Simple Demo
IATHook principle
IATHook refers to the import table function of a process. When the program runs, IAT will fill in the actual memory address of the function, which is usually in a dll memory loaded! Then we change the address value to the address where our self written function is located. When the system calls the IAT function, it will jump to the function we wrote
Code
#include <windows.h> #include <string.h> #include <stdio.h> int WINAPI MessageBoxPro(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType){ printf("IATHook Success\n"); system("pause"); return 0; } int main(){ HMODULE hmod; PIMAGE_DOS_HEADER pdos; PIMAGE_NT_HEADERS pnt; PIMAGE_OPTIONAL_HEADER popt; PIMAGE_IMPORT_DESCRIPTOR piid; PIMAGE_THUNK_DATA pfuncname_addr,pfunc_addr; DWORD dwOldProtect,dwNewProtect; DWORD* repAddr = (DWORD *)MessageBoxPro; // It has to be changed hmod = GetModuleHandle(NULL); pdos = (PIMAGE_DOS_HEADER)hmod; pnt = (PIMAGE_NT_HEADERS)((PBYTE)hmod + pdos->e_lfanew); popt = (PIMAGE_OPTIONAL_HEADER)(&(pnt->OptionalHeader)); piid = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hmod+popt->DataDirectory[1].VirtualAddress); // Base_addr + RVA_addr MessageBox(NULL,"HelloWorld","Title",MB_OK); while(piid->FirstThunk){ pfuncname_addr = (PIMAGE_THUNK_DATA)((BYTE *)hmod + piid->OriginalFirstThunk); pfunc_addr = (PIMAGE_THUNK_DATA)((BYTE *)hmod + piid->FirstThunk); // char* pdll_name = (char *)((BYTE *)hmod + piid->Name); // printf("%s\n",pdll_name); while(pfuncname_addr->u1.Function){ char* func_name = (char *)((BYTE *)hmod + pfuncname_addr->u1.AddressOfData+2); DWORD *lpAddr = (DWORD *)&pfunc_addr->u1.AddressOfData; if(!strcmp(func_name,"MessageBoxA")){ VirtualProtect(lpAddr,4,PAGE_EXECUTE_READWRITE,&dwOldProtect); WriteProcessMemory((HMODULE)-1,lpAddr,&repAddr,4,NULL); // The first way to modify an address // *lpAddr = repAddr; / / the second way to modify the address } VirtualProtect(lpAddr,4,dwOldProtect,&dwNewProtect); pfuncname_addr++; pfunc_addr++; } piid++; } MessageBox(NULL,"HelloWorld","Title",MB_OK); return 0; }
Explain
You can modify the IAT address by assigning a value or by using the WriteProcessMemory function! Don't forget to use VirtualProtect to modify the properties of the memory page, otherwise it can't be written successfully! We need to pay attention to the type conversion of function name and the reasonable use of pointer! Finally, try to compile it into a 32-bit program. If you want to compile it into a 64 bit program, you need to modify the variable type yourself. Of course, you can run it if you don't change it!
Operation result
Advanced Demo
To be continued...