C++获取指定程序的IAT

今天学习导入表,于是便通过程序将获取IAT的过程实现一下,各位看官发现什么问题,请多指教。谢谢!
废话不多说,下面是代码:


#include <iostream> #include <windows.h> #include <winnt.h> using namespace std; int main(int argc, char* argv[]) { if (argc != 2) { cout << "Usage: " << argv[0] <<" "<<argv[1]<<endl; exit(1); } HANDLE hFile = NULL; IMAGE_DOS_HEADER * pDosHeader = NULL; cout << argv[0] << "  " << argv[1] << endl; WCHAR  pwchar[255] = {0}; MultiByteToWideChar(CP_ACP, 0, argv[1], sizeof(argv[1]) + 1, pwchar, sizeof(pwchar)/sizeof(pwchar[0])); //hFile = CreateFile("D:\\project\\PEInfo\\Debug\\Loadsys.exe", GENERIC_READ, FILE_SHARE_READ| FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) cout << "CreateFile Error" << GetLastError() << endl; HANDLE hMap = 0; hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (!hMap) cout << "CreatefileMapping Error !" << endl; void * lpMemory = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0); pDosHeader = (IMAGE_DOS_HEADER *)lpMemory; if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) cout << "This File is not a PE File !" << endl; IMAGE_NT_HEADERS* pNtHeader = (IMAGE_NT_HEADERS*)((BYTE*)pDosHeader + pDosHeader->e_lfanew); cout << "----------------------------------------------------------------------" << endl; cout << "Number of Section: " << pNtHeader->FileHeader.NumberOfSections << endl; for (int i = 0; i < pNtHeader->FileHeader.NumberOfSections; ++i) { IMAGE_SECTION_HEADER * pSectionHeader = (IMAGE_SECTION_HEADER *)((pNtHeader->FileHeader.SizeOfOptionalHeader + 24 + (BYTE*)pNtHeader) + i * 0x28); cout << "Setction Name: " << pSectionHeader->Name << endl; } cout << "----------------------------------------------------------------------" << endl; IMAGE_IMPORT_DESCRIPTOR * pImportTabe = (IMAGE_IMPORT_DESCRIPTOR *)(pNtHeader->OptionalHeader.DataDirectory[1].VirtualAddress + (BYTE*)pDosHeader); IMAGE_IMPORT_DESCRIPTOR* pOriginalImportTable = pImportTabe; IMAGE_THUNK_DATA * pThunk = nullptr; IMAGE_IMPORT_BY_NAME* pINT = nullptr; DWORD n = 0; while (pImportTabe->Name) { cout <<"+-------------------------------------------------------------------"<< endl; cout << "+动态库:" << pImportTabe->Name + (BYTE*)pDosHeader << endl; cout << "                     +----导入函数名称表:" << endl; pThunk = (IMAGE_THUNK_DATA *)(pImportTabe->OriginalFirstThunk + (BYTE*)pDosHeader); while (pThunk->u1.Function) { pINT = (IMAGE_IMPORT_BY_NAME*)(pThunk->u1.Function + (BYTE*)pDosHeader); cout <<"                                     |------"<< pINT->Hint << " : " << pINT->Name << endl; //cout << ((DWORD*)(pImportTabe->FirstThunk + (BYTE*)pDosHeader) + n)<<endl; //printf("%x \n", ((DWORD*)(pImportTabe->FirstThunk + (BYTE*)pDosHeader) + n)); //n++; pThunk = (IMAGE_THUNK_DATA*)((BYTE*)pThunk + 4); } pImportTabe = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)pImportTabe + 20); } cout << "----------------------------------------------------------------------" << endl; return 0; }

转载于:https://www.cnblogs.com/nsxz85/p/4814803.html

  • 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、付费专栏及课程。

余额充值