簡體   English   中英

Qemu和原始二進制文件

[英]Qemu and Raw Binary File

我正在編譯並運行二進制文件(引導扇區,第1階段,第2階段)進行練習。 引導扇區是asm,第一個階段是asm運行正常。 第二階段加載到0x1000,我有一些asm跳轉到我的C代碼的開頭。 我的跳轉和調用似乎關閉(短)兩個字節。

我已經嘗試過Bochs和Qemu中的代碼(單步執行)。 所有代碼看起來都不錯。 我甚至在IDA拆解它,每個看起來都很好。 我假設可能是我缺乏代碼對齊知識。

第二階段從0x1000開始:

0x1000: cli    
0x1001: xor    eax,eax
0x1003: mov    eax,0x1f1a
0x1008: mov    esp,eax
0x100a: sti    
0x100b: jmp    0x1010

第一個跳轉到0x1010(這是反匯編的C代碼):

0x1010: push   0x16b4
0x1015: call   0x14ca   <---
0x101a: add    esp,0x4
0x101d: jmp    0x101d

上面對0x14CA的調用實際上位於0x000014c9,兩個字節短。

正如在上面的代碼中,我期望跳轉或調用在操作數地址處着陸,但它總是錯過兩個字節。

這是一個瘋狂的猜測,可能實際上是錯誤的。 它基於以下事實:在32位代碼中,您編碼的相對JMP和CALL指令是5個字節,在16位代碼中它們是3個字節。 5個字節 - 3個字節= 2個字節。 鑒於相對JMP和CALL目標是基於距下一條指令開始的距離,它可能會提示可能出錯的地方。

如果我拿這個代碼:

bits 32
org 0x1000

    cli
    xor    eax,eax
    mov    eax,0x1f1a
    mov    esp,eax
    sti
    jmp    0x1010
    push   0x16b4
    call   0x14ca
    add    esp,0x4
    jmp    0x101d

組裝它:

nasm -f bin stage2.asm -o stage2.bin

並查看32位解碼:

ndisasm -b32 -o 0x1000 stage2.bin

我明白了:

 00001000 FA cli 00001001 31C0 xor eax,eax 00001003 B81A1F0000 mov eax,0x1f1a 00001008 89C4 mov esp,eax 0000100A FB sti 0000100B E900000000 jmp dword 0x1010 00001010 68B4160000 push dword 0x16b4 00001015 E8B0040000 call dword 0x14ca 0000101A 83C404 add esp,byte +0x4 0000101D E9FBFFFFFF jmp dword 0x101d 

這看起來很正確。 但是,如果我使用16位解碼相同的代碼:

ndisasm -b16 -o 0x1000 stage2.bin

我明白了:

 00001000 FA cli 00001001 31C0 xor ax,ax 00001003 B81A1F mov ax,0x1f1a 00001006 0000 add [bx+si],al 00001008 89C4 mov sp,ax 0000100A FB sti 0000100B E90000 jmp word 0x100e 0000100E 0000 add [bx+si],al 00001010 68B416 push word 0x16b4 00001013 0000 add [bx+si],al 00001015 E8B004 call word 0x14c8 00001018 0000 add [bx+si],al 0000101A 83C404 add sp,byte +0x4 0000101D E9FBFF jmp word 0x101b 00001020 FF db 0xff 00001021 FF db 0xff 

指令解碼不正確,但JMP和CALL存在並進入錯誤的存儲位置。 這看起來非常像您所看到的觀察結果。

在沒有看到您的代碼的情況下,我希望當您開始在0x1000處執行第2階段時,您已進入32位保護模式。 如果你還沒有,那么我懷疑這是你問題的根源。 我相信32位編碼指令正在16位實模式下執行。


更新

根據評論,OP建議他們進入32位保護模式,作為進入虛幻模式的過程的一部分。 他們相信虛幻模式仍會將指令解碼為32位代碼,從而解決問題。

進入32位保護模式並返回16位實模式,即可進入虛幻模式。 虛幻模式仍然是16位實模式,但隱藏描述符緩存中的限制設置為0xffffffff(4GiB限制)。 一旦返回到16位實模式,您將能夠使用32位尋址直接尋址超過64KiB的段中的存儲器,但代碼仍然以16位實模式運行。

如果您正在為16位虛幻模式編寫代碼,則編譯器和匯編器仍需要生成16位代碼。 如果您打算編寫/生成32位代碼,則不能選擇虛幻模式,您需要輸入32位保護模式才能執行32位代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM