2012-08-16 22 views
2

我一直在研究一個簡單的用於Linux的PE進程加載器。我想我已經掌握了基礎知識;我使用的大部分代碼來自binfmt_elf.cbinfmt_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... 

我想知道什麼可以讓這樣的事情發生,我可能能夠做到要解決這個問題。我懷疑我用來設置堆棧框架的代碼可能有點...關閉,但我不確定如何判斷這是什麼原因造成的。我知道這是一個非常具體的問題,但我希望有人能給我一些建議。

+0

mmap:ed內存是否獲得執行權限? – 2012-08-16 16:37:25

+0

@JensBjörnhager它被映射到保護'PROT_READ | PROT_EXEC'和標誌'MAP_PRIVATE | MAP_FIXED | MAP_DENYWRITE'。據我所知,這與ELF加載程序的做法是一樣的。 – nosuchthingasstars 2012-08-16 16:52:48

+2

'4d 5a ...'看起來像一個MS-DOS標題。你確定你沒有意外地映射過嗎? – atomicinf 2012-08-16 17:26:36

回答

0

錯誤是由我的錯誤頁面對齊引起的,神祕的十六進制轉儲內容實際上是所討論的PE文件的MS-DOS標題。我通過使用kernel_readcopy_to_user而不是do_mmap來修復它,以避免在非頁面對齊的部分出現故障。