2010-11-28 18 views
14

Est-il possible d'obtenir l'adresse de base de l'image exe/DLL dans C++/windows? merci :)EXE ou DLL Adresse de base de l'image

+0

Vous pouvez utiliser (en plus des autres réponses) EnumProcessModulesEx et GetModuleInformation qui vous permettent de trouver cette information pour d'autres processus. – Ironside

Répondre

14

Si vous chargez le binaire dans votre propre processus, vous pouvez utiliser GetModuleHandle. Il renvoie un HMODULE, mais c'est the same as HINSTANCE and the base address.

Si vous voulez connaître l'adresse de base que le binaire préfère, lisez l'en-tête PE. Voir here et recherchez le champ ImageBase dans IMAGE_OPTIONAL_HEADER. Edit: GetModuleHandle (NULL) renvoie l'adresse de base (bien que le type spécifié soit HMODULE) pour le processus en cours.

6

Si vous examinez un fichier DLL ou EXE sur le disque, utilisez l'utilitaire dumpbin. Il est installé avec Visual Studio ou le SDK.

Exemple de sortie de 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

Si vous voulez énumérer les modules de tous les processus, vous pouvez également utiliser 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

Je trouve que la façon la plus pratique et précis pour obtenir des années modules l'adresse de base (et la taille de l'image en mémoire) est via GetModuleInformation (inclure psapi.h, lien vers 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

Si vous souhaitez obtenir votre propre adresse ImageBase à l'intérieur d'une DLL/EXE alors que diriez-vous:

#include <winnt.h> 

EXTERN_C IMAGE_DOS_HEADER __ImageBase; 
+0

et dans le débogueur; peut ajouter une montre sur & ImageBase –

0

trouverez ci-dessous le code pour trouver l'adresse de base d'image du RPC:

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