Nedávno jsem měl v práci úkol pochopit binární linuxový program. Program však byl v binární podobě.
Použil jsem příkazy file
, řetězce
a objdump
abyste měli malou představu o tom, co dělá a jaké funkce volá.
Zdá se, že binární soubor je zkompilován s informacemi pro ladění. Co dalšího se o tom mohu dozvědět?
Přijatá odpověď:
Včetně příkazů, které jste již použili, se pokusím co nejlépe popsat, co lze udělat pro provedení některých forenzních operací ve spustitelném souboru.
Skromné řetězce
Příkaz může být užitečný pro vizualizaci textových chybových zpráv, které naznačují binární funkce. Je to také jednoduchý způsob detekce zabalených binárních souborů jako v příkladu (časté u binárních souborů malwaru):
$strings exe_fileUPX!...PROT_EXEC|PROT_WRITE se nezdařilo.$Info:Tento soubor je zabalen se spustitelným baličem UPX http://upx.sf.net $$Id:UPX 3.91 Copyright (C) 1996 -2013 tým UPX. Všechna práva vyhrazena. $...UPX!
strings – vytiskne řetězce tisknutelných znaků v souborech.
Pro každý daný soubor GNU strings vytiskne sekvence tisknutelných znaků
, které jsou dlouhé alespoň 4 znaky (nebo číslo uvedené u
možností níže) a za nimi následuje netisknutelný znak.
soubor
umožňuje zobrazit vlastnosti spustitelného souboru, konkrétně:
- architektura, na kterou se zaměřuje;
- OS;
- pokud je dynamicky nebo staticky propojen;
- zda je kompilován s informacemi o ladění či nikoli.
V tomto příkladu „not stripped“ označuje, že byl zkompilován včetně informací o ladění.
$ soubor exe_fileexe_file:ELF 64bitový LSB spustitelný soubor, x86-64, verze 1 (SYSV), dynamicky propojený, interpret /lib64/ld-linux-x86-64.so.2, pro GNU/Linux 2.6.18, BuildID[sha1]=6f4c5f003e19c7a4bbacb30af3e84a41c88fc0d9, neodstraněno
soubor
testuje každý argument ve snaze ho klasifikovat. Existují tři
sady testů, prováděné v tomto pořadí:testy souborového systému, magické testy,
a jazykové testy. První úspěšný test způsobí vytištění typu souboru
.
objdump
vytvoří výpis pro rozebrání spustitelného souboru:
$ objdump -d exe_filels:formát souboru Mach-O 64-bit x86-64Demontáž sekce __TEXT,__text:__text:100000f20:55 pushq %rbp100000f21:48 89 e5, mov0rbp4 %rsp C7 68 ADDQ 104, %RDI100000F28:48 83 C6 68 ADDQ 104, %RSI100000F2C:5D POPQ %RBP100000F2D:E9 58 36 00 00 JMP 13912100000F32:55 PRAZPEDNOST leaq 104(%rsi), %rax100000f3a:48 8d 77 68 leaq 104(%rdi), %rsi...............
objdump
také umožňuje znát kompilátor použitý ke kompilaci binárního spustitelného souboru:
$ objdump -s --section .comment exe_fileexe_file:file format elf64-x86-64Contents of section .comment:0000 4743433a 2028474e 55292034 2e342e37 GCC:(GNU) 4.4.7 0010 20323031 32303331 33202852 65642048 20120313 (Red H 0020 61742034 2e342e37 2d313129 00 v 4.4.7-11).
objdump
také uvádí externí funkce dynamicky propojené za běhu:
$ objdump -T exe_file
true:formát souboru elf64-x86-64dynamický symbol Tabulka:00000000000000 df *und *0000000000000000 glibc_2.2.5 __uflow0000000000000000 df *und *und *und *und *und *und *und *und *und *und *und *und *und *und *und *und *und *und *und *und *und *und * 0000000000000000 GLIBC_2.2.5 abort0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __errno_location0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strncmp0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 _exit0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __fpending0000000000000000 DF * Und* 0000000000000000 glibc_2.2.5 TextMorain0000000000000000 df* und* 00000000000000 glibc_2.2.5 fclose0000000000000000 df* und* 00000000000000 glibc_2.2.5 BindTextdomain 00000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __ctype_get_mb_cur_max0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strlen0000000000000000 DF *UND* 0000000000000000 GLIBC_2.4 __stack_chk_fail0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 mbrtowc0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strrchr0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 lseek0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 memset0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fscanf0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 close0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 memcmp0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fputs_unlocked0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 000000000000000000000000000000000000000000000000000000000000000000000000 00000000000 w D *UND* 0000000000000000 __gmon_start__0000000000000000 DF *UND* 0000000000000000 GLIBC_2.14 memcpy0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fileno0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 malloc0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fflush0000000000000000 DF *UND* 0000000000000000 GLIBC_2 .2.5 nl_langinfo0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 ungetc0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __freading0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 realloc0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fdopen0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 setlocale0000000000000000 DF * Und * 0000000000000000 glibc_2.3.4 __printf_chk00000000000000 df * und * 00000000000000 glibc_2.2.5 error0000000000000000 df * und * 00000000000000 GLIBC_2.2.5 Open0000000000000000 DF * und * und * und * und * und * und. * 0000000000000000 GLIBC_2.2.5 fseeko0000000000000000 w D *UND* 0000000000000000 _Jv_RegisterClasses0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_atexit0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 exit0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fwrite0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3.4 __fprintf_chk0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 mbsinit0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 iswprint0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3 __ctype_b_loc0000000000207228 g DO .bss 0000000000000008 GLIBC_2. 2.5 stdout0000000000207220 g DO .bss 0000000000000008 GLIBC_2.2.5 __progname0000000000207230 w DO .bss 0000000080000 program_20 GLIBC_20 _NAME0000000000207230 G DO .BSS 00000000000008 GLIBC_2.5 __POGNAME_FULL0000000020720 W DO .BSS 00000000000008 GLIBC_2.2.5 PROGRAM_INVOCACE_SHORT_NAME0000000000207240 G DO
objdump
zobrazuje informace o jednom nebo více objektových souborech. Možnosti
určují, jaké konkrétní informace se mají zobrazit. Tyto
informace jsou většinou užitečné pro programátory, kteří pracují na
kompilačních nástrojích, na rozdíl od programátorů, kteří jen chtějí, aby jejich
program zkompiloval a fungoval.
Binární soubor můžete spustit ve virtuálním počítači, který byl vytvořen a poté zahozen pouze za účelem spuštění binárního souboru. Použijte strace
, ltrace
, gdb
a sysdig
abyste se dozvěděli více o tom, co dělá binární soubor na úrovni systémových volání za běhu.
$strace exe_fileopen("/opt/sms/AU/mo/tmp.RqBcjY", O_RDWR|O_CREAT|O_EXCL, 0600) =3open("/opt/sms/AU/mo/tmp.PhHkOr" , O_RDWR|O_CREAT|O_EXCL, 0600) =4open("/opt/sms/AU/mo/tmp.q4MtjV", O_RDWR|O_CREAT|O_EXCL, 0600) =5
strace
spustí zadaný příkaz, dokud se neskončí. Zachycuje a
zaznamenává systémová volání, která jsou volána procesem, a signály
, které proces přijímá. Název každého systémového volání, jeho
argumenty a jeho návratová hodnota se vytisknou při standardní chybě nebo do
souboru zadaného s volbou -o.
$ltrace exe_file_libc_start_main(0x400624, 1, 0x7ffcb7b6d7c8, 0x400710 čas(0) =1508018406 srand(0x59e288e606,7x7ffdb, 0x59e288e6, 760x77 /opt/sms/AU/mo'", "mkdir -p -- '%s'", "/opt/sms/AU/mo") =28 system("mkdir -p -- '/opt/sms/ AU/mo'" <žádný návrat ...> --- SIGCHLD (Dítě ukončeno) --- <... systém obnoven> ) =0 rand(2, 0x7ffcb7b6d480, 0, 0x7f9d6d4622b0) =0x2d8ddbe1 sprintf("/opt /sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo") =29 mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1) =3 sprintf(3) opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo") =29 mkstemp (0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1) =4 +++ ukončeno (stav 0) +++
ltrace
je program, který jednoduše spouští zadaný příkaz, dokud se
neskončí. Zachycuje a zaznamenává volání dynamických knihoven, které
volá prováděný proces, a signály, které
tento proces přijímá. Může také zachytit a vytisknout systémová volání
prováděná programem.
Lze jej také ladit krok za krokem pomocí gdb
.
Účelem debuggeru, jako je GDB, je umožnit vám vidět, co se
děje „uvnitř“ jiného programu, když se spouští.
Chcete-li sledovat/vytvářet výpisy z velké části jeho systémové aktivity, na které běží, použijte sysdig jako v:
#sudo sysdig proc.name=exe_file……………….11569 19:05:40.938743330 1 exe_file (35690)> getpid 11570 19:05:40.93874 get4605 1:5571019 (31) exe_file 05:40.938749018 1 soubor exe (35690)> otevřít 11572 19:05:40.938801508 1 soubor exe (35690) /opt/sms/AUhms/mo/trlsM. AU/mo/tmp.XXXXMhVlrl flags=39(O_EXCL|O_CREAT|O_RDWR) mode=0 11573 19:05:40.938811276 1 exe_file (35690)> getpid 11574 1015598319:4 (015159311fil) :40.938813171 1 exe_file (35690)> otevřít 11576 19:05:40.938826313 1 exe_soubor (35690) /opt/sms/AU/mo/tmp.tmp.5tsopts /mo/tmp.5tlBSs flags=39(O_EXCL|O_CREAT|O_RDWR) mode=0 11577 19:05:40.938848592 1 exe_soubor (35690)> getpid 11578 19:05:49956931file 19:05:43956931file 15191919 exe:190 40,938849728 1 soubor exe (35690)> otevřít 11580 19:05:40,938860629 1 soubor exe (35690) /opt/sms/AU/mo/tmp.CJWQs/jméno/CJWQs mo/tmp.CJWQjA příznaky=39(O_EXCL|O_CREAT|O_RDWR) režim=0
sysdig
je nástroj pro řešení problémů se systémem, analýzu a průzkum. Lze jej použít k zachycení, filtrování a dekódování systémových volání
a dalších událostí operačního systému.
sysdig lze použít ke kontrole živých systémů nebo ke generování trasovacích
souborů, které lze analyzovat pozdější fáze.
sysdig obsahuje výkonný filtrovací jazyk, má přizpůsobitelný výstup a lze jej rozšířit pomocí skriptů Lua, nazývaných sekáče.
Ve zbývající části této odpovědi se budeme znovu zabývat statickou analýzou samotného binárního souboru.
Související:Jaké je čtení souboru conf mezi přihlašovacím a nepřihlašovacím shellem?
ldd exe_file
uvádí knihovny, které používá;
$ ldd exe_file linux-vdso.so.1 (0x00007ffdf83bd000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f14d9b32007f14d9b32007f14d9b32000) x86-64.so.2 (0x000055ededaea000)
ldd
vytiskne sdílené objekty (sdílené knihovny) požadované každým
programem nebo sdíleným objektem zadaným na příkazovém řádku.
velikost -A exe_soubor
$ size -A exe_file exe_file :velikost sekce addr .interp 28 4194816 .note.ABI-tag 32 4194844 .note.gnu.build-id 36 4194876 .gnu.hash 24129419464 90 4195160 .gnu.Version 18 4195250 .gnu.version_r 32 4195272 .rela.dyn 24 4195304 .Rela.plt 168 4195328.iniT 24 4196. .eh_frame 124 4196416 .ctors 16 6293696 .dtors 16 6293712 .jcr 8 6293728 .dynamic 400 6293736 .got 8 6294126 data 29.926 .got.plt26 804 .got. 4232 .comment 45 0 Celkem 2306 $ velikost -d ls textová data bss dec hex název souboru 122678 4664 4552 131894 20336 ls
velikost
GNU obslužný program uvádí velikosti oddílů – a celkovou
velikost – pro každý objekt nebo archivní soubory objfile ve svém seznamu
argumentů. Ve výchozím nastavení je pro každý objektový soubor
nebo každý modul v archivu generován jeden řádek výstupu.
readelf -x .rodata exe_soubor
uvádí statické řetězce
$ readelf -x .rodata exe_file Hexadecimální výpis sekce '.rodata':0x004007e8 01000200 00000000 00000000 00000000 ................ 0x004007f8 262922000 0x004007f8 26d72200 p -- '%s' 0x00400808 0025732f 746d702e 58585858 58585858 .%s/tmp.XXXXXXXX 0x00400818 585800 XX.
readelf -h exe_soubor
získá informace hlavičky ELF
$ readelf -h exe_file Záhlaví ELF:Magic:7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Třída:ELF64 Data:doplněk 2, little endian Verze:1 (aktuální) OS/ ABI:UNIX - System V Verze ABI:0 Typ:EXEC (Spustitelný soubor) Stroj:Advanced Micro Devices X86-64 Verze:0x1 Adresa vstupního bodu:0x400540 Začátek záhlaví programu:64 (bajtů do souboru) Začátek záhlaví sekcí:3072 (bajtů do souboru) Příznaky:0x0 Velikost tohoto záhlaví:64 (bajtů) Velikost záhlaví programu:56 (bajtů) Počet záhlaví programu:8 Velikost záhlaví sekcí:64 (bajtů) Počet záhlaví sekcí:30 Řetězec záhlaví sekcí tab index souboru:27
readelf -s exe_soubor
zobrazuje symboly
$ readelf -s exe_file Tabulka symbolů '.dynsym' obsahuje 9 položek:Číslo:Hodnota Velikost Typ Vazba Vis Ndx Název 0:0000000000000000 0 NOTYPE LOKÁLNÍ VÝCHOZÍ UND 1:000000000000000000 0 000000000000000000000000000000000000000000 0 FUNC GLOBAL DEFAULT UND [chráněno e-mailem]_2.2.5 (2) 3:0000000000000000 0 FUNC GLOBAL DEFAULT UND [chráněno e-mailem]_2.2.5 (2) 4:0000000000000000000000000000000000000000000000000000000000000000000000 ) 5:0000000000000000 0 FUNC GLOBAL DEFAULT UND [chráněno e-mailem]_2.2.5 (2) 6:0000000000000000 0 FUNC GLOBAL VÝCHOZÍ UND:0 FUNC GLOBAL DEFAULT UND (0 0.02 e-mail chráněno]_22.02.02 .2.5 (2) 8:0000000000000000 0 FUNC GLOBAL DEFAULT UND [chráněno e-mailem]_2.2.5 (2) Tabulka symbolů '.symtab' obsahuje 69 položek:Počet:Hodnota Velikost Typ Vazba Vis Ndx Na ME 0:00000000000000 0 Notpe Local Default UND 1:0000000000400200 0 Část Local Default 1 2:000000000040021C 0 Část Local Default 2 3:0000000040023C 0 Část Lokální výchozí výchozí hodnota 4 5:0. Část 4 5 50 0. Část 4 50 0. Část 4 5 5:Část 4 5 5:§00000000000000 5 4 5:0000000000000000 5:Část 4:00000000 5::0000000000400358 0 Sekce Local Default 6 7:00000000004003B2 0 Část Local Default 7 8:00000000004003C8 0 Část místní výchozí hodnota 8 9:00000000004003000000400400 0. Část 10 10. 10. Část 10 10 11:0000 0. Část 10 11:10 11:0000 0 0 Sekce Local Default 12 13:0000000000400540 0 Local Default 13 14:000000004007d8 0 Local Default 14 15:000000004007E8 0 SEKCE 15 16:000000000040 081C 0 Sekce Local Default 16 17:0000000000400840 0 Část Local Default 17 18:00000000006008C0 0 SEKCE Místní výchozí 18 19:00000000006008D0 0 SEKCE Místní výdaje 19 20. Část 10. Část 22200000 2220800000 2208000000 220800000 220800000 220800000 220800000 22080000 22080000 22080000 22080000 22080000 22080000 22.2080000 220800000 220800000 2 22080000 220800000 2 22080000 2 22080000 2 22080000000000 2 2208000000 2 2208000000 2 2208000000 22080000000022000 Sekce Local Default 22 23:0000000000600A80 0 Část Local Default 23 24:0000000000600AD0 0 Sekce Local Default 24 25:0000000000600AD8 0 SEKCE Místní výchozí hodnota 25 26:00000000000000 0 SEKCE ROCAL PRO VÝSTAVA LOCAL DEFAULT ABS crtstuff.c 29:000000000006008c0 0 OBJECT LOCAL DEFAULT 18 __CTOR_LIST__ 30:00000000006008d0 0 OBJEKT MÍSTNÍ DEFAULT_00300000 OBJEKT 003001000 OBJEKT 0030019 003 OBJEKT LOD0009 __CTOR_LIST__ 20 __JCR_LIST__ 32:0000000000400590 0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux 33:0000000000600ad8 1 OBJECT LOCAL DEFAULT 25 completed.6349 34:0000000000600ae0 8 OBJECT LOCAL DEFAULT 25 dtor_idx.6351 35:0000000000400600 0 FUNC LOCAL DEFAULT 13 frame_dummy 36:0000000000000000 0 FILE LOCAL DEFAULT ABS crtStuff.c 37:00000000006008c8 0 Objekt Local Default 18 __ctor_end__ 38:00000000004008b8 0 Objekt Local Default 17 __frame_end__ 39:00000000006008E0 0 VOLKONTION 00 00 ° C. 42:0000000000600a80 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_ 43:00000000006008bc 0 NOTYPE LOCAL DEFAULT 18 __init_array_end 18 __init_array_end 0080000000000000000004000000000000800000 tart 45:00000000006008e8 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC 46:0000000000600ad0 0 NOTYPE WEAK DEFAULT 24 data_start 47:0000000000400700 2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini 48:0000000000400540 0 FUNC GLOBAL DEFAULT 13 _start 49:0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 50:0000000000000000 0 Notpe slabá výchozí und _jv_registerClasses 51:00000000004007d8 0 func globální výchozí 14 _fini 52:0000000000000000 0 func globální výchozí und [e -mail chráněn] @glibc_ 53:00000000000000 0 func 0 func 0 func [e -mail chráněno]@glibc_2.2.2.2.5 54:Výchozí 15 _io_stdin_used 55:0000000000600ad0 0 notpe globální výchozí 24 __data_start 56:00000000000000 0 func globální výchozí und [e -mail chráněn]@glibc_2.2.5 57:000000004007f0 0 58:00000000006008D8 0 Objekt Global Skrytý 19 __dtor_end__ 59:0000000000400710 137 Func Global Default 13 __libc_CSU_ITIT 60:000000000000:00@Func00 00@Global00 und. Und [chráněno e -mailem]@glibc_2.2.5 63:0000000000600ae8 0 notpe globální výchozí abs _end 64:0000000000000000 0 func globální výchozí und [e -mail chráněn]@glibc_2.2.5 65:0000000000600ad4 0 notTyy Abs _edata 66:000000000000 0 UND [chráněný e-mailem]@GLIBC_2.2.5 67:0000000000400624 207 FUNC GLOBAL DEFAULT 13 hlavní 68:00000000004004a8 0 FUNC GLOBAL DEFAULT 11 _init
readelf
zobrazuje informace o jednom nebo více souborech objektu
formátu ELF. Možnosti řídí, jaké konkrétní informace se mají zobrazit.
elffile… jsou soubory objektů, které mají být prozkoumány. Jsou podporovány 32bitové a 64bitové soubory ELF
, stejně jako archivy obsahující soubory ELF.
nm exe_file
vypíše symboly z tabulky objektů:
$ nm exe_file 0000000000600ad4 A __bss_start 000000000040056c t call_gmon_start 0000000000600ad8 b completed.6349 00000000006008c8 d __CTOR_END__ 00000000006008c0 d __CTOR_LIST__ 0000000000600ad0 D __data_start 0000000000600ad0 W data_start 00000000004007a0 t __do_global_ctors_aux 0000000000400590 t __do_global_dtors_aux 00000000004007f0 R __dso_handle 00000000006008d8 D __DTOR_END__ 0000000000600ae0 b dtor_idx.6351 00000000006008d0 d __DTOR_LIST__ 00000000006008e8 d _DYNAMIC 0000000000600ad4 A _edata 0000000000600ae8 A _end 00000000004007d8 T _fini 0000000000400600 t frame_dummy 00000000004008b8 r __FRAME_END__ 0000000000600a80 d _GLOBAL_OFFSET_TABLE_ w __gmon_start__ 00000000004004a8 T _init 00000000006008bc d __init_array_end 00000000006008bc d __init_array_start 00000000004007e8 R _IO_stdin_used 00000000006008e0 d __JCR_END__ 00000000006008e0 d __JCR_LIST__ w _Jv_RegisterClasses 0000000000400700 T __libc_csu _fini 0000000000400710 T __libc_csu_init U [chráněno e-mailem]@GLIBC_2.2.5 0000000000400624 T hlavní U [chráněno e-mailem]@GLIBC_2.2.5 U [chráněno e-mailem2.2.5 U [e-mailem chráněno2.GLIBC]2.GLI .2.5 0000000000400540 T _start U [chráněno e-mailem]@GLIBC_2.2.5 U [chráněno e-mailem]@GLIBC_2.2.5
nm
vypíše symboly z objektových souborů objfile…. Pokud nejsou jako argumenty uvedeny žádné objektové soubory
, předpokládá nm soubor a.out.
Kromě rozebrání binárního kódu pomocí objdump
, lze také použít dekompilátor.
Související:Linux – Jak mohu přenosně rozdělit velké záložní soubory na více disků?
Pro dekompilaci jsem nedávno provedl technickou výzvu, kde jsem potřeboval dekompilovat dvě malé 64bitové linuxové binární soubory.
Zkusil jsem použít Boomerang a Snowmana. Projekt Boomerang se zdá opuštěný a omezení obou z nich na mě neudělalo dojem. Několik dalších alternativ, ať už open source/freeware/staré, včetně té nedávno vydané Avastem, dekompilovalo pouze 32bitové binární soubory.
Nakonec jsem zkusil demo Hoppera v MacOS (má také verzi pro Linux).
Hopper Disassembler, nástroj zpětného inženýrství, který vám umožní
rozebírat, dekompilovat a ladit vaše aplikace.
Hopper rozebírá a dekompiluje buď 32 nebo 64bitové binární soubory pro OS/X, Linux a Windows. Je-li licencován, je schopen se vypořádat s velkými binárními soubory.
Vytváří také vývojové grafy funkcí/programové struktury a proměnných.
Je také aktivně udržován a aktualizován. Nicméně je to komerční.
Tolik jsem si užíval jeho používání a výsledný výstup, který si zakoupil licenci. Licence je mnohem dostupnější než hexadecimální paprsky.
V komentářích k této odpovědi @d33tah a @Josh také zmiňují jako open source alternativy radare2 plus odpovídající grafické rozhraní Cutter, které je podobné Hopperu v Linuxu, za to nemůže osobně ručit, protože je nepoužívám.
Protože byl cílový binární soubor zkompilován s informacemi o ladění, můžete získat zpět původní název funkcí a proměnných.
Ještě pozoruhodnější je, že nikdy nedostanete zpět komentáře ve zdrojovém kódu, protože nejsou žádným způsobem zkompilovány do binárních spustitelných souborů.
Zlepšení kvality výstupního zdroje a porozumění binárnímu systému bude vždy vyžadovat určitý čas a detektivní práci. Dekompilátory dělají jen tolik práce.
Příklad výstupu zásobníku bez informací o ladění:
int EntryPoint(int arg0, int arg1, int arg2) { rdx =arg2; rbx =arg1; r12 =arg0; if (r12 <=0x1) goto loc_100000bdf;loc_10000093c:r15 =*(rbx + 0x8); if (strcmp(r15, "-l") ==0x0) goto loc_1000009c2;loc_100000953:if (strcmp(r15, "-s") ==0x0) goto loc_100000a45;
Grafické rozhraní Hopperu je také velmi dobře použitelné (na tomto obrázku je současně rozšířeno několik funkcí):
viz také související otázka Proč jsou pravdivé a nepravdivé tak velké?
Ssh – spouštět vzdálené příkazy, zcela se odpojit od připojení Ssh?
Je terminál Gnome typem prostředí bez přihlášení?
Linux