web-dev-qa-db-ja.com

EXEまたはDLLイメージのベースアドレス

C++/windowsでexe/DLLイメージのベースアドレスを取得する方法はありますか?ありがとう:)

14
Idov

バイナリを独自のプロセスにロードする場合は、 GetModuleHandle を使用できます。 HMODULEを返しますが、それは HINSTANCEおよびベースアドレスと同じ です。

バイナリが優先するベースアドレスを知りたい場合は、PEヘッダーを読む必要があります。 here を参照し、IMAGE_OPTIONAL_HEADERでImageBaseフィールドを探します。

編集:GetModuleHandle(NULL)は、現在のプロセスのベースアドレス(指定されたタイプはHMODULEですが)を返します。

16
Lars Truijens

ディスク上のDLLまたはEXEファイルを調べる場合は、 dumpbin ユーティリティを使用します。VisualStudioまたは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
6
shf301

モジュールのベースアドレス(およびメモリ内の画像サイズ)を取得する最も便利で正確な方法は、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;
    // ...
}
4
Arty OneSoul

DLL/EXE内から独自のImageBaseアドレスを取得したい場合は、次のようにします。

#include <winnt.h>

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
3

すべてのプロセスのモジュールを列挙する場合は、 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);
}
2
Mi-La

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