如何找出.exe文件中的主要功能在哪里?

How to find out where the main function in an .exe file is?

我创建了一个简单的 .exe 文件,它只是将值 3 赋给一个名为 "x" 的整数,然后打印出 value.Here 是源代码的图片:

source code

我用十六进制编辑器(名为HxD)打开.exe文件,并使用Visual Studio 2017的反汇编功能向我展示了我的主要功能的操作码。经过一番搜索后,我发现主要功能存储在偏移量 0xC10

的文件中

这里是反汇编:disassembly

这是十六进制编辑器中的文件:hexadecimal view of .exe file

我知道十六进制编辑器中 .exe 文件的某些值与 visual studio 调试器所说的不同,但我知道主要从那里开始,因为我在十六进制编辑器中更改了 x 的值,并且然后,当我启动 .exe 时,它​​打印出另一个值而不是 3。我的问题是 .exe 文件中的哪个值表示:"At that point of the file start the opcodes of the main function."

例如,在 .bmp 文件中,位置 0x0A、0x0B、0x0C 和 0x0D 的 4 个字节告诉您第一个像素的第一个字节的偏移量。

一个.exe是一个portable executable

Layout

Structure of a Portable Executable 32 bit A PE file consists of a number of headers and sections that tell the dynamic linker how to map the file into memory. An executable image consists of several different regions, each of which require different memory protection; so the start of each section must be aligned to a page boundary.[4] For instance, typically the .text section (which holds program code) is mapped as execute/readonly, and ...

所以实际上这是 .text 部分在文件中的位置的问题。具体位置取决于 headers 和其他部分的位置。

在 Windows 上,可执行文件 (.exe) 的 入口点 设置在文件的 PE Header 中。

WikiPedia 说明了这个 header like this (SVG file) 的结构。

相对于文件的开头,PE Header 从地址

指示的位置开始

DWORD 0x3C Pointer to PE Header

      File Header / DOS Header
     +--------------------+--------------------+
0000 |  0x5A4D  |         |                    |
0008 |                    |                    |
0010 |                    |                    |
0018 |                    |                    |
0020 |                    |                    |
0028 |                    |                    |
0030 |                    |                    |
0038 |                    | PE Header addr     |
0040 |                    |                    |
.... | .................. | .................. |

并且入口点被指定在位置(相对于上面的地址)

DWORD 0x28 EntryPoint

      PE Header
     +--------------------+--------------------+
0000 | Signature          | Machine | NumOfSect|
0008 | TimeDateStamp      | PtrToSymTable      |
0010 | NumOfSymTable      |SizOfOHdr| Chars    |
0018 | Magic   | MJV| MNV | SizeOfCode         |
0020 | SizeOfInitData     | SizeOfUnInitData   |
0028 | EntryPoint (RVA)   | BaseOfCode (RVA)   |
0030 | BaseOfData (RVA)   | ImageBase          |
0038 | SectionAlignment   | FileAlignment      |
0040 | ...                | ...                |

从PE开始Header。这个地址是一个RVA (Relative Virtual Address),这意味着它是相对于加载器加载文件的图像基地址的:

Relative virtual addresses (RVAs) are not to be confused with standard virtual addresses. A relative virtual address is the virtual address of an object from the file once it is loaded into memory, minus the base address of the file image.

这个地址是main函数的地址。