2010-11-28 48 views
14

在C++/windows中有沒有獲得exe/DLL圖像基地址的方法? 謝謝:)EXE或DLL圖像基地址

+0

您可以使用(除了其他答案)EnumProcessModulesEx和GetModuleInformation,它允許您爲其他進程查找此信息。 – Ironside 2013-02-19 20:41:54

回答

14

如果您將二進制文件加載到您自己的進程中,您可以使用GetModuleHandle。它返回一個HMODULE,但是這是the same as HINSTANCE and the base address

如果你想知道二進制首選的基地址,你應該讀PE頭。請參閱here並查找IMAGE_OPTIONAL_HEADER中的ImageBase字段。

編輯:GetModuleHandle(NULL)將返回當前進程的基地址(儘管指定的類型是HMODULE)。

6

如果您正在檢查磁盤上的DLL或EXE文件,請使用dumpbin實用程序。它與Visual Studio或SDK一起安裝。的dumpbin /headers

輸出示例:

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 
2

如果要列舉所有進程的模塊,你也可以使用CreateToolhelp32Snapshot

#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); 
} 
3

我發現,最方便和最準確的方式來獲得模塊基地址(和內存中的圖像大小)是通過GetModuleInformation(包括psapi.h,鏈接到psapi.lib):

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; 
    // ... 
} 
2

如果你想從一個DLL/EXE中獲得自己的基址地址,然後這個怎麼樣:

#include <winnt.h> 

EXTERN_C IMAGE_DOS_HEADER __ImageBase; 
+0

並在調試器中;可以在&__ ImageBase上添加手錶 – 2018-02-17 12:27:06

0

找到下面的代碼找到映像基址在CPP:

#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<<"\n CreateFile failed \n"; 
     return 1; 
    } 

    hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL); 

    if(hFileMapping==0) 
    { 
     std::cout<<"\n CreateFileMapping failed \n"; 
     CloseHandle(hFile); 
     return 1; 
    } 

    lpFileBase = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0); 

    if(lpFileBase==0) 
    { 
     std::cout<<"\n MapViewOfFile failed \n"; 
     CloseHandle(hFileMapping); 
     CloseHandle(hFile); 
     return 1; 
    } 

    dosHeader = (PIMAGE_DOS_HEADER) lpFileBase; 
    if(dosHeader->e_magic==IMAGE_DOS_SIGNATURE) 
    { 
     std::cout<<"\n DOS Signature (MZ) Matched \n"; 

     peHeader = (PIMAGE_NT_HEADERS) ((u_char*)dosHeader+dosHeader->e_lfanew); 
     if(peHeader->Signature==IMAGE_NT_SIGNATURE) 
     { 
      std::cout<<"\n PE Signature (PE) Matched \n"; 
      //once found valid exe or dll 
      std::cout<<"\n Image Base : "<<std::hex<<peHeader->OptionalHeader.ImageBase; 
     } 
     else 
     { 
      return 1; 
     } 
    } 
    else 
    { 
     return 1; 
    } 
    return 0; 
}