2009-11-15 154 views
74

我想反彙編我有的可啓動x86磁盤的MBR(前512字節)。我抄了MBR到使用Linux的實用工具,可以拆卸文件mbr如何反彙編原始x86代碼?

dd if=/dev/my-device of=mbr bs=512 count=1 

任何建議文件?

回答

89

您可以使用objdump。據this article語法是:

objdump -D -b binary -mi386 -Maddr16,data16 mbr 
+0

你能解釋一下你指定的選項嗎? – Hawken 2012-11-17 14:18:13

+10

或'--target'而不是'-b'。 '-D'是「反彙編所有部分的內容」; '-b bfdname'或'--target = bfdname'會強制讀取指定的目標代碼格式(在我們的例子中不是精靈,而是原始二進制); '-m machine'將指定要使用的體系結構(在我們的文件中沒有包含arch info的標題)。 '-M options'是反彙編的選項; 'addr16,data16'用於「指定默認地址大小和操作數大小」(在通用x86 disasm引擎中將代碼視爲i8086) – osgx 2012-11-28 16:41:25

18

我喜歡ndisasm用於這一目的。它帶有NASM彙編程序,它是免費的,開源的,並且包含在大多數Linux發行版的軟件包倉庫中。

+0

我更喜歡這個答案。更容易使用,我可以在OS X上安裝nasm - objdump不在那裏,我不想從源代碼構建它。 – 2012-10-28 13:12:40

+0

@ H2CO3 NASM通常預裝在OS-X上... – Hawken 2012-11-17 03:42:19

26

GNU工具被稱爲objdump的,例如:

objdump -D -b binary -m i8086 <file> 
+0

您還可以爲體系結構和語法設置不同的選項。例如,'-m i386'或'-Mintel,x86-64'。 'i8086'是一種古老的架構,將其用於現代代碼可能會產生意想不到的結果。此外,現在指定'x86-64'爲'-M'可能是一個好主意,因爲許多機器都是64位的。將'intel'傳遞給'-M'會將語法更改爲Intel風格,而不是默認的AT&T風格,您可能會也可能不想要。 – GDP2 2018-03-05 03:04:50

7

須藤DD如果=/dev/sda上BS = 512計數= 1 | ndisasm -b16 -o7c00h -

16
ndisasm -b16 -o7c00h -a -s7c3eh mbr 

說明 - 從ndisasm手冊頁

  • -b =指定16,32或64位模式。默認值是16位模式。
  • -o =指定文件的名義加載地址。這個選項會導致ndisasm得到它在左邊空白處列出的地址,以及PC相對跳轉和調用的目標地址。
  • -a =啓用自動(或智能)同步模式,其中ndisasm將嘗試通過檢查相對跳轉的目標地址並調用它進行反彙編來猜測應執行同步的位置。
  • -s =手動指定一個同步地址,這樣ndisasm將不會輸出包含地址兩邊字節的任何機器指令。因此,從該地址開始的指令將被正確拆卸。
  • mbr =需要反彙編的文件。
+0

與簡單的ndisasm相比,這是做什麼用的?你能解釋一下選項嗎 – Hawken 2012-11-17 14:16:12

+4

你能解釋一下這些選項的含義嗎?理解答案比只取得答案要好。 – ArtB 2012-11-17 17:33:04

+0

'-b指定16,32或64位模式。缺省值是16位模式。「-o是文件的名義加載地址。這個選項 導致ndisasm得到它在左邊 餘量中列出的地址,以及PC相對跳轉和調用的目標地址, right。「-s指定同步地址,使得ndisasm 將不輸出任何機器指令包含地址兩側的字節 。因此,在該地址開始 的指令將被正確拆卸。' – 2013-05-06 18:49:59

8

starblue and hlovdal都有部分規範的答案。如果要拆卸的原始i8086代碼,通常希望英特爾的語法,而不是在& T語法,也因此使用:

objdump -D -Mintel,i8086 -b binary -m i386 mbr.bin 
objdump -D -Mintel,i386 -b binary -m i386 foo.bin # for 32-bit code 
objdump -D -Mintel,x86-64 -b binary -m i386 foo.bin # for 64-bit code 

如果你的代碼是ELF(或a.out的(或(E)COFF) ),則可以使用簡寫形式:

objdump -D -Mintel,i8086 a.out # disassembles the entire file 
objdump -d -Mintel,i8086 a.out # disassembles only code sections 

對於32位或64位的代碼,則省略,8086; ELF標題已包含此信息。

ndisasm,通過jameslin的建議,也是一個不錯的選擇,但objdump通常自帶操作系統,並能夠處理由GNU binutils的(那些由GCC支持的超集)支持的所有架構,其輸出通常可以喂到GNU as(當然,ndisasm's通常可以輸入到nasm中)。

Peter Cordes表明「Agner Fog's objconv是非常好的。它將標籤放在分支目標上,使得更容易弄清代碼的作用。它可以反彙編爲NASM,YASM,MASM或T(GNU)語法。「

Multimedia Mike已經發現約--adjust-vma;等效的ndisasm-o選項。

爲了拆卸,比方說,sh4代碼(I使用的一個二進制從Debian的測試),使用此具有GNU binutils的(幾乎所有其他反彙編限於一個平臺,例如x86與ndisasmobjconv):

objdump -D -b binary -m sh -EL x 

-m是機器,並-EL意味着小端(對於sh4eb使用-EB代替),這是相關的存在於任一端序架構。

+2

[Agner Fog's objconv](http://agner.org/optimize/)非常好。它將標籤放在分支*目標*上,使得更容易弄清楚代碼的作用。它可以反彙編成NASM,YASM,MASM或AT&T(GNU)語法。 – 2015-12-23 04:05:54

+0

它在GNU/Linux上爲我開箱即可使用。但是,是的,它只是x86/x86-64,不像GNU binutils。但是,它有很多很好的x86特有提示,它們會作爲註釋添加,比如操作數大小的前綴會導致英特爾CPU解碼器中的LCP停頓。通過一切手段,在你的答案中提及它。評論的主要目的之一是幫助海報改善他們的答案,而不僅僅是後來觀衆需要閱讀的內容。 – 2015-12-23 11:11:03

+1

@PeterCordes是的,我有MirBSD作爲主要操作系統;) – mirabilos 2015-12-23 11:35:23