Jak zdemontować surowy 16-bitowy kod maszynowy x86?

91

Chciałbym zdemontować MBR (pierwsze 512 bajtów) z bootowalnego dysku x86, który mam. Skopiowałem MBR do pliku za pomocą

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

Jakieś sugestie dotyczące narzędzia Linux, które może zdemontować plik mbr?

sigjuice
źródło

Odpowiedzi:

109

Możesz użyć objdump. Zgodnie z tym artykułem składnia jest następująca:

objdump -D -b binary -mi386 -Maddr16,data16 mbr
hlovdal
źródło
czy możesz wyjaśnić, jakie działania mają określone przez Ciebie opcje?
Hawken
11
lub --targetzamiast -b. -Doznacza „rozmontowanie zawartości wszystkich sekcji”; -b bfdnamelub --target=bfdnamewymusi odczyt zgodnie z określonym formatem kodu obiektowego (w naszym przypadku nie elf, ale nieprzetworzony plik binarny); -m machineokreśli architekturę do użycia (w naszym pliku nie ma nagłówka z informacją o archiwum). -M optionssą opcjami dezasemblera; addr16,data16są używane do "określania domyślnego rozmiaru adresu i rozmiaru operandu" (traktuje kod jako i8086 w uniwersalnym silniku disasm x86)
osgx
30

Narzędzie GNU nazywa się objdump , na przykład:

objdump -D -b binary -m i8086 <file>
starblue
źródło
Możesz także ustawić różne opcje architektury i składni. Na przykład -m i386lub -Mintel,x86-64. i8086jest starą architekturą i użycie jej we współczesnym kodzie może przynieść nieoczekiwane rezultaty. Ponadto określenie x86-64na -Mmoże być obecnie dobrym pomysłem, ponieważ wiele komputerów jest 64-bitowych. Przejście inteldo -Mzmienia składnię na styl Intel zamiast domyślnego stylu AT&T, którego możesz lub nie chcesz.
PKB2,
24

Podoba mi się ndisasmw tym celu. Jest dostarczany z asemblerem NASM, który jest darmowy i open source i jest zawarty w repozytoriach pakietów większości dystrybucji Linuksa.

asveikau
źródło
Ta odpowiedź podoba mi się bardziej. Łatwiejszy w użyciu i mogłem zainstalować nasm na OS X - objdump tam nie było i nie chcę go budować ze źródeł.
23
ndisasm -b16 -o7c00h -a -s7c3eh mbr

Wyjaśnienie - ze strony podręcznika ndisasm

  • -b= Określa tryb 16-, 32- lub 64-bitowy. Domyślnie jest to tryb 16-bitowy.
  • -o= Określa hipotetyczny adres ładowania pliku. Ta opcja powoduje, że ndisasm pobiera adresy, które podaje na lewym marginesie, a adresy docelowe skoków i wywołań względem komputera, po prawej.
  • -a = Włącza tryb automatycznej (lub inteligentnej) synchronizacji, w którym ndisasm spróbuje odgadnąć, gdzie powinna zostać wykonana synchronizacja, poprzez zbadanie adresów docelowych odpowiednich skoków i wywołuje deasemblacje.
  • -s= Ręcznie określa adres synchronizacji, tak aby ndisasm nie wyprowadził żadnych instrukcji maszynowych, które obejmują bajty po obu stronach adresu. Stąd instrukcja zaczynająca się pod tym adresem zostanie poprawnie zdemontowana.
  • mbr = Plik do zdemontowania.
jameslin
źródło
co to robi w przeciwieństwie do prostego ndisasm? Czy możesz wyjaśnić opcje
Hawken,
4
Czy mógłbyś wyjaśnić, co oznaczają i co robią te opcje? Zrozumienie odpowiedzi jest lepsze niż samo uzyskanie odpowiedzi.
Sanki
-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

starblue i hlovdal mają części odpowiedzi kanonicznej. Jeśli chcesz zdemontować surowy kod i8086, zwykle potrzebujesz składni Intela, a nie składni AT&T, więc użyj:

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

Jeśli Twój kod to ELF (lub a.out (lub (E) COFF)), możesz użyć krótkiej formy:

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

W przypadku kodu 32-bitowego lub 64-bitowego pomiń ,8086; nagłówek ELF już zawiera te informacje.

ndisasm, jak sugeruje jameslin , jest również dobrym wyborem, ale objdumpzwykle jest dostarczany z systemem operacyjnym i radzi sobie ze wszystkimi architekturami obsługiwanymi przez GNU binutils (nadzbiór tych obsługiwanych przez GCC), a jego dane wyjściowe można zwykle wprowadzić do GNU as(ndisasm zazwyczaj może podawany do nasmchociaż oczywiście).

Peter Cordes sugeruje, że „ objconv Agner Fog jest bardzo fajne. Umieszcza etykiety na docelowych gałęziach, co znacznie ułatwia zrozumienie, co robi kod. Można go rozłożyć na składnię NASM, YASM, MASM lub AT&T (GNU). ”

Multimedia Mike już się dowiedział --adjust-vma; ndisasmrównoważne jest -orozwiązaniem.

Aby zdemontować, powiedzmy, sh4kod (użyłem jednego pliku binarnego z Debiana do testowania), użyj tego z GNU binutils (prawie wszystkie inne deasemblery są ograniczone do jednej platformy, takiej jak x86 z ndisasmi objconv):

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

-mJest maszyna, a -ELoznacza little endian (do sh4ebwykorzystania -EBzamiast), co jest istotne dla architektur, które istnieją w każdej bajt.

mirabilos
źródło
2
Objconv Agner Fog jest bardzo fajny. Umieszcza etykiety na docelowych gałęziach , co znacznie ułatwia zrozumienie, co robi kod. Może rozłożyć na składnię NASM, YASM, MASM lub AT&T (GNU).
Peter Cordes
Jak dla mnie, zbudował dobrze od razu po wyjęciu z pudełka w systemie GNU / Linux. Ale tak, to tylko x86 / x86-64, w przeciwieństwie do GNU binutils. Jednak ma wiele fajnych wskazówek specyficznych dla x86, które dodaje jako komentarze, na przykład gdy prefiks rozmiaru operandu może spowodować zablokowanie LCP w dekoderach procesora Intela. Jak najbardziej, wspomnij o tym w swojej odpowiedzi. Jednym z głównych celów komentarzy jest pomoc autorowi w poprawieniu odpowiedzi, a nie tylko to, co później muszą przeczytać widzowie.
Peter Cordes
1
@PeterCordes Tak dobrze, mam MirBSD jako główny system operacyjny;)
mirabilos
@PeterCordes, ale wygląda na to, że nie może zdemontować surowych plików binarnych, prawda? Musiałem utworzyć minimalne pliki ELF, aby móc wprowadzić do niego kilka instrukcji, ale może po prostu przegapiłem jakąś opcję?
Ruslan
1
@Ruslan: IDK, ciekawe pytanie. Zwykle używam po prostu objdump lub jeśli chcę etykiety gałęzi gcc -O3 -masm=intel -fverbose-asm -S -o- | less, ponieważ zwykle próbuję dostosować kod C do kompilacji do dobrego asm.
Peter Cordes
9

Wypróbuj to polecenie:

sudo dd if=/dev/sda bs=512 count=1 | ndisasm -b16 -o7c00h -
Jason
źródło