利用NtUnmapViewOfSection强制卸载模块
作者:JiaJia 日期:2008-09-16
确实可以卸载指定进程指定位置的模块,但有几个问题:
[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;
}
[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 | 查看次数: -
发表评论
上一篇
下一篇

文章来自:
Tags: