我一直在研究一個簡單的用於Linux的PE進程加載器。我想我已經掌握了基礎知識;我使用的大部分代碼來自binfmt_elf.c
和binfmt_aout.c
。我的測試可執行文件的是儘可能(FASM格式)簡單:。內存中的文本在執行過程中被覆蓋
format PE GUI 4.0
entry main
section '.text' code readable executable
main:
mov eax, 4
add eax, 5
ret
這個程序(math1
)編譯32位和虛擬機,我在(Xubuntu上12.04)運行也是32位。我將loader作爲內核模塊編譯並使用insmod
進行安裝。該加載程序似乎工作到目前爲止,我已經檢查了每個可能的步驟的錯誤代碼。它所做的全部是mmap
開始地址0x401000
處的代碼部分,並用該地址呼叫start_thread()
。如果我在命令行輸入類似./math1.exe
的東西,我的加載器確實會被調用。所以,如果一切按計劃進行,我應該每次得到返回值9
。然而,不是每次都執行段錯誤math1
,所以我在gdb
中打開它以查看發生了什麼。
執行前,一切看起來都很正常。如果我傾倒的起始地址,我看看到底是什麼,我應該(我可以證實,這是上述程序的機器代碼):
(gdb) x/9xb 0x401000
0x401000: 0xb8 0x04 0x00 0x00 0x00 0x83 0xc0 0x05
0x401008: 0xc3
(gdb) run
Starting program: /media/sf_Sandbox/math1.exe
Program received signal SIGSEGV, Segmentation fault.
0x00401002 in ??()
的內存設計缺陷後,在同一地址傾銷,內存有完全改變了,並且,從寄存器轉儲,它不會出現在以往執行的第一個指令:
(gdb) x/9xb 0x401000
0x401000: 0x4d 0x5a 0x80 0x00 0x01 0x00 0x00 0x00
0x401008: 0x04
(gdb) info all-registers
eax 0x0 0
ecx 0x81394e8 135501032
edx 0x64656d2f 1684368687
ebx 0x8139548 135501128
esp 0xbfffe5a0 0xbfffe5a0
ebp 0xffffffff 0xffffffff
esi 0x81394e8 135501032
edi 0x2f7ff4 3112948
eip 0x401002 0x401002
eflags 0x210296 [ PF AF SF IF RF ID ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x0 0
...more registers...
我想知道什麼可以讓這樣的事情發生,我可能能夠做到要解決這個問題。我懷疑我用來設置堆棧框架的代碼可能有點...關閉,但我不確定如何判斷這是什麼原因造成的。我知道這是一個非常具體的問題,但我希望有人能給我一些建議。
mmap:ed內存是否獲得執行權限? – 2012-08-16 16:37:25
@JensBjörnhager它被映射到保護'PROT_READ | PROT_EXEC'和標誌'MAP_PRIVATE | MAP_FIXED | MAP_DENYWRITE'。據我所知,這與ELF加載程序的做法是一樣的。 – nosuchthingasstars 2012-08-16 16:52:48
'4d 5a ...'看起來像一個MS-DOS標題。你確定你沒有意外地映射過嗎? – atomicinf 2012-08-16 17:26:36