Làm cách nào để tháo rời mã máy x86 16-bit thô?


91

Tôi muốn tháo rời MBR (512 byte đầu tiên) của đĩa x86 có thể khởi động mà tôi có. Tôi đã sao chép MBR vào một tệp bằng cách sử dụng

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

Bất kỳ đề xuất nào về tiện ích Linux có thể tháo rời tệp mbr?

Câu trả lời:


109

Bạn có thể sử dụng objdump. Theo bài viết này , cú pháp là:

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

bạn có thể giải thích những gì các tùy chọn bạn chỉ định làm?
Hawken

11
hoặc --targetthay vì -b. -Dlà "tháo rời nội dung của tất cả các phần"; -b bfdnamehoặc --target=bfdnamesẽ buộc đọc theo định dạng mã đối tượng được chỉ định (không phải elf mà là nhị phân thô trong trường hợp của chúng tôi); -m machinesẽ chỉ định kiến ​​trúc để sử dụng (trong tệp của chúng tôi không có tiêu đề với thông tin vòm). -M optionslà các tùy chọn của trình tháo gỡ; addr16,data16được sử dụng để "xác định kích thước địa chỉ mặc định và toán hạng kích thước" (mã điều trị như i8086 một trong công cụ disasm x86 phổ quát)
osgx

29

Công cụ GNU được gọi là objdump , ví dụ:

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

Bạn cũng có thể đặt các tùy chọn khác nhau cho kiến ​​trúc và cú pháp. Ví dụ, -m i386hoặc -Mintel,x86-64. i8086là một kiến ​​trúc cũ và việc sử dụng nó cho mã hiện đại có thể mang lại kết quả không mong muốn. Bên cạnh đó, quy định cụ thể x86-64để -Mcó thể là một ý tưởng tốt hiện nay vì nhiều máy là 64-bit. Chuyển intelsang -Mthay đổi cú pháp thành kiểu Intel thay vì kiểu AT&T mặc định, mà bạn có thể muốn hoặc không.
GDP2

24

Tôi thích ndisasmcho mục đích này. Nó đi kèm với trình hợp dịch NASM, miễn phí và mã nguồn mở và được bao gồm trong kho gói của hầu hết các bản phân phối linux.


Tôi thích câu trả lời này hơn. Dễ sử dụng hơn và tôi có thể cài đặt nasm trên OS X - objdump không có ở đó và tôi không muốn xây dựng nó từ nguồn.

22
ndisasm -b16 -o7c00h -a -s7c3eh mbr

Giải thích - từ trang ndisasm

  • -b= Chỉ định chế độ 16-, 32- hoặc 64-bit. Mặc định là chế độ 16-bit.
  • -o= Chỉ định địa chỉ tải danh nghĩa cho tệp. Tùy chọn này khiến ndisasm lấy các địa chỉ mà nó liệt kê ở lề trái, và các địa chỉ đích của các bước nhảy và lệnh liên quan đến PC, ở bên phải.
  • -a = Bật chế độ đồng bộ hóa tự động (hoặc thông minh), trong đó ndisasm sẽ cố gắng đoán nơi đồng bộ hóa sẽ được thực hiện, bằng cách kiểm tra địa chỉ đích của các bước nhảy tương đối và gọi nó là sự tháo gỡ.
  • -s= Chỉ định thủ công địa chỉ đồng bộ hóa, như vậy ndisasm sẽ không xuất ra bất kỳ lệnh máy nào bao gồm các byte ở cả hai phía của địa chỉ. Do đó, lệnh bắt đầu tại địa chỉ đó sẽ được tháo rời một cách chính xác.
  • mbr = Tệp được tháo rời.

điều này làm gì trái ngược với ndisasm đơn giản? Bạn có thể giải thích sự lựa chọn
Hawken

4
Bạn có thể giải thích những tùy chọn đó có nghĩa là gì và làm gì không? Hiểu một câu trả lời tốt hơn là chỉ nhận một câu trả lời.
Xe trượt

