EXE or DLL Image base address
在C / windows中是否有一种获取exe / DLL映像基址的方法?
谢谢:)
如果将二进制文件加载到自己的进程中,则可以使用GetModuleHandle。它返回一个HMODULE,但是与HINSTANCE和基地址相同。
如果您想知道二进制文件首选的基址,则应阅读PE标头。在此处查看并在IMAGE_OPTIONAL_HEADER中查找ImageBase字段。
编辑:GetModuleHandle(NULL)将返回当前进程的基地址(虽然指定的类型为HMODULE)。
我发现获取模块基地址(和内存中图像大小)的最方便,最准确的方法是通过GetModuleInformation(包括psapi.h,链接到psapi.lib):
1 2 3 4 5 6 | MODULEINFO module_info; memset(&module_info, 0, sizeof(module_info)); if (GetModuleInformation(GetCurrentProcess(), hModule, &module_info, sizeof(module_info))) { DWORD module_size = module_info.SizeOfImage; BYTE * module_ptr = (BYTE*)module_info.lpBaseOfDll; // ... } |
如果要检查磁盘上的DLL或EXE文件,请使用dumpbin实用程序。它与Visual Studio或SDK一起安装。
dumpbin / header的示例输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | FILE HEADER VALUES 14C machine (i386) 6 number of sections 306F7A22 time date stamp Sun Oct 01 22:35:30 1995 0 file pointer to symbol table 1D1 number of symbols E0 size of optional header 302 characteristics Executable 32 bit word machine Debug information stripped OPTIONAL HEADER VALUES 10B magic # 2.60 linker version 1E00 size of code 1E00 size of initialized data 0 size of uninitialized data 1144 address of entry point 1000 base of code 3000 base of data ----- new ----- **2BB0000 image base** <--- This is what you are looking for 1000 section alignment 200 file alignment 3 subsystem (Windows CUI) 4.00 operating system version 4.00 image version 3.50 subsystem version 8000 size of image 400 size of headers 62C8 checksum 100000 size of stack reserve 1000 size of stack commit 100000 size of heap reserve 1000 size of heap commit 0 [ 0] address [size] of Export Directory 5000 [ 3C] address [size] of Import Directory 6000 [ 394] address [size] of Resource Directory 0 [ 0] address [size] of Exception Directory 0 [ 0] address [size] of Security Directory 7000 [ 21C] address [size] of Base Relocation Directory 3030 [ 38] address [size] of Debug Directory 0 [ 0] address [size] of Description Directory 0 [ 0] address [size] of Special Directory 0 [ 0] address [size] of Thread Storage Directory 0 [ 0] address [size] of Load Configuration Directory 268 [ 44] address [size] of Bound Import Directory 50A0 [ 64] address [size] of Import Address Table Directory 0 [ 0] address [size] of Reserved Directory 0 [ 0] address [size] of Reserved Directory 0 [ 0] address [size] of Reserved Directory SECTION HEADER #1 .text name 1D24 virtual size 1000 virtual address 1E00 size of raw data 400 file pointer to raw data 0 file pointer to relocation table 3C20 file pointer to line numbers 0 number of relocations 37E number of line numbers 60000020 flags Code (no align specified) Execute Read |
如果要从DLL / EXE内部获取自己的ImageBase地址,该怎么做:
1 2 3 | #include <winnt.h> EXTERN_C IMAGE_DOS_HEADER __ImageBase; |
如果要枚举所有进程的模块,也可以使用CreateToolhelp32Snapshot:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <windows.h> #include <tlhelp32.h> std::vector<std::pair<std::string, uint32_t> > base_addresses; // take a snapshot of all modules in the specified process HANDLE snaphot_handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0); if (snaphot_handle != INVALID_HANDLE_VALUE) { // first module MODULEENTRY32 mod_entry; mod_entry.dwSize = sizeof(mod_entry); if (Module32First(snaphot_handle, &mod_entry)) { // iterate through the module list of the process do { base_addresses.push_back( std::make_pair(mod_entry.szModule, static_cast<uint32_t>(mod_entry.modBaseAddr)); } while (Module32Next(snaphot_handle, &mod_entry)); } CloseHandle(snaphot_handle); } |
有点黑,但这也可行:

https://ntopcode.wordpress.com/2018/02/26/anatomy-of-the-process-environment-block-peb-windows-internals/
确保包含
当我在VMMap中打开它时:
(由于ASLR,地址这次有所不同)
对于.dll,尚无人提及此方法:http://sandsprite.com/CodeStuff/Understanding_the_Peb_Loader_Data_List.html
查看kd中的结构并为您的系统获取正确的偏移量,尽管它在Windows版本中很少更改。
这仅是无论如何实现
中所示。
模块句柄只是转换为
查找以下代码以查找CPP中的图像基址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | #include<windows.h> #include<iostream> int main() { LPCSTR fileName="inputFile.exe"; HANDLE hFile; HANDLE hFileMapping; LPVOID lpFileBase; PIMAGE_DOS_HEADER dosHeader; PIMAGE_NT_HEADERS peHeader; PIMAGE_SECTION_HEADER sectionHeader; hFile = CreateFileA(fileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); if(hFile==INVALID_HANDLE_VALUE) { std::cout<<"\ CreateFile failed \ "; return 1; } hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL); if(hFileMapping==0) { std::cout<<"\ CreateFileMapping failed \ "; CloseHandle(hFile); return 1; } lpFileBase = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0); if(lpFileBase==0) { std::cout<<"\ MapViewOfFile failed \ "; CloseHandle(hFileMapping); CloseHandle(hFile); return 1; } dosHeader = (PIMAGE_DOS_HEADER) lpFileBase; if(dosHeader->e_magic==IMAGE_DOS_SIGNATURE) { std::cout<<"\ DOS Signature (MZ) Matched \ "; peHeader = (PIMAGE_NT_HEADERS) ((u_char*)dosHeader+dosHeader->e_lfanew); if(peHeader->Signature==IMAGE_NT_SIGNATURE) { std::cout<<"\ PE Signature (PE) Matched \ "; //once found valid exe or dll std::cout<<"\ Image Base :"<<std::hex<<peHeader->OptionalHeader.ImageBase; } else { return 1; } } else { return 1; } return 0; } |