获取当前进程的IAT

#include <windows.h>  
#include <stdio.h>  
  
int main(int argc, char* argv[])  
{  
    HMODULE hModule = ::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);  
  
    while (pImportDesc->FirstThunk)  
    {  
        char* pszDllName = (char*)((BYTE*)hModule + pImportDesc->Name);  
        printf("模块名称:%s\n", pszDllName);  
  
        DWORD n = 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("function name:%-25s,  ", pszFuncName);  
            //取得函数地址  
            PDWORD lpAddr = (DWORD*)((BYTE*)hModule + pImportDesc->FirstThunk) + n; //从第一个函数的地址,以后每次+4字节  
            printf("addrss:%X\n", lpAddr);  
            n++; //每次增加一个DWORD  
            pThunk++;  
        }  
        printf("\n");  
        pImportDesc++;  
    }  
    return 0;  
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值