我主要是按照微软的文档来做的,但是在如何计算一些字段和操作系统如何使用这些字段的解释上有一些漏洞。
我正试图从头开始,在不使用LLVM和libc的情况下制作自己的编程语言,所以目前我的重点是学习PE文件格式,以便能够生成一个打印 "Hello World "的二进制文件。
我已经用x86 ASM做了程序的代码,然后翻译成了操作码。
有一些东西目前是硬编码的(节数,.text节内容,...)。
我比较了由Visual Studio链接器(link.exe)和我的 "编译器 "链接的ASM代码的结果。
我不太明白下面的fieds:1.SizeOfInitializedData,我不知道如何计算它(似乎是.text和.rdata部分的大小相加)2.AddressOfEntryPoint,Visual Studio链接程序(link.exe)和我的 "编译器 "链接的ASM代码的结果。AddressOfEntryPoint,Visual linker把它放在文件末尾吗??3.BaseOfCode吗??4.BaseOfData吗?
对于节头,SizeOfRawData大于VirtualAddress是否正常?因为当我阅读文档时,与我从真实的二进制文件中得到的信息相比,这些值似乎是相反的。
我可以把MS-Dos stub的大小设为0吗,还是必须要有一个?
也许有更好的文档来学习如何使用不同的部分,尤其是导入和重定位的部分?我也认为静态数据的部分也很重要。
下面是我的x86 ASM代码,是nasm格式的。
; How to build (you'll need nasm compiler and Visual Studio)
; Be sure that nasm compiler path is in your PATH env
; nasm -fwin32 hello_world.nasm
;
; From a native Visual Studio Tools Command prompt
; link /subsystem:console /nodefaultlib /entry:main hello_world.obj kernel32.lib
global _main
extern _GetStdHandle@4
extern _WriteFile@20
extern _ExitProcess@4
section .text
_main:
; DWORD bytes;
mov ebp, esp
sub esp, 4
; hStdOut = GetstdHandle(STD_OUTPUT_HANDLE)
push -11
call _GetStdHandle@4
mov ebx, eax
; WriteFile( hstdOut, message, length(message), &bytes, 0);
push 0
lea eax, [ebp-4]
push eax
push (message_end - message)
push message
push ebx
call _WriteFile@20
; ExitProcess(0)
push 0
call _ExitProcess@4
; never here
hlt
message:
db 'Hello World', 9
message_end: