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++程序设计有所帮助。