IAT_HOOK原理实现
0x00 原理简介
IAT(Import Address Table,输入地址表):当PE文件装入的时候,Windows加载器的工作之一就是定位所有被输入的函数和数据,并且让正在被装入的文件可以使用那些地址,输入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于相关的dll等文件中,当然只有被程序调用到的函数才会出现在IAT中(EAT是PE中所有导出的函数或者变量,注意区别,一般的EXE文件不会有导出表,但并不是说EXE不能导出函数或者变量)。HOOK IAT就是钩住感兴趣的函数,然后改变程序的执行流程或者对该函数进行监控。
0x01 代码实现
1,HOOK函数MessageBox,首先定义一个用于替换的MyMessageBox函数。
int WINAPI MyMessageBox(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)
{
char lpNewText[]="修改后的内容";
typedef int (WINAPI *PFNMESSAGEBOX)(HWND,LPCSTR,LPCSTR,UINT);
int ret=((PFNMESSAGEBOX)g_dwOldAddr)(hWnd,lpNewText,lpCaption,uType);
return ret;
}2,得到模块基址,并找到该PE模块中IAT表的位置
dwImageBase=(DWORD)::GetModuleHandle(NULL);
pNtHeader=(PIMAGE_NT_HEADERS)(dwImageBase+((PIMAGE_DOS_HEADER)dwImageBase)->e_lfanew);
pImportDescriptor=(PIMAGE_IMPORT_DESCRIPTOR)(dwImageBase+pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);3,遍历IAt表,找到要HOOK的MessageBox函数地址,找到后先修改内存页的属性为PAGE_READWRITE,再修改当前位置为MyMessageBox函数地址,恢复内存页属性。
while(pImportDescriptor->FirstThunk!=0 && bFlag == FALSE)
{
pFuncAddr=(PDWORD)(dwImageBase+pImportDescriptor->FirstThunk);
while(*pFuncAddr)
{
if(dwOldAddr == *pFuncAddr)
{
VirtualProtect(pFuncAddr,sizeof(DWORD),PAGE_READWRITE,&dwOldProtect);
*pFuncAddr=dwNewAddr;
VirtualProtect(pFuncAddr,sizeof(DWORD),dwOldProtect,0);
bFlag=TRUE;
break;
}
pFuncAddr=(PDWORD)((DWORD)pFuncAddr+sizeof(DWORD));
}
pImportDescriptor=(PIMAGE_IMPORT_DESCRIPTOR)((DWORD)pImportDescriptor+sizeof(IMAGE_IMPORT_DESCRIPTOR));
}0x02 完整代码
这是个dll文件
0x03实验结果
实验环境: win10
对象程序: crackme.exe
单击程序Help的Register,随便输入注册账号和密码

Last updated
Was this helpful?