C++基于hook iat改变Messagebox实例
本文实例讲述了C++基于hookiat改变Messagebox的方法,分享给大家供大家参考。具体方法如下:
步骤:
1.定义原始函数类型的写法
//定义函数原型 typedefint(WINAPI*PFNMESSAGEBOX)(HWNDhWnd, LPCTSTRlpText, LPCTSTRlpCaption, UINTuType); //保存原始的MessageBox地址,注意这里 PROCg_orgProc=(PROC)MessageBox;
2.先找到dll,找到后设置标志
if(stricmp(pszDllName,"user32.dll")==0)//如果是user32.dll { bFindDll=TRUE; break; }
3.找到dll后,查找函数名称
//在这里是比较的函数名称 if(stricmp(pszFuncName,"MessageBoxA")==0) { //取得函数地址 PDWORDlpAddr=(DWORD*)((BYTE*)hModule+pImportDesc->FirstThunk)+n;//从第一个函数的地址,以后每次+4字节 //在这里是比较的函数地址 printf("addrss:%X\n",lpAddr); DWORD*lpNewProc=(DWORD*)MyMessageBox; ::WriteProcessMemory(GetCurrentProcess(),lpAddr,&lpNewProc,sizeof(DWORD),NULL); return; }
当然在3.中,也可以根据函数地址比较
#include<windows.h> #include<stdio.h> //定义函数原型 typedefint(WINAPI*PFNMESSAGEBOX)(HWNDhWnd, LPCTSTRlpText, LPCTSTRlpCaption, UINTuType); //保存原始的MessageBox地址,注意这里 PROCg_orgProc=(PROC)MessageBox; intMyMessageBox(HWNDhWnd, LPCTSTRlpText, LPCTSTRlpCaption, UINTuType) { return((PFNMESSAGEBOX)g_orgProc)(hWnd,"mymessagebox",lpCaption,uType); } voidSetHook() { HMODULEhModule=::GetModuleHandleA(NULL); IMAGE_DOS_HEADER*pDosHeader=(IMAGE_DOS_HEADER*)hModule; IMAGE_OPTIONAL_HEADER*pOpNtHeader=(IMAGE_OPTIONAL_HEADER*)((BYTE*)hModule+pDosHeader->e_lfanew+24);//这里加24 IMAGE_IMPORT_DESCRIPTOR*pImportDesc=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hModule+pOpNtHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); BOOLbFindDll=FALSE; while(pImportDesc->FirstThunk) { char*pszDllName=(char*)((BYTE*)hModule+pImportDesc->Name); printf("模块名称:%s\n",pszDllName); if(stricmp(pszDllName,"user32.dll")==0)//如果是user32.dll { bFindDll=TRUE; break; } pImportDesc++; } if(bFindDll) { DWORDn=0; //一个IMAGE_THUNK_DATA就是一个导入函数 IMAGE_THUNK_DATA*pThunk=(IMAGE_THUNK_DATA*)((BYTE*)hModule+pImportDesc->OriginalFirstThunk); while(pThunk->u1.Function) { //取得函数名称 char*pszFuncName=(char*)((BYTE*)hModule+pThunk->u1.AddressOfData+2);//函数名前面有两个.. printf("functionname:%-25s, ",pszFuncName); //在这里是比较的函数名称 if(stricmp(pszFuncName,"MessageBoxA")==0) { //取得函数地址 PDWORDlpAddr=(DWORD*)((BYTE*)hModule+pImportDesc->FirstThunk)+n;//从第一个函数的地址,以后每次+4字节 //在这里是比较的函数地址 printf("addrss:%X\n",lpAddr); DWORD*lpNewProc=(DWORD*)MyMessageBox; ::WriteProcessMemory(GetCurrentProcess(),lpAddr,&lpNewProc,sizeof(DWORD),NULL); return; } n++;//每次增加一个DWORD } printf("\n"); } } intmain(intargc,char*argv[]) { ::MessageBoxA(NULL,"beforehook","",MB_OK); SetHook(); ::MessageBoxA(NULL,"AFTEREhook","",MB_OK); return0; }
下面这个是比较函数地址的版本
#include<windows.h> #include<stdio.h> //定义函数原型 typedefint(WINAPI*PFNMESSAGEBOX)(HWNDhWnd, LPCTSTRlpText, LPCTSTRlpCaption, UINTuType); //保存原始的MessageBox地址,注意这里 PROCg_orgProc=(PROC)MessageBox; intMyMessageBox(HWNDhWnd, LPCTSTRlpText, LPCTSTRlpCaption, UINTuType) { return((PFNMESSAGEBOX)g_orgProc)(hWnd,"mymessagebox",lpCaption,uType); } voidSetHook() { HMODULEhModule=::GetModuleHandleA(NULL); IMAGE_DOS_HEADER*pDosHeader=(IMAGE_DOS_HEADER*)hModule; IMAGE_OPTIONAL_HEADER*pOpNtHeader=(IMAGE_OPTIONAL_HEADER*)((BYTE*)hModule+pDosHeader->e_lfanew+24);//这里加24 IMAGE_IMPORT_DESCRIPTOR*pImportDesc=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hModule+pOpNtHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); BOOLbFindDll=FALSE; while(pImportDesc->FirstThunk) { char*pszDllName=(char*)((BYTE*)hModule+pImportDesc->Name); printf("模块名称:%s\n",pszDllName); if(stricmp(pszDllName,"user32.dll")==0)//如果是user32.dll { bFindDll=TRUE; break; } pImportDesc++; } if(bFindDll) { DWORDn=0; //一个IMAGE_THUNK_DATA就是一个导入函数 IMAGE_THUNK_DATA*pThunk=(IMAGE_THUNK_DATA*)((BYTE*)hModule+pImportDesc->OriginalFirstThunk); while(pThunk->u1.Function) { //取得函数名称 char*pszFuncName=(char*)((BYTE*)hModule+pThunk->u1.AddressOfData+2);//函数名前面有两个.. printf("functionname:%-25s, ",pszFuncName); //取得函数地址 PDWORDlpAddr=(DWORD*)((BYTE*)hModule+pImportDesc->FirstThunk)+n;//从第一个函数的地址,以后每次+4字节 printf("addrss:%X\n",lpAddr); //在这里是比较的函数地址 if(*lpAddr==(DWORD)g_orgProc) { DWORD*lpNewProc=(DWORD*)MyMessageBox; ::WriteProcessMemory(GetCurrentProcess(),lpAddr,&lpNewProc,sizeof(DWORD),NULL); return; } n++;//每次增加一个DWORD } printf("\n"); } } intmain(intargc,char*argv[]) { ::MessageBoxA(NULL,"beforehook","",MB_OK); SetHook(); ::MessageBoxA(NULL,"AFTEREhook","",MB_OK); return0; }
附上修改内存页保护属性的代码:
//修改内存页的保护属性 ::VirtualQuery(lpAddr,&mbi,sizeof(MEMORY_BASIC_INFORMATION)); ::VirtualProtect(lpAddr,sizeof(DWORD),PAGE_READWRITE,&dwOldProtect); ::WriteProcessMemory(GetCurrentProcess(),lpAddr,&lpNewProc,sizeof(DWORD),NULL); ::VirtualProtect(lpAddr,sizeof(DWORD),dwOldProtect,NULL);
希望本文所述对大家的C++程序设计有所帮助。