【问题标题】:EXE or DLL Image base addressEXE 或 DLL 映像基址
【发布时间】:2010-11-28 18:39:28
【问题描述】:

在 C++/windows 中有没有办法获取 exe/DLL 映像基址? 谢谢:)

【问题讨论】:

  • 您可以使用(除了其他答案之外)EnumProcessModulesEx 和 GetModuleInformation,它们允许您为其他进程找到此信息。

标签: c++ windows portable-executable base-address


【解决方案1】:

如果您将二进制文件加载到您自己的进程中,您可以使用GetModuleHandle。它返回一个 HMODULE,但那是 the same as HINSTANCE and the base address

如果你想知道二进制更喜欢哪个基地址,你应该阅读 PE 头。请参阅here 并在 IMAGE_OPTIONAL_HEADER 中查找 ImageBase 字段。

编辑:GetModuleHandle(NULL) 将返回当前进程的基地址(尽管指定的类型是 HMODULE)。

【讨论】:

    【解决方案2】:

    如果您正在检查磁盘上的 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
    

    【讨论】:

      【解决方案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;
          // ...
      }
      

      【讨论】:

        【解决方案4】:

        如果您想从 DLL/EXE 中获取自己的 ImageBase 地址,那么如何:

        #include <winnt.h>
        
        EXTERN_C IMAGE_DOS_HEADER __ImageBase;
        

        【讨论】:

        • 在调试器中;可以在 &__ImageBase 上添加手表
        【解决方案5】:

        如果要枚举所有进程的模块,也可以使用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);
        }
        

        【讨论】:

          【解决方案6】:

          在下面的代码中找到 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;
          }
          

          【讨论】:

            【解决方案7】:

            有点hacky,但这也有效:

            https://ntopcode.wordpress.com/2018/02/26/anatomy-of-the-process-environment-block-peb-windows-internals/

            确保包含windows.h,最终在winnt.h 中包含NtCurrentTeb 的定义,以及winnt.h 需要的宏和类型定义,并确保包含winternl.h 用于struct _TEB类型定义。

            当我在 VMMap 中打开它时:

            (由于ASLR,这次地址不同)

            对于.dlls,还没有人提到这个方法:http://sandsprite.com/CodeStuff/Understanding_the_Peb_Loader_Data_List.html

            查看 kd 中的结构并为您的系统获取正确的偏移量,尽管它很少在 Windows 版本之间更改。

            这只是GetModuleHandle 的实现方式。它调用BasepGetModuleHandleExW,功能在RtlPcToFileHeader 中实现。如果参数为NULL,则返回return ((HMODULE)NtCurrentPeb()-&gt;ImageBaseAddress);,否则将使用PEB中其下方的Ldr成员解析地址空间中加载的dll列表,如sandsprite链接所示。

            可以看出,镜像基地址也是初始化顺序链表中的第一个模块。

            模块句柄只是转换为HMODULE 的地址,它只是一个HINSTANCE,它是一个HANDLE,它是一个PVOID,它是一个void* 指向一个void 的64 位指针。转换为任何一个都将对汇编输出产生相同的影响——它只有助于代码级别的概念清晰和编译器警告,并使句柄的实现对程序员透明;他们只需要将句柄传递给 API 函数,而不用担心它是否是指向 struct _EPROCESS 指向的句柄表的句柄条目的索引、64 位原始地址还是伪句柄。

            您可以在kd 中查看此内容,方法是使用 Process Explorer 获取进程 ID,然后执行(即,如果它是 pid 16416,则与上一个示例不同):

            lkd> ? 0n16416                    //convert denary to hex (output not shown in this example)
            lkd> !process 0x4020              //display eprocess for pid (or you can use !process 0n16416 without having to convert to hex) (output not shown in this example)
            lkd> .process /P 0xfffffa802edb1a80  //supply eprocess address acquired from the output of the !process command the current; sets current context to the context of that process (output not shown in this example)
            lkd> !peb                         //display the PEB of for the current process context                                                                                
            PEB at 000007fffffd3000                                                                                                      
                InheritedAddressSpace:    No                                                                                             
                ReadImageFileExecOptions: No                                                                                             
                BeingDebugged:            No                                                                                             
                ImageBaseAddress:         00000000ff0c0000                                                                               
                Ldr                       000000007794d640                                                                               
                Ldr.Initialized:          Yes                                                                                            
                Ldr.InInitializationOrderModuleList: 0000000000343cd0 . 00000000003b3950                                                 
                Ldr.InLoadOrderModuleList:           0000000000343bc0 . 00000000003b3930                                                 
                Ldr.InMemoryOrderModuleList:         0000000000343bd0 . 00000000003b3940                                                 
                        Base TimeStamp                     Module                                                                        
                    ff0c0000 559ea8be Jul 09 18:00:46 2015 C:\Windows\system32\NOTEPAD.EXE                                               
                    77820000 595fa942 Jul 07 16:31:14 2017 C:\Windows\SYSTEM32\ntdll.dll                                                 
                    77700000 595fa987 Jul 07 16:32:23 2017 C:\Windows\system32\kernel32.dll                                              
                 7fefd700000 595fa988 Jul 07 16:32:24 2017 C:\Windows\system32\KERNELBASE.dll                                            
                 7fefed00000 595fa8e2 Jul 07 16:29:38 2017 C:\Windows\system32\ADVAPI32.dll                                              
                 7feffa90000 4eeb033f Dec 16 08:37:19 2011 C:\Windows\system32\msvcrt.dll                                                
                 7feff780000 55636728 May 25 19:17:12 2015 C:\Windows\SYSTEM32\sechost.dll                                               
                 7fefd9a0000 595fa8ec Jul 07 16:29:48 2017 C:\Windows\system32\RPCRT4.dll                                                
                 7feff100000 5915fd6c May 12 19:22:36 2017 C:\Windows\system32\GDI32.dll                                                 
                    77600000 5824a140 Nov 10 16:33:04 2016 C:\Windows\system32\USER32.dll                                                
                 7fefee10000 5915fd82 May 12 19:22:58 2017 C:\Windows\system32\LPK.dll                                                   
                 7fefdad0000 5915fd8f May 12 19:23:11 2017 C:\Windows\system32\USP10.dll                                                 
                 7fefde20000 4ce7c635 Nov 20 12:59:33 2010 C:\Windows\system32\COMDLG32.dll                                              
                 7fefee20000 4ce7c9ab Nov 20 13:14:19 2010 C:\Windows\system32\SHLWAPI.dll                                               
                 7fefcff0000 553a8775 Apr 24 19:12:05 2015 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0
                 7fefdec0000 591331f3 May 10 16:29:55 2017 C:\Windows\system32\SHELL32.dll                                               
                 7fefa1d0000 4ce7ca38 Nov 20 13:16:40 2010 C:\Windows\system32\WINSPOOL.DRV                                              
                 7fefdba0000 58f4e14a Apr 17 16:37:46 2017 C:\Windows\system32\ole32.dll                                                 
                 7feff190000 58f4e14e Apr 17 16:37:50 2017 C:\Windows\system32\OLEAUT32.dll                                              
                 7fefd500000 4a5be082 Jul 14 02:33:54 2009 C:\Windows\system32\VERSION.dll                                               
                 7fefede0000 4a5bdf40 Jul 14 02:28:32 2009 C:\Windows\system32\IMM32.DLL                                                 
                 7feff980000 57fd0632 Oct 11 16:33:06 2016 C:\Windows\system32\MSCTF.dll                                                 
                 7fefd510000 5b046e43 May 22 20:23:47 2018 C:\Windows\system32\nvinitx.dll                                               
                    75190000 57f433c5 Oct 04 23:57:09 2016 C:\Program Files\NVIDIA Corporation\CoProcManager\detoured.dll                
                 7fefa4e0000 5b047092 May 22 20:33:38 2018 C:\Program Files\NVIDIA Corporation\CoProcManager\nvd3d9wrapx.dll             
                 7feff7a0000 4ce7c9a2 Nov 20 13:14:10 2010 C:\Windows\system32\SETUPAPI.dll                                              
                 7fefd8e0000 4ce7c55c Nov 20 12:55:56 2010 C:\Windows\system32\CFGMGR32.dll                                              
                 7fefd6e0000 4a5bdee1 Jul 14 02:26:57 2009 C:\Windows\system32\DEVOBJ.dll                                                
                 7fefa4b0000 5b04708d May 22 20:33:33 2018 C:\Program Files\NVIDIA Corporation\CoProcManager\nvdxgiwrapx.dll             
                 7fefd2b0000 5a147c83 Nov 21 19:20:35 2017 C:\Windows\system32\guard64.dll                                               
                 7fefd290000 5879cba2 Jan 14 06:56:34 2017 C:\Windows\system32\api-ms-win-core-synch-l1-2-0.DLL                          
                 7fefcf80000 4a5bdeff Jul 14 02:27:27 2009 C:\Windows\system32\fltlib.dll                                                
                 7fefd430000 595fa9c6 Jul 07 16:33:26 2017 C:\Windows\system32\CRYPTBASE.dll                                             
                 7fefb4c0000 4a5be093 Jul 14 02:34:11 2009 C:\Windows\system32\uxtheme.dll                                               
                 7fefb090000 559eb4fe Jul 09 18:53:02 2015 C:\Windows\system32\dwmapi.dll                                                
                SubSystemData:     0000000000000000                                                                                      
                ProcessHeap:       0000000000340000                                                                                      
                ProcessParameters: 0000000000342a50                                                                                      
                CurrentDirectory:  'C:\Program Files (x86)\IntelSWTools\VTune Amplifier XE 2016\'                                        
                WindowTitle:  'C:\Users\lewis\Desktop\support.txt - Shortcut.lnk'                                                        
                ImageFile:    'C:\Windows\system32\NOTEPAD.EXE'        
                DllPath:      'C:\Windows\system32;C:\Windows\system32;C:\Windows\system;C:\Windows;.;C:\Program Files (x86)\IntelSWTools\VTune Amplifier XE 2016\bin32;C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\Hostx64\x64;C:\Program Files\ImageMagick-7.0.10-Q16-HDRI;C:\Users\lewis\Desktop\IDA_Pro_v6.8_and_Hex-Rays_Decompiler_(ARM,x64,x86)\;C:\Program Files\Java\jdk-9\bin;C:\Program Files\ImageMagick-7.0.10-Q16-HDRI;C:\Program Files\Debugging Tools for Windows (x64)\;C:\Windows\system32;C:\Windows\system32\ffmpeg\bin;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\texlive\2017\bin\win32;C:\adb;C:\Users\lewis\AppData\Local\Programs\Python\Python36-32\;C:\Users\lewis\AppData\Local\Programs\Python\Python36-32\Scripts;C:\Users\lewis\Desktop\New folder (2)\sqlmapproject-sqlmap-6402d2e;C:\Program Files\PuTTY\;C:\Program Files\Java\jdk-9\bin;;C:\Users\lewis\AppData\Local\Programs\hyper\resources\bin'
                Environment:  00000000003c7ff0                                                
                    =C:=C:\Users\lewis\Desktop
                    =ExitCode=00000000
                    ALLUSERSPROFILE=C:\ProgramData
                    APPDATA=C:\Users\lewis\AppData\Roaming
                    CLASSPATH=.;C:\Program Files\Java\jdk-9\lib
                    CommonProgramFiles=C:\Program Files\Common Files
                    CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
                    CommonProgramW6432=C:\Program Files\Common Files
                    COMPUTERNAME=QWERTYUIOP
                    ComSpec=C:\Windows\system32\cmd.exe
                    FP_NO_HOST_CHECK=NO
                    HOMEDRIVE=C:
                    HOMEPATH=\Users\lewis
                    JAVA_HOME=C:\Program Files\Java\jdk-9
                    JDK_HOME=C:\Program Files\Java\jdk-9
                    LOCALAPPDATA=C:\Users\lewis\AppData\Local
                    LOGONSERVER=\\QWERTYUIOP
                    NUMBER_OF_PROCESSORS=8
                    NVIDIAWHITELISTED=0x01
                    ORIGINAL_XDG_CURRENT_DESKTOP=undefined
                    OS=Windows_NT
                    Path=C:\Program Files (x86)\IntelSWTools\VTune Amplifier XE 2016\bin32;C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\Hostx64\x64;C:\Program Files\ImageMagick-7.0.10-Q16-HDRI;C:\Users\lewis\Desktop\IDA_Pro_v6.8_and_Hex-Rays_Decompiler_(ARM,x64,x86)\;C:\Program Files\Java\jdk-9\bin;C:\Program Files\ImageMagick-7.0.10-Q16-HDRI;C:\Program Files\Debugging Tools for Windows (x64)\;C:\Windows\system32;C:\Windows\system32\ffmpeg\bin;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\QuickTime\QTSystem\;C:\texlive\2017\bin\win32;C:\adb;C:\Users\lewis\AppData\Local\Programs\Python\Python36-32\;C:\Users\lewis\AppData\Local\Programs\Python\Python36-32\Scripts;C:\Users\lewis\Desktop\New folder (2)\sqlmapproject-sqlmap-6402d2e;C:\Program Files\PuTTY\;C:\Program Files\Java\jdk-9\bin;;C:\Users\lewis\AppData\Local\Programs\hyper\resources\bin
                    PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
                    PROCESSOR_ARCHITECTURE=AMD64
                    PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 158 Stepping 9, GenuineIntel
                    PROCESSOR_LEVEL=6
                    PROCESSOR_REVISION=9e09
                    ProgramData=C:\ProgramData
                    ProgramFiles=C:\Program Files
                    ProgramFiles(x86)=C:\Program Files (x86)
                    ProgramW6432=C:\Program Files
                    PROMPT=$P$G
                    PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
                    PT7HOME=C:\Program Files\Cisco Packet Tracer 7.0
                    PUBLIC=C:\Users\Public
                    PYTHON_HOME=C:\Users\lewis\AppData\Local\Programs\Python\Python36-32
                    QTJAVA=C:\Program Files (x86)\QuickTime\QTSystem\QTJava.zip
                    SESSIONNAME=Console
                    SHIM_MCCOMPAT=0x810000001
                    SystemDrive=C:
                    SystemRoot=C:\Windows
                    TEMP=D:\System\Temp
                    TMP=D:\System\Temp
                    USERDOMAIN=QWERTYUIOP
                    USERNAME=lewis
                    USERPROFILE=C:\Users\lewis
                    VBOX_MSI_INSTALL_PATH=C:\Program Files\Oracle\VirtualBox\
                    VTUNE_AMPLIFIER_XE_2016_DIR=C:\Program Files (x86)\IntelSWTools\VTune Amplifier XE 2016\
                    windir=C:\Windows
                    windows_tracing_flags=3
                    _NT_SYMBOL_PATH=srv*c:\symbols*http://msdl.microsoft.com/download/symbols
                    LANG=en_GB.UTF-8
                    TERM=xterm-256color
                    COLORTERM=truecolor
                    TERM_PROGRAM=Hyper
                    TERM_PROGRAM_VERSION=3.1.0-canary.4                  
            

            要获取内核模块库,您可以使用.reload 命令后跟lm,如果在快照时映射了PEB,它还将显示.process 设置的当前进程上下文的用户库被采取(在livekd的情况下)或当时(在kd -kl本地调试的情况下)。

            .reload 在当前进程上下文中搜索 PEB 中的模块,如果 PEB 被映射进来以了解它们的名称、基数和长度,并且还遍历 PsLoadedModuleList 以获取内核模块名称、基数和长度,但是卸载/不加载除基本模块之外的任何模块的符号,它加载更少或更多基本.pdbs,具体取决于.pdb是否在本地缓存或是否需要从符号服务器下载(如果您没有指定缓存,则发送到sym\ 中的缓存或它自己的缓存)。您必须使用ld *.reload /f 加载符号,并确保.sympathsrv*C:\localcache\*https://https://msdl.microsoft.com/download/symbols。当 PEB 未映射时,您必须使用 VMMap / Process Explorer 来获取模块的基地址和长度。如果 PEB 未在 .reload kernel32 中映射,则它将无法工作,因为它无法找到该模块,但如果您通过提供从 Process Explorer 获取的基址和地址来告诉它它在哪里,.reload kernel32.dll 775c0000,11f000 将工作。无论/f 设置如何,为模块提供地址也会从该地址开始加载要与它一起使用的符号。 lm 显示找到的所有模块、地址、最终页面分配后第一页的地址、名称以及是否已在调试器中为它们加载符号。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-10-05
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多