作者在 2009-02-15 21:50:41 发布以下内容
下面这段代码是一个动态链接库的源码,它用于挂接MessageBoxW的调用
#include <windows.h>
#include <ImageHlp.h> //for ImageDirectoryEntryToData
#include <TlHelp32.h> //for Module32First,MODULEENTRY32 and CreateToolhelp32Snapshot
#pragma comment(lib,"ImageHlp") //for ImageDirectoryEntryToData
#pragma data_seg("Shared")
HHOOK hhk = NULL; //shared by all process,must be initilized
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,rws") //tell the linker to put hhk into the Shared section
//钩子函数.它只简单地把消息传递到下一个钩子过程
LRESULT CALLBACK GetMsgProc( int nCode, WPARAM wParam, LPARAM lParam ){
return CallNextHookEx(hhk,nCode,wParam,lParam);
}
//替换了的MessageBoxW.注意函数原型要和原来的一致,包括WIAPI
//它显示一个消息框指明MessageBoxW已被截获
int WINAPI MyMessageBoxW( HWND hwnd,LPCWSTR lpszContent,LPCWSTR lpszCaption,UINT uType ){
MessageBoxW(hwnd,L"Call to MessageBoxW is interceptedZZZZZZZZZZ!",L"Hook",MB_OK);
return MessageBoxW( hwnd,lpszContent,lpszCaption,uType);
}
//修改输入表
VOID ModifyIAT(HMODULE hmodCaller,LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
PIMAGE_THUNK_DATA pITD;
ULONG ulSize;
//对每一个用到的dll,在输入表中都用一个IMAGE_IMPORT_DESCRIPTOR类型的
//结构体保存该dll的信息
PIMAGE_IMPORT_DESCRIPTOR pIID;
//用ImageDirectoryEntryToData可以取得输入表中的第一项
//参数IMAGE_DIRECTORY_ENTRY_IMPORT指明要取得输入表,而不是其他表
pIID =(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmodCaller,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
//如果pIID为NULL,表示该模块没有输入表,返回
if( !pIID )
return;
//IMAGE_IMPORT_DESCRIPTOR有一个Name的成员,该成员是dll名字的RVA
//hmodCaller实质是模块映射到进程空间中的基地址,通过将它转换为PBYTE类型,
//再加上Name这个RVA就可以得到这项IMAGE_IMPORT_DESCRIPTOR记录的dll的名字
//将这个名字与我们要挂接的dll的名字比较
//如果两个名字不同,则pIID++取下一项IMAGE_IMPORT_DESCRIPTOR
for(; pIID->Name; pIID++){
if( !lstrcmpiA( szDllName,(LPSTR)((PBYTE)hmodCaller + pIID->Name) ) )
break;
}
//如果遍历完所有dll都没有找到我们要挂接的dll,则返回
if( !pIID->Name )
return;
//可以从一个dll中输入多个函数.对每一个输入的函数,用一个IMAGE_THUNK_DATA
//结构体保存它的信息.在IMAGE_IMPORT_DESCRIPTOR中,有一个FirstThunk成员记录着
//第一个IMAGE_THUNK_DATA(这个IMAGE_THUNK_DATA保存着第一个输入函数的信息)的RVA
//我们用与取得dll名字一样的方法(基址+RVA)取得这个IMAGE_THUNK_DATA
pITD = (PIMAGE_THUNK_DATA)( (PBYTE)hmodCaller + pIID->FirstThunk );
//IMAGE_THUNK_DATA有一个ul成员,它是一个共同体.通过这个共同体的Function成员,我们
//可以得到输入函数在进程空间中的真实地址
//将这个真实地址和我们要挂接的函数的地址比较,如果相同,则修改
//否则pITD++取下一个输入函数的信息
for(; pITD->u1.Function ; pITD++){
PROC* ppfn = (PROC*)&pITD->u1.Function;
if( *ppfn == pfnOrg ){
WriteProcessMemory(GetCurrentProcess(),ppfn,&pfnNew,sizeof(pfnNew),NULL);
return;
}
}
}
//安装钩子
_declspec(dllexport) VOID SetHook(){
if( !hhk ){
HINSTANCE hInst = LoadLibrary( TEXT("HOOKAPILIB.DLL") );
if( !hInst )
return;
hhk = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInst,0);
FreeLibrary( hInst );
}
}
//缷载钩子
_declspec(dllexport) VOID UnHook(){
if( hhk ){
/* ModifyIAT(
hCurrentProcess,
"USER32.DLL",
(PROC)MyMessageBoxW,
GetProcAddress( GetModuleHandle("USER32.DLL"),"MessageBoxW" )
);*/
UnhookWindowsHookEx( hhk );
}
}
//dll的入口函数.每当这个dll被映射到一个进程的地址空间中,我们就挂接MessageBoxW
//在dll从进程的地址空间中缷载时,我们将原来的MessageboxW的地址写回进程中
//要取得这个进程的基地址,要用到MODULEENTRY32和CreateToolhelp32Snapshot
//MODULEENTRY32的hModule成员就是进程的基地址
BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved ){
HMODULE hCurrentProcess;
MODULEENTRY32 me32;
HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE,GetCurrentProcessId() );
me32.dwSize = sizeof( MODULEENTRY32 );
Module32First(hSnapshot,&me32);
hCurrentProcess = me32.hModule;
switch( dwReason ){
case DLL_PROCESS_ATTACH:
ModifyIAT(
hCurrentProcess,
"USER32.DLL",
GetProcAddress( GetModuleHandle("USER32.DLL"),"MessageBoxW" ),
(PROC)MyMessageBoxW
);
break;
case DLL_PROCESS_DETACH:
ModifyIAT(
hCurrentProcess,
"USER32.DLL",
(PROC)MyMessageBoxW,
GetProcAddress( GetModuleHandle("USER32.DLL"),"MessageBoxW" )
);
break;
}
return TRUE;
}
#include <ImageHlp.h> //for ImageDirectoryEntryToData
#include <TlHelp32.h> //for Module32First,MODULEENTRY32 and CreateToolhelp32Snapshot
#pragma comment(lib,"ImageHlp") //for ImageDirectoryEntryToData
#pragma data_seg("Shared")
HHOOK hhk = NULL; //shared by all process,must be initilized
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,rws") //tell the linker to put hhk into the Shared section
//钩子函数.它只简单地把消息传递到下一个钩子过程
LRESULT CALLBACK GetMsgProc( int nCode, WPARAM wParam, LPARAM lParam ){
return CallNextHookEx(hhk,nCode,wParam,lParam);
}
//替换了的MessageBoxW.注意函数原型要和原来的一致,包括WIAPI
//它显示一个消息框指明MessageBoxW已被截获
int WINAPI MyMessageBoxW( HWND hwnd,LPCWSTR lpszContent,LPCWSTR lpszCaption,UINT uType ){
MessageBoxW(hwnd,L"Call to MessageBoxW is interceptedZZZZZZZZZZ!",L"Hook",MB_OK);
return MessageBoxW( hwnd,lpszContent,lpszCaption,uType);
}
//修改输入表
VOID ModifyIAT(HMODULE hmodCaller,LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
PIMAGE_THUNK_DATA pITD;
ULONG ulSize;
//对每一个用到的dll,在输入表中都用一个IMAGE_IMPORT_DESCRIPTOR类型的
//结构体保存该dll的信息
PIMAGE_IMPORT_DESCRIPTOR pIID;
//用ImageDirectoryEntryToData可以取得输入表中的第一项
//参数IMAGE_DIRECTORY_ENTRY_IMPORT指明要取得输入表,而不是其他表
pIID =(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmodCaller,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
//如果pIID为NULL,表示该模块没有输入表,返回
if( !pIID )
return;
//IMAGE_IMPORT_DESCRIPTOR有一个Name的成员,该成员是dll名字的RVA
//hmodCaller实质是模块映射到进程空间中的基地址,通过将它转换为PBYTE类型,
//再加上Name这个RVA就可以得到这项IMAGE_IMPORT_DESCRIPTOR记录的dll的名字
//将这个名字与我们要挂接的dll的名字比较
//如果两个名字不同,则pIID++取下一项IMAGE_IMPORT_DESCRIPTOR
for(; pIID->Name; pIID++){
if( !lstrcmpiA( szDllName,(LPSTR)((PBYTE)hmodCaller + pIID->Name) ) )
break;
}
//如果遍历完所有dll都没有找到我们要挂接的dll,则返回
if( !pIID->Name )
return;
//可以从一个dll中输入多个函数.对每一个输入的函数,用一个IMAGE_THUNK_DATA
//结构体保存它的信息.在IMAGE_IMPORT_DESCRIPTOR中,有一个FirstThunk成员记录着
//第一个IMAGE_THUNK_DATA(这个IMAGE_THUNK_DATA保存着第一个输入函数的信息)的RVA
//我们用与取得dll名字一样的方法(基址+RVA)取得这个IMAGE_THUNK_DATA
pITD = (PIMAGE_THUNK_DATA)( (PBYTE)hmodCaller + pIID->FirstThunk );
//IMAGE_THUNK_DATA有一个ul成员,它是一个共同体.通过这个共同体的Function成员,我们
//可以得到输入函数在进程空间中的真实地址
//将这个真实地址和我们要挂接的函数的地址比较,如果相同,则修改
//否则pITD++取下一个输入函数的信息
for(; pITD->u1.Function ; pITD++){
PROC* ppfn = (PROC*)&pITD->u1.Function;
if( *ppfn == pfnOrg ){
WriteProcessMemory(GetCurrentProcess(),ppfn,&pfnNew,sizeof(pfnNew),NULL);
return;
}
}
}
//安装钩子
_declspec(dllexport) VOID SetHook(){
if( !hhk ){
HINSTANCE hInst = LoadLibrary( TEXT("HOOKAPILIB.DLL") );
if( !hInst )
return;
hhk = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInst,0);
FreeLibrary( hInst );
}
}
//缷载钩子
_declspec(dllexport) VOID UnHook(){
if( hhk ){
/* ModifyIAT(
hCurrentProcess,
"USER32.DLL",
(PROC)MyMessageBoxW,
GetProcAddress( GetModuleHandle("USER32.DLL"),"MessageBoxW" )
);*/
UnhookWindowsHookEx( hhk );
}
}
//dll的入口函数.每当这个dll被映射到一个进程的地址空间中,我们就挂接MessageBoxW
//在dll从进程的地址空间中缷载时,我们将原来的MessageboxW的地址写回进程中
//要取得这个进程的基地址,要用到MODULEENTRY32和CreateToolhelp32Snapshot
//MODULEENTRY32的hModule成员就是进程的基地址
BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved ){
HMODULE hCurrentProcess;
MODULEENTRY32 me32;
HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE,GetCurrentProcessId() );
me32.dwSize = sizeof( MODULEENTRY32 );
Module32First(hSnapshot,&me32);
hCurrentProcess = me32.hModule;
switch( dwReason ){
case DLL_PROCESS_ATTACH:
ModifyIAT(
hCurrentProcess,
"USER32.DLL",
GetProcAddress( GetModuleHandle("USER32.DLL"),"MessageBoxW" ),
(PROC)MyMessageBoxW
);
break;
case DLL_PROCESS_DETACH:
ModifyIAT(
hCurrentProcess,
"USER32.DLL",
(PROC)MyMessageBoxW,
GetProcAddress( GetModuleHandle("USER32.DLL"),"MessageBoxW" )
);
break;
}
return TRUE;
}
#include <windows.h>
#define DLLNAME "HOOKAPILIB.DLL"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HOOKAPI") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass)){
MessageBox(NULL,TEXT("DDFD"),TEXT("DDDFAS"),MB_OK);
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("HOOKAPI"), // window caption
WS_OVERLAPPEDWINDOW, // window style
462, // initial x position
353, // initial y position
100, // initial x size
62, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
if( hwnd ){
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
}
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
PROC SetHook;
HINSTANCE hInst = LoadLibrary(DLLNAME);
if( !hInst ){
DestroyWindow(hwnd);
MessageBox(hwnd,TEXT("Can not load dll!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
SetHook = GetProcAddress(hInst,"SetHook");
if( !SetHook ){
DestroyWindow(hwnd);
MessageBox(hwnd,TEXT("Can not find function!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
//安装钩子,这样我们的dll就被映射到每一个gui程序的进程空间中
SetHook();
FreeLibrary(hInst);
return 0 ;
}
case WM_DESTROY:
{
PROC UnHook;
HINSTANCE hInst = LoadLibrary(DLLNAME);
if( !hInst ){
MessageBox(hwnd,TEXT("Can not load dll!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
UnHook = GetProcAddress(hInst,"UnHook");
if( !UnHook ){
MessageBox(hwnd,TEXT("Can not find function!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
//退出之前我们要缷载钩子
UnHook();
PostQuitMessage (0) ;
return 0 ;
}
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
#define DLLNAME "HOOKAPILIB.DLL"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("HOOKAPI") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass)){
MessageBox(NULL,TEXT("DDFD"),TEXT("DDDFAS"),MB_OK);
return 0 ;
}
hwnd = CreateWindow (szAppName, // window class name
TEXT ("HOOKAPI"), // window caption
WS_OVERLAPPEDWINDOW, // window style
462, // initial x position
353, // initial y position
100, // initial x size
62, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL) ; // creation parameters
if( hwnd ){
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
}
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
PROC SetHook;
HINSTANCE hInst = LoadLibrary(DLLNAME);
if( !hInst ){
DestroyWindow(hwnd);
MessageBox(hwnd,TEXT("Can not load dll!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
SetHook = GetProcAddress(hInst,"SetHook");
if( !SetHook ){
DestroyWindow(hwnd);
MessageBox(hwnd,TEXT("Can not find function!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
//安装钩子,这样我们的dll就被映射到每一个gui程序的进程空间中
SetHook();
FreeLibrary(hInst);
return 0 ;
}
case WM_DESTROY:
{
PROC UnHook;
HINSTANCE hInst = LoadLibrary(DLLNAME);
if( !hInst ){
MessageBox(hwnd,TEXT("Can not load dll!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
UnHook = GetProcAddress(hInst,"UnHook");
if( !UnHook ){
MessageBox(hwnd,TEXT("Can not find function!"),TEXT("HOOKAPI"),MB_ICONHAND);
PostQuitMessage(0);
return 0;
}
//退出之前我们要缷载钩子
UnHook();
PostQuitMessage (0) ;
return 0 ;
}
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
下面我们把我们的截获做得彻底些
下面新的dll的代码,里面加入了对LoadLibraryA和GetProcAddress的截获
#include <windows.h>
#include <ImageHlp.h>
#include <TlHelp32.h>
#pragma comment(lib,"ImageHlp")
#pragma data_seg("Shared")
HHOOK hhk = NULL;
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,rws")
HMODULE hmodThisDll;
LRESULT CALLBACK GetMsgProc( int nCode,WPARAM wParam,LPARAM lParam){
return CallNextHookEx(hhk,nCode,wParam,lParam);
}
int WINAPI MyMessageBoxW(HWND hwnd,LPCWSTR lpszContent,LPCWSTR lpszCaption,UINT uType){
MessageBoxW(hwnd,L"Call to MessageBoxW is intercepted!",L"HOOKAPILIB2",MB_OK);
return MessageBoxW(hwnd,lpszContent,lpszCaption,uType);
}
VOID ModifyIAT(HMODULE hmodCaller,LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
PIMAGE_THUNK_DATA pITD;
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR pIID;
pIID = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmodCaller,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
if( !pIID )
return;
for( ; pIID->Name; pIID++ ){
if( !lstrcmpiA(szDllName,(LPSTR)((PBYTE)hmodCaller+pIID->Name)) )
break;
}
if( !pIID->Name )
return;
pITD = (PIMAGE_THUNK_DATA)((PBYTE)hmodCaller+pIID->FirstThunk);
for( ; pITD->u1.Function ; pITD++ ){
PROC* ppfn = (PROC*)&pITD->u1.Function;
if(*ppfn == pfnOrg){
WriteProcessMemory(GetCurrentProcess()/*hmodCaller*/,ppfn,&pfnNew,sizeof(pfnNew),NULL);
return;
}
}
}
//在这里枚举进程的所有模块,并修改各个模块对MessageBoxW的调用
//这个枚举过程用到了Module32First和Module32Next
VOID ModifyIATs(LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
BOOL fOk = FALSE;
MODULEENTRY32 me32;
HANDLE hSnapshot;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
me32.dwSize = sizeof( me32 );
for( fOk = Module32First( hSnapshot,&me32 ); fOk ; fOk = Module32Next(hSnapshot,&me32)){
if( me32.hModule != hmodThisDll ){
ModifyIAT(me32.hModule,szDllName,pfnOrg,pfnNew);
}
}
CloseHandle( hSnapshot );
}
//LoadLriary的替代函数
HMODULE WINAPI MyLoadLibraryA( LPCSTR lpLibFileName ){
HMODULE hmod = LoadLibrary( lpLibFileName );
ModifyIAT( hmod,"USER32.DLL",
GetProcAddress(GetModuleHandle("USER32.DLL"),"MessageBoxW"),MyMessageBoxW
);
return hmod;
}
//GetProcAddress的替代函数
FARPROC WINAPI MyGetProcAddress( HMODULE hModule,LPCSTR lpProcName ){
if( hModule == GetModuleHandle("USER32.DLL") &&
!lstrcmpiA(lpProcName,"MessageBoxW") )
return (PROC)MyMessageBoxW;
else
return GetProcAddress( hModule,lpProcName );
}
//_declspec(dllexport) VOID SetHook( DWORD dwThreadId ){
_declspec(dllexport) VOID SetHook( ){
if( !hhk ){
HINSTANCE hInst = LoadLibrary("HOOKAPILIB2.DLL");
if( !hInst )
return;
hhk = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInst,0);
FreeLibrary( hInst );
}
}
_declspec(dllexport) VOID UnHook(){
if( hhk )
UnhookWindowsHookEx( hhk );
}
//在DLL_PROCESS_ATTACH通知时,修改MessageBoxW,LoadLibraryA,GetProcAddress的地址
//在DLL_PROCESS_DETACH通知时,将地址改回原来的地址
BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpvReserved){
hmodThisDll = hInstance;
switch( dwReason ){
case DLL_PROCESS_ATTACH:
ModifyIATs(
"USER32.DLL",
GetProcAddress(GetModuleHandle("USER32.DLL"),
"MessageBoxW"),
(PROC)MyMessageBoxW);
ModifyIATs(
"KERNEL32.DLL",
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"LoadLibraryA"),
(PROC)MyLoadLibraryA);
ModifyIATs(
#include <ImageHlp.h>
#include <TlHelp32.h>
#pragma comment(lib,"ImageHlp")
#pragma data_seg("Shared")
HHOOK hhk = NULL;
#pragma data_seg()
#pragma comment(linker, "/Section:Shared,rws")
HMODULE hmodThisDll;
LRESULT CALLBACK GetMsgProc( int nCode,WPARAM wParam,LPARAM lParam){
return CallNextHookEx(hhk,nCode,wParam,lParam);
}
int WINAPI MyMessageBoxW(HWND hwnd,LPCWSTR lpszContent,LPCWSTR lpszCaption,UINT uType){
MessageBoxW(hwnd,L"Call to MessageBoxW is intercepted!",L"HOOKAPILIB2",MB_OK);
return MessageBoxW(hwnd,lpszContent,lpszCaption,uType);
}
VOID ModifyIAT(HMODULE hmodCaller,LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
PIMAGE_THUNK_DATA pITD;
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR pIID;
pIID = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmodCaller,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&ulSize);
if( !pIID )
return;
for( ; pIID->Name; pIID++ ){
if( !lstrcmpiA(szDllName,(LPSTR)((PBYTE)hmodCaller+pIID->Name)) )
break;
}
if( !pIID->Name )
return;
pITD = (PIMAGE_THUNK_DATA)((PBYTE)hmodCaller+pIID->FirstThunk);
for( ; pITD->u1.Function ; pITD++ ){
PROC* ppfn = (PROC*)&pITD->u1.Function;
if(*ppfn == pfnOrg){
WriteProcessMemory(GetCurrentProcess()/*hmodCaller*/,ppfn,&pfnNew,sizeof(pfnNew),NULL);
return;
}
}
}
//在这里枚举进程的所有模块,并修改各个模块对MessageBoxW的调用
//这个枚举过程用到了Module32First和Module32Next
VOID ModifyIATs(LPCSTR szDllName,PROC pfnOrg,PROC pfnNew){
BOOL fOk = FALSE;
MODULEENTRY32 me32;
HANDLE hSnapshot;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId());
me32.dwSize = sizeof( me32 );
for( fOk = Module32First( hSnapshot,&me32 ); fOk ; fOk = Module32Next(hSnapshot,&me32)){
if( me32.hModule != hmodThisDll ){
ModifyIAT(me32.hModule,szDllName,pfnOrg,pfnNew);
}
}
CloseHandle( hSnapshot );
}
//LoadLriary的替代函数
HMODULE WINAPI MyLoadLibraryA( LPCSTR lpLibFileName ){
HMODULE hmod = LoadLibrary( lpLibFileName );
ModifyIAT( hmod,"USER32.DLL",
GetProcAddress(GetModuleHandle("USER32.DLL"),"MessageBoxW"),MyMessageBoxW
);
return hmod;
}
//GetProcAddress的替代函数
FARPROC WINAPI MyGetProcAddress( HMODULE hModule,LPCSTR lpProcName ){
if( hModule == GetModuleHandle("USER32.DLL") &&
!lstrcmpiA(lpProcName,"MessageBoxW") )
return (PROC)MyMessageBoxW;
else
return GetProcAddress( hModule,lpProcName );
}
//_declspec(dllexport) VOID SetHook( DWORD dwThreadId ){
_declspec(dllexport) VOID SetHook( ){
if( !hhk ){
HINSTANCE hInst = LoadLibrary("HOOKAPILIB2.DLL");
if( !hInst )
return;
hhk = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hInst,0);
FreeLibrary( hInst );
}
}
_declspec(dllexport) VOID UnHook(){
if( hhk )
UnhookWindowsHookEx( hhk );
}
//在DLL_PROCESS_ATTACH通知时,修改MessageBoxW,LoadLibraryA,GetProcAddress的地址
//在DLL_PROCESS_DETACH通知时,将地址改回原来的地址
BOOL WINAPI DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID lpvReserved){
hmodThisDll = hInstance;
switch( dwReason ){
case DLL_PROCESS_ATTACH:
ModifyIATs(
"USER32.DLL",
GetProcAddress(GetModuleHandle("USER32.DLL"),
"MessageBoxW"),
(PROC)MyMessageBoxW);
ModifyIATs(
"KERNEL32.DLL",
GetProcAddress(GetModuleHandle("KERNEL32.DLL"),"LoadLibraryA"),
(PROC)MyLoadLibraryA);
ModifyIATs(
文章评论,共0条
最新评论
- lanqiaojun:如果是MFC程序,可以通过AfxGetMainWnd()获取主窗口指针;如果不是MFC,通过下...
- 夜风依旧:好东西!顶下
- xingxing0714:博主,你的小窝非常好啊,刚才我在看MFC多线程写的很好.特别是线程通信..
- 夜风依旧:为什么我的xp注册表里面没有RegisteredOwner和RegisteredOrganiz...
- lanqiaojun:cmps<br /> scas<br /> lods<br /> stos<br /> ...
- zklhp:在黑防上看过~~~