-b specifies 16-, 32- or 64-bit mode. The default is 16-bit mode. -o is the notional load address for the file. This option causes ndisasm to get the addresses it lists down the left hand margin, and the target addresses of PC-relative jumps and calls, right. -s specifies a synchronisation address, such that ndisasm will not output any machine instruction which encompasses bytes on both sides of the address. Hence the instruction which starts at that address will be correctly disassembled.
Janus Troelsen

15

starbluehlovdal đều có các phần của câu trả lời chính tắc. Nếu bạn muốn tháo rời mã i8086 thô, bạn thường muốn cú pháp Intel, không phải cú pháp AT&T, vì vậy hãy sử dụng:

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

Nếu mã của bạn là ELF (hoặc a.out (hoặc (E) COFF)), bạn có thể sử dụng mẫu ngắn:

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

Đối với mã 32 bit hoặc 64 bit, hãy bỏ qua ,8086; tiêu đề ELF đã bao gồm thông tin này.

ndisasm, theo gợi ý của jameslin , cũng là một lựa chọn tốt, nhưng objdumpthường đi kèm với HĐH và có thể xử lý tất cả các kiến ​​trúc được hỗ trợ bởi GNU binutils (tập siêu của những kiến ​​trúc được GCC hỗ trợ) và đầu ra của nó thường có thể được đưa vào GNU as(thường có thể của ndisasm được đưa vào nasmmặc dù, tất nhiên).

Peter Cordes gợi ý rằng “Đối tượng của Agner Fog rất hay. Nó đặt nhãn trên các mục tiêu nhánh, giúp dễ dàng hơn rất nhiều để tìm ra mã hoạt động. Nó có thể tháo rời thành cú pháp NASM, YASM, MASM hoặc AT&T (GNU) ”.

Đa phương tiện Mike đã tìm hiểu về --adjust-vma; các ndisasmtương đương là -otùy chọn.

Ví dụ, để tháo rời sh4mã (tôi đã sử dụng một mã nhị phân từ Debian để kiểm tra), hãy sử dụng mã này với GNU binutils (hầu hết tất cả các trình tháo gỡ khác được giới hạn ở một nền tảng, chẳng hạn như x86 với ndisasmobjconv):

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

Các -mlà máy, và -ELcó nghĩa là Little Endian (đối với sh4ebsử dụng -EBthay vì), trong đó có liên quan cho các kiến trúc tồn tại trong cả hai endian.


2
Obconv của Agner Fog rất hay. Nó đặt nhãn trên các mục tiêu nhánh , giúp dễ dàng hơn rất nhiều để tìm ra mã hoạt động. Nó có thể tháo rời thành cú pháp NASM, YASM, MASM hoặc AT&T (GNU).
Peter Cordes

Đối với tôi, nó được xây dựng tốt ngay trên GNU / Linux. Nhưng có, nó chỉ là x86 / x86-64, không giống như GNU binutils. Tuy nhiên, nó có rất nhiều gợi ý cụ thể về x86 mà nó thêm vào dưới dạng nhận xét, chẳng hạn như khi tiền tố kích thước toán hạng có thể gây ra lỗi LCP trong bộ giải mã của CPU Intel. Bằng mọi cách, hãy đề cập đến nó trong câu trả lời của bạn. Một trong những mục đích chính của nhận xét là giúp người đăng cải thiện câu trả lời của họ, không chỉ là thứ mà người xem sau này cũng cần đọc.
Peter Cordes

1
@PeterCordes Có tốt Tôi có MirBSD như hệ điều hành chính;)
mirabilos

@PeterCordes nhưng có vẻ như nó không thể tháo rời các tệp nhị phân thô, phải không? Tôi đã phải tạo các tệp ELF tối thiểu chỉ để có thể đưa một loạt các hướng dẫn vào đó, nhưng có lẽ tôi đã bỏ lỡ một số tùy chọn?
Ruslan

1
@Ruslan: IDK, câu hỏi thú vị. Tôi thường chỉ sử dụng objdump hoặc nếu tôi muốn các nhãn nhánh gcc -O3 -masm=intel -fverbose-asm -S -o- | less, vì tôi thường cố gắng điều chỉnh mã nguồn C để biên dịch thành asm tốt.
Peter Cordes

9

Hãy thử lệnh này:

sudo dd if=/dev/sda bs=512 count=1 | ndisasm -b16 -o7c00h -
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.