获取IAT里的函数地址并修改

/* 1 */HANDLE hCurrent = GetModuleHandle(NULL);
/* 2 */IMAGE_DOS_HEADER *pidh;
/* 3 */IMAGE_NT_HEADERS *pinh;
/* 4 */IMAGE_DATA_DIRECTORY *pSymbolTable;
/* 5 */IMAGE_IMPORT_DESCRIPTOR *piid;
 
/* 6 */pidh = (IMAGE_DOS_HEADER *)hCurrent; 
/* 7 */pinh = (IMAGE_NT_HEADERS *)((DWORD)hCurrent + pidh->e_lfanew);
/* 8 */pSymbolTable = &pinh->OptionalHeader.DataDirectory[1];
/* 9 */piid =(IMAGE_IMPORT_DESCRIPTOR *)((DWORD)hCurrent +  pSymbolTable->VirtualAddress);
/*10 */do {
/*11 */    IMAGE_THUNK_DATA *pitd,*pitd2;
/*12 */    pitd = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->OriginalFirstThunk);
/*13 */    pitd2 = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->FirstThunk);
/*14 */    do {
/*15 */ IMAGE_IMPORT_BY_NAME *piibn;
/*16 */ piibn = (IMAGE_IMPORT_BY_NAME *)((DWORD)hCurrent +  *((DWORD *)pitd));
/*17 */ PROC *ppfn = (PROC *)(pitd2->u1.Function);
/*18 */ if (!strcmp("MessageBoxW",(char *)piibn->Name)) {
/*19 */     oldMsg = (MsgBoxType)(ppfn);
/*20 */     DWORD addr = (DWORD)MyMessage;
/*21 */     DWORD written = 0;
      /* 改变内存读写状态 */
/*22 */     DWORD oldAccess;
/*23 */     VirtualProtect(&pitd2->u1.Function,sizeof(DWORD),PAGE_WRITECOPY,&oldAccess);
/*24 */     APIAddress = (DWORD)&pitd2->u1.Function;
      /* 向内存映像写入数据 */
/*25 */     WriteProcessMemory(GetCurrentProcess(),&pitd2->u1.Function, &addr,sizeof(DWORD), &written);
/*26 */ }
/*27 */ pitd++;pitd2++;
/*28 */    } while (pitd->u1.Function);
 
/*29 */    piid++;
/*30 */} while (piid->FirstThunk + piid->Characteristics 
  + piid->ForwarderChain + piid->Name + piid->TimeDateStamp);








HANDLE hMap;
switch (reason) {
    case DLL_PROCESS_ATTACH:
    /*创建/打开共享内存区域*/
    hMap = CreateFileMapping((HFILE *)0xFFFFFFFF,NULL,PAGE_READWRITE,0,sizeof(GLOBALDATA),ID_MAP);
    pg_data = (GLOBALDATA*)MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0 ,0 ,0);
    if (!pg_data) {
 MessageBox(NULL,"无法建立共享内存,程序终止!",szApp,MB_OK);
 if (hMap) {
     CloseHandle(hMap);
     hMap = NULL;
     return 0;
       }
    }
    pg_data->hInst = hInst;
    showerr("共享内存映像文件");
    showerr("DLL装载中...",FALSE);
    break;
    case DLL_PROCESS_DETACH:
    if (pg_data) {
        UnmapViewOfFile(pg_data);
 pg_data = NULL;
    }
    if (hMap) {
 CloseHandle(hMap);
 hMap = NULL;
     }
    break;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
获取IAT表中的函数地址可以使用以下步骤: 1. 获取PE文件的基地址 2. 定位到PE文件的导入表(Import Table),获取导入表的 RVA 和 Size 3. 遍历导入表中的每一个导入描述符(Import Descriptor) 4. 对于每一个导入描述符,获取其名称表(Name Table)的 RVA 和 Size,以及导入地址表(Import Address Table,也称为IAT)的 RVA 5. 遍历导入地址表中的每一个函数地址,即可获取IAT表中的函数地址。 下面是伪代码实现: ```C++ // 获取PE文件基地址 HMODULE hModule = GetModuleHandle(NULL); // 获取导入表 PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule; PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((DWORD)pDosHeader + pDosHeader->e_lfanew); PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hModule + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); DWORD dwImportSize = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size; // 遍历导入表 while (pImportDesc->Name != 0) { // 获取名称表和IAT表 PIMAGE_THUNK_DATA pNameTable = (PIMAGE_THUNK_DATA)((DWORD)hModule + pImportDesc->OriginalFirstThunk); PIMAGE_THUNK_DATA pIat = (PIMAGE_THUNK_DATA)((DWORD)hModule + pImportDesc->FirstThunk); // 遍历IAT表中的每一个函数地址 while (pNameTable->u1.AddressOfData != 0) { // 获取函数名称 PIMAGE_IMPORT_BY_NAME pImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD)hModule + pNameTable->u1.AddressOfData); LPCSTR lpFunctionName = (LPCSTR)pImportByName->Name; // 获取函数地址 FARPROC fpFunction = (FARPROC)pIat->u1.Function; // 处理函数地址 // ... // 下一个函数 pNameTable++; pIat++; } // 下一个导入描述符 pImportDesc++; } ``` 注意:在遍历导入表时,需要检查导入描述符的 Name 字段是否为 0,以判断是否到达导入表的末尾。在遍历IAT表时,需要检查名称表中的 AddressOfData 字段是否为 0,以判断是否到达IAT表的末尾。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值