利用NtUnmapViewOfSection强制卸载模块

确实可以卸载指定进程指定位置的模块,但有几个问题:
[1]  PEB的模块列表中还存在该模块的记录,大部分模块枚举函数都是枚举这个列表
[2]  可能会出现访问异常
[3]  ZwUnmapViewOfSection这个NTDLL中的函数的地址自己用GetProcAddress就可以得到引用了

看来RING3下是不可能做到强制卸载模块的完美实现,要进ring0才行。下面是测试代码
typedef ULONG (WINAPI *PFNNtUnmapViewOfSection)( IN HANDLE ProcessHandle,IN PVOID BaseAddress );

BOOL UnmapViewOfModule ( DWORD dwProcessId, LPVOID lpBaseAddr )
{
    HMODULE hModule = GetModuleHandle ( L"ntdll.dll" ) ;
    if ( hModule == NULL )
        hModule = LoadLibrary ( L"ntdll.dll" ) ;

    PFNNtUnmapViewOfSection pfnNtUnmapViewOfSection = (PFNNtUnmapViewOfSection)GetProcAddress ( hModule, "NtUnmapViewOfSection" ) ;
    
    HANDLE hProcess = OpenProcess ( PROCESS_ALL_ACCESS, TRUE, dwProcessId ) ;
    ULONG    ret = pfnNtUnmapViewOfSection ( hProcess, lpBaseAddr ) ;
    CloseHandle ( hProcess ) ;
    return ret ? false : true ;
}

下面还有一段转帖代码:
引用内容 引用内容

BOOL UnLoadModules( LPCTSTR processname , LPCTSTR modulename)
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
HANDLE hpro;
DWORD modulebase;
DWORD pid=GetProcessIdByName(processname);

hpro= OpenProcess
  
(
  
PROCESS_ALL_ACCESS,
  
TRUE,
  
pid
      
);

hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
if( hModuleSnap == INVALID_HANDLE_VALUE )
{
  
    
return( FALSE );
}

me32.dwSize = sizeof( MODULEENTRY32 );

if( !Module32First( hModuleSnap, &me32 ) )
{

    
CloseHandle( hModuleSnap );
    
return( FALSE );
}

do
{
printf( "\n\n     MODULE NAME:     %s",             me32.szModule );
    
printf( "\n     executable     = %s",             me32.szExePath );
    
printf( "\n     process ID     = 0x%08X",         me32.th32ProcessID );
    
printf( "\n     ref count (g) =     0x%04X",     me32.GlblcntUsage );
    
printf( "\n     ref count (p) =     0x%04X",     me32.ProccntUsage );
    
printf( "\n     base address   = 0x%08X", (DWORD) me32.modBaseAddr );
    
printf( "\n     base size      = %d",             me32.modBaseSize );


if(!strcmpi(me32.szModule, modulename))
{
modulebase=(DWORD)me32.modBaseAddr;
printf("module :%s found at :%x\n",modulename,modulebase);
break;

}

}
while( Module32Next( hModuleSnap, &me32 ) );

ZwUnmapViewOfSection(hpro,(DWORD)modulebase);
CloseHandle( hModuleSnap );
return( TRUE );
}

DWORD GetProcessIdByName(LPCTSTR name)
{

PROCESSENTRY32 prostruct;
    
DWORD id = 0;
    
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    
prostruct.dwSize = sizeof(PROCESSENTRY32);

if(!Process32First(hSnapshot,&prostruct))
    
return 0;

do

{
  
prostruct.dwSize = sizeof(PROCESSENTRY32);
        
if(!Process32Next(hSnapshot,&prostruct))
          
break;

  
if(strcmp(prostruct.szExeFile,name) == 0)

   {
    
id = prostruct.th32ProcessID;
    
break;
   }

}
while(TRUE);

CloseHandle(hSnapshot);
return id;
}



评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.