我创建了一个简单的.exe文件,只是将值3赋给一个名为“x”的整数,然后输出该值。这是源代码的图片:
我用十六进制编辑器(名为HxD)打开.exe文件,并使用Visual Studio 2017的反汇编功能向我显示我的主函数的操作码。经过一些搜索后,我发现主函数存储在Offset 0xC10的文件中
这是拆卸:disassembly
这里是Hex-Editor中的文件:hexadecimal view of .exe file
我知道十六进制编辑器中的.exe文件的某些值与visual studio调试器的说法有所不同,但我知道主要的启动是因为我在十六进制编辑器中更改了x的值,然后当我启动.exe时打印出另一个值而不是3.我的问题是.exe文件中的值是这样的值:“在文件的那一点开始主函数的操作码。”
例如,在.bmp文件中,位置0x0A,0x0B,0x0C和0x0D处的4个字节告诉您第一个像素的第一个字节的偏移量。
.exe
是portable executable。
布局
可移植可执行文件32位的结构PE文件由许多标头和部分组成,这些标头和部分告诉动态链接器如何将文件映射到内存中。可执行映像由几个不同的区域组成,每个区域都需要不同的内存保护。所以每个部分的开头必须与页面边界对齐。[4]例如,通常将.text段(包含程序代码)映射为execute / readonly,并且...
所以真的是.text
部分在文件中的位置的问题。究竟在哪里取决于其他部分的标题和位置。
在Windows上,可执行文件的入口点(.exe
)在文件的PE Header中设置。
WikiPedia说明了这个标题like this (SVG file)的结构。
相对于文件的开头,PE标头从地址指示的位置开始
DWORD 0x3C指向PE标头的指针
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),这意味着它相对于加载器加载文件的Image Base地址:
不要将相对虚拟地址(RVAs)与标准虚拟地址混淆。相对虚拟地址是文件加载到内存后的文件的虚拟地址,减去文件图像的基地址。
该地址是主函数的地址。