제가 가장 최근에 맡은 업무는 바이너리 Linux 프로그램을 이해하는 것이었습니다. 그러나 프로그램은 바이너리 형식입니다.
나는 그것이 무엇을 하고 있는지, 어떤 기능을 호출하는지에 대해 조금 알아보기 위해 file
, strings
, 명령을 사용했습니다 .objdump
바이너리가 디버그 정보로 컴파일된 것으로 보입니다. 또 무엇을 배울 수 있나요?
답변1
이미 사용한 명령을 포함하여 실행 파일 내에서 수행할 수 있는 몇 가지 포렌식 작업을 자세히 설명하겠습니다.
이 간단한 strings
명령은 바이너리 기능에 대한 힌트를 제공하는 텍스트 오류 메시지를 시각화하는 데 유용합니다. 이것도 간단한 방법인데압축된 바이너리 감지예제에 표시된 대로(맬웨어 바이너리에서 일반적임):
$strings exe_file
UPX!
...
PROT_EXEC|PROT_WRITE failed.
$Info: This file is packed with the UPX executable packer http://upx.sf.net $
$Id: UPX 3.91 Copyright (C) 1996-2013 the UPX Team. All Rights Reserved. $
...
UPX!
문자열 - 파일에 인쇄 가능한 문자열입니다.
주어진 각 파일에 대해 GNU 문자열은 최소 4자 길이(또는 아래 옵션에 제공된 숫자)의 인쇄 가능한 문자 시퀀스와 인쇄할 수 없는 문자를 인쇄합니다.
file
다음과 같은 실행 가능 속성을 볼 수 있습니다.
- 대상 아키텍처
- 운영 체제;
- 동적 또는 정적 링크인 경우;
- 디버그 정보로 컴파일할지 여부입니다.
이 예에서 "unstripped"는 디버깅 정보가 포함되어 컴파일되었음을 의미합니다.
$ file exe_file
exe_file: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.18, BuildID[sha1]=6f4c5f003e19c7a4bbacb30af3e84a41c88fc0d9, not stripped
file
각 인수를 테스트하고 분류해 보세요. 파일 시스템 테스트, 매직 테스트, 언어 테스트의 세 가지 테스트 세트가 이 순서대로 실행됩니다. 첫 번째 테스트에 성공하면 해당 파일 형식이 인쇄됩니다.
objdump
실행 파일의 디스어셈블리 목록을 생성합니다.
$ objdump -d exe_file
ls: file format Mach-O 64-bit x86-64
Disassembly of section __TEXT,__text:
__text:
100000f20: 55 pushq %rbp
100000f21: 48 89 e5 movq %rsp, %rbp
100000f24: 48 83 c7 68 addq $104, %rdi
100000f28: 48 83 c6 68 addq $104, %rsi
100000f2c: 5d popq %rbp
100000f2d: e9 58 36 00 00 jmp 13912
100000f32: 55 pushq %rbp
100000f33: 48 89 e5 movq %rsp, %rbp
100000f36: 48 8d 46 68 leaq 104(%rsi), %rax
100000f3a: 48 8d 77 68 leaq 104(%rdi), %rsi
...............
objdump
또한 바이너리 실행 파일을 컴파일하는 데 사용되는 컴파일러에 대해서도 알아보세요.
$ objdump -s --section .comment exe_file
exe_file: file format elf64-x86-64
Contents 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 at 4.4.7-11).
objdump
런타임 시 동적으로 연결되는 외부 함수도 나열됩니다.
$ objdump -T exe_file
true: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __uflow
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 getenv
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 free
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 abort
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __errno_location
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strncmp
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 _exit
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __fpending
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 textdomain
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fclose
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 bindtextdomain
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 dcgettext
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __ctype_get_mb_cur_max
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strlen
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.4 __stack_chk_fail
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 mbrtowc
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strrchr
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 lseek
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 memset
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fscanf
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 close
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 memcmp
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fputs_unlocked
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 calloc
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 strcmp
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.14 memcpy
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fileno
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 malloc
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fflush
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 nl_langinfo
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 ungetc
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __freading
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 realloc
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fdopen
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 setlocale
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3.4 __printf_chk
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 error
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 open
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fseeko
0000000000000000 w D *UND* 0000000000000000 _Jv_RegisterClasses
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_atexit
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 exit
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 fwrite
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3.4 __fprintf_chk
0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 mbsinit
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 iswprint
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.3 __ctype_b_loc
0000000000207228 g DO .bss 0000000000000008 GLIBC_2.2.5 stdout
0000000000207220 g DO .bss 0000000000000008 GLIBC_2.2.5 __progname
0000000000207230 w DO .bss 0000000000000008 GLIBC_2.2.5 program_invocation_name
0000000000207230 g DO .bss 0000000000000008 GLIBC_2.2.5 __progname_full
0000000000207220 w DO .bss 0000000000000008 GLIBC_2.2.5 program_invocation_short_name
0000000000207240 g DO .bss 0000000000000008 GLIBC_2.2.5 stderr
objdump
하나 이상의 대상 파일에 대한 정보를 표시합니다. 이러한 옵션은 표시되는 특정 정보를 제어합니다. 이 정보는 프로그램을 컴파일하고 실행하기만 원하는 프로그래머보다는 컴파일 도구를 사용하는 프로그래머에게 가장 유용합니다.
바이너리 실행 목적으로만 생성된 후 삭제되는 가상 머신에서 바이너리를 실행할 수 있습니다. 시스템 호출 수준에서 런타임에 바이너리가 수행하는 작업에 대해 자세히 알아보려면 strace
, ltrace
및 gdb
를 사용하세요 .sysdig
$strace exe_file
open("/opt/sms/AU/mo/tmp.RqBcjY", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
open("/opt/sms/AU/mo/tmp.PhHkOr", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
open("/opt/sms/AU/mo/tmp.q4MtjV", O_RDWR|O_CREAT|O_EXCL, 0600) = 5
strace
종료할 때까지 지정된 명령을 실행합니다. 프로세스에서 호출한 시스템 호출과 프로세스에서 수신한 신호를 가로채서 기록합니다. 각 시스템 호출의 이름, 해당 인수 및 반환 값은 표준 오류 또는 -o 옵션으로 지정된 파일에 인쇄됩니다.
$ltrace exe_file
_libc_start_main(0x400624, 1, 0x7ffcb7b6d7c8, 0x400710 <unfinished ...>
time(0) = 1508018406
srand(0x59e288e6, 0x7ffcb7b6d7c8, 0x7ffcb7b6d7d8, 0) = 0
sprintf("mkdir -p -- '/opt/sms/AU/mo'", "mkdir -p -- '%s'", "/opt/sms/AU/mo") = 28
system("mkdir -p -- '/opt/sms/AU/mo'" <no return ...>
--- SIGCHLD (Child exited) ---
<... system resumed> ) = 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("/opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo") = 29
mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1) = 4
+++ exited (status 0) +++
ltrace
종료될 때까지 지정된 명령만 실행하는 프로그램입니다. 실행 프로세스에서 호출한 동적 라이브러리 호출과 프로세스에서 수신한 신호를 가로채서 기록합니다. 또한 프로그램이 실행하는 시스템 호출을 가로채서 인쇄할 수도 있습니다.
단계별 디버깅에도 사용할 수 있습니다 gdb
.
GDB와 같은 디버거의 목적은 실행되는 동안 다른 프로그램 "내부"에서 무슨 일이 일어나고 있는지 볼 수 있도록 하는 것입니다.
이를 실행하는 대부분의 시스템 활동에 대한 덤프를 추적/생성하려면 다음과 같이 sysdig를 사용하십시오.
#sudo sysdig proc.name=exe_file
……………….
11569 19:05:40.938743330 1 exe_file (35690) > getpid
11570 19:05:40.938744605 1 exe_file (35690) < getpid
11571 19:05:40.938749018 1 exe_file (35690) > open
11572 19:05:40.938801508 1 exe_file (35690) < open fd=3(<f>/opt/sms/AU/mo/tmp.MhVlrl) name=/opt/sms/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 19:05:40.938812431 1 exe_file (35690) < getpid
11575 19:05:40.938813171 1 exe_file (35690) > open
11576 19:05:40.938826313 1 exe_file (35690) < open fd=4(<f>/opt/sms/AU/mo/tmp.5tlBSs) name=/opt/sms/AU/mo/tmp.5tlBSs flags=39(O_EXCL|O_CREAT|O_RDWR) mode=0
11577 19:05:40.938848592 1 exe_file (35690) > getpid
11578 19:05:40.938849139 1 exe_file (35690) < getpid
11579 19:05:40.938849728 1 exe_file (35690) > open
11580 19:05:40.938860629 1 exe_file (35690) < open fd=5(<f>/opt/sms/AU/mo/tmp.CJWQjA) name=/opt/sms/AU/mo/tmp.CJWQjA flags=39(O_EXCL|O_CREAT|O_RDWR) mode=0
sysdig
시스템 문제 해결, 분석 및 탐색을 위한 도구입니다. 시스템 호출 및 기타 운영 체제 이벤트를 캡처, 필터링 및 디코딩하는 데 사용할 수 있습니다. sysdig는 라이브 시스템을 검사하고 이후 단계에서 분석할 수 있는 추적 파일을 생성하는 데 사용할 수 있습니다.sysdig에는 사용자 정의 가능한 출력을 갖춘 강력한 필터링 언어가 포함되어 있으며 chisel이라는 Lua 스크립트를 통해 확장 가능합니다.
이 답변의 나머지 부분에서는 바이너리 자체의 정적 분석을 다시 다루겠습니다.
ldd exe_file
사용하는 라이브러리를 나열하십시오.
$ ldd exe_file
linux-vdso.so.1 (0x00007ffdf83bd000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f14d9b32000)
/lib64/ld-linux-x86-64.so.2 (0x000055ededaea000)
ldd
각 프로그램에 필요한 공유 개체(공유 라이브러리) 또는 명령줄에 지정된 공유 개체를 인쇄합니다.
size -A exe_file
$ size -A exe_file
exe_file :
section size addr
.interp 28 4194816
.note.ABI-tag 32 4194844
.note.gnu.build-id 36 4194876
.gnu.hash 28 4194912
.dynsym 216 4194944
.dynstr 90 4195160
.gnu.version 18 4195250
.gnu.version_r 32 4195272
.rela.dyn 24 4195304
.rela.plt 168 4195328
.init 24 4195496
.plt 128 4195520
.text 664 4195648
.fini 14 4196312
.rodata 51 4196328
.eh_frame_hdr 36 4196380
.eh_frame 124 4196416
.ctors 16 6293696
.dtors 16 6293712
.jcr 8 6293728
.dynamic 400 6293736
.got 8 6294136
.got.plt 80 6294144
.data 4 6294224
.bss 16 6294232
.comment 45 0
Total 2306
$ size -d ls
text data bss dec hex filename
122678 4664 4552 131894 20336 ls
GNU
size
유틸리티는 각 객체 또는 아카이브 파일 objfile의 섹션 크기와 인수 목록의 전체 크기를 나열합니다. 기본적으로 아카이브의 각 개체 파일이나 모듈에 대해 한 줄의 출력이 생성됩니다.
readelf -x .rodata exe_file
정적 문자열 나열
$ readelf -x .rodata exe_file
Hex dump of section '.rodata':
0x004007e8 01000200 00000000 00000000 00000000 ................
0x004007f8 6d6b6469 72202d70 202d2d20 27257327 mkdir -p -- '%s'
0x00400808 0025732f 746d702e 58585858 58585858 .%s/tmp.XXXXXXXX
0x00400818 585800 XX.
readelf -h exe_file
ELF 헤더 정보 가져오기
$ readelf -h exe_file
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400540
Start of program headers: 64 (bytes into file)
Start of section headers: 3072 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 8
Size of section headers: 64 (bytes)
Number of section headers: 30
Section header string table index: 27
readelf -s exe_file
기호 표시
$ readelf -s exe_file
Symbol table '.dynsym' contains 9 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND system@GLIBC_2.2.5 (2)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sprintf@GLIBC_2.2.5 (2)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND mkstemp@GLIBC_2.2.5 (2)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND srand@GLIBC_2.2.5 (2)
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND rand@GLIBC_2.2.5 (2)
8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND time@GLIBC_2.2.5 (2)
Symbol table '.symtab' contains 69 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400200 0 SECTION LOCAL DEFAULT 1
2: 000000000040021c 0 SECTION LOCAL DEFAULT 2
3: 000000000040023c 0 SECTION LOCAL DEFAULT 3
4: 0000000000400260 0 SECTION LOCAL DEFAULT 4
5: 0000000000400280 0 SECTION LOCAL DEFAULT 5
6: 0000000000400358 0 SECTION LOCAL DEFAULT 6
7: 00000000004003b2 0 SECTION LOCAL DEFAULT 7
8: 00000000004003c8 0 SECTION LOCAL DEFAULT 8
9: 00000000004003e8 0 SECTION LOCAL DEFAULT 9
10: 0000000000400400 0 SECTION LOCAL DEFAULT 10
11: 00000000004004a8 0 SECTION LOCAL DEFAULT 11
12: 00000000004004c0 0 SECTION LOCAL DEFAULT 12
13: 0000000000400540 0 SECTION LOCAL DEFAULT 13
14: 00000000004007d8 0 SECTION LOCAL DEFAULT 14
15: 00000000004007e8 0 SECTION LOCAL DEFAULT 15
16: 000000000040081c 0 SECTION LOCAL DEFAULT 16
17: 0000000000400840 0 SECTION LOCAL DEFAULT 17
18: 00000000006008c0 0 SECTION LOCAL DEFAULT 18
19: 00000000006008d0 0 SECTION LOCAL DEFAULT 19
20: 00000000006008e0 0 SECTION LOCAL DEFAULT 20
21: 00000000006008e8 0 SECTION LOCAL DEFAULT 21
22: 0000000000600a78 0 SECTION LOCAL DEFAULT 22
23: 0000000000600a80 0 SECTION LOCAL DEFAULT 23
24: 0000000000600ad0 0 SECTION LOCAL DEFAULT 24
25: 0000000000600ad8 0 SECTION LOCAL DEFAULT 25
26: 0000000000000000 0 SECTION LOCAL DEFAULT 26
27: 000000000040056c 0 FUNC LOCAL DEFAULT 13 call_gmon_start
28: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
29: 00000000006008c0 0 OBJECT LOCAL DEFAULT 18 __CTOR_LIST__
30: 00000000006008d0 0 OBJECT LOCAL DEFAULT 19 __DTOR_LIST__
31: 00000000006008e0 0 OBJECT LOCAL DEFAULT 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 OBJECT LOCAL DEFAULT 18 __CTOR_END__
38: 00000000004008b8 0 OBJECT LOCAL DEFAULT 17 __FRAME_END__
39: 00000000006008e0 0 OBJECT LOCAL DEFAULT 20 __JCR_END__
40: 00000000004007a0 0 FUNC LOCAL DEFAULT 13 __do_global_ctors_aux
41: 0000000000000000 0 FILE LOCAL DEFAULT ABS exe_file.c
42: 0000000000600a80 0 OBJECT LOCAL DEFAULT 23 _GLOBAL_OFFSET_TABLE_
43: 00000000006008bc 0 NOTYPE LOCAL DEFAULT 18 __init_array_end
44: 00000000006008bc 0 NOTYPE LOCAL DEFAULT 18 __init_array_start
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 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
51: 00000000004007d8 0 FUNC GLOBAL DEFAULT 14 _fini
52: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
53: 0000000000000000 0 FUNC GLOBAL DEFAULT UND system@@GLIBC_2.2.5
54: 00000000004007e8 4 OBJECT GLOBAL DEFAULT 15 _IO_stdin_used
55: 0000000000600ad0 0 NOTYPE GLOBAL DEFAULT 24 __data_start
56: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sprintf@@GLIBC_2.2.5
57: 00000000004007f0 0 OBJECT GLOBAL HIDDEN 15 __dso_handle
58: 00000000006008d8 0 OBJECT GLOBAL HIDDEN 19 __DTOR_END__
59: 0000000000400710 137 FUNC GLOBAL DEFAULT 13 __libc_csu_init
60: 0000000000600ad4 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
61: 0000000000000000 0 FUNC GLOBAL DEFAULT UND mkstemp@@GLIBC_2.2.5
62: 0000000000000000 0 FUNC GLOBAL DEFAULT UND srand@@GLIBC_2.2.5
63: 0000000000600ae8 0 NOTYPE GLOBAL DEFAULT ABS _end
64: 0000000000000000 0 FUNC GLOBAL DEFAULT UND rand@@GLIBC_2.2.5
65: 0000000000600ad4 0 NOTYPE GLOBAL DEFAULT ABS _edata
66: 0000000000000000 0 FUNC GLOBAL DEFAULT UND time@@GLIBC_2.2.5
67: 0000000000400624 207 FUNC GLOBAL DEFAULT 13 main
68: 00000000004004a8 0 FUNC GLOBAL DEFAULT 11 _init
readelf
하나 이상의 ELF 형식 개체 파일에 대한 정보를 표시합니다. 이러한 옵션은 표시되는 특정 정보를 제어합니다.elffile...은 확인할 대상 파일입니다. 32비트 및 64비트 ELF 파일과 ELF 파일이 포함된 아카이브가 지원됩니다.
nm exe_file
객체 테이블의 기호를 나열합니다.
$ 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 __libc_start_main@@GLIBC_2.2.5
0000000000400624 T main
U mkstemp@@GLIBC_2.2.5
U rand@@GLIBC_2.2.5
U sprintf@@GLIBC_2.2.5
U srand@@GLIBC_2.2.5
0000000000400540 T _start
U system@@GLIBC_2.2.5
U time@@GLIBC_2.2.5
nm
객체 파일 objfile의 기호를 나열합니다.... 인수로 나열된 대상 파일이 없으면 nm은 파일이 a.out이라고 가정합니다.
디컴파일된 바이너리를 사용하는 것 외에도 objdump
디컴파일러를 사용할 수도 있습니다.
디컴파일을 위해 저는 최근 두 개의 작은 64비트 Linux 바이너리를 디컴파일해야 하는 기술적인 과제를 수행했습니다.
부메랑과 눈사람을 사용해 보았습니다. 부메랑 프로젝트는 폐기된 것 같고 둘 중 어느 쪽의 한계도 인상적이지 않습니다. Avast에서 최근 출시한 버전을 포함하여 오픈 소스/프리웨어/이전 버전 등 여러 다른 대안은 32비트 바이너리만 디컴파일할 수 있습니다.
결국 데모를 해봤습니다홉 따는 기계MacOS에서는 (Linux 버전도 있습니다).
Hopper Disassembler는 애플리케이션을 분해, 디컴파일 및 디버깅할 수 있는 리버스 엔지니어링 도구입니다.
Hopper는 OS/X, Linux 및 Windows용 32비트 또는 64비트 바이너리를 분해하고 디컴파일할 수 있습니다. 라이선스가 부여되면 대용량 바이너리 파일을 처리할 수 있습니다.
또한 프로그램 구조와 변수의 기능적 흐름도를 생성합니다.
또한 적극적으로 유지 관리 및 업데이트되고 있습니다. 그러나 그것은 상업적이다.
나는 그것을 사용하고 라이센스 구매의 최종 결과물을 정말 즐겼습니다. 장기적으로 볼 때 이 라이센스는 육각형 광선보다 훨씬 저렴합니다.
이 답변에 대한 댓글에서 @d33tah 및 @Josh도 오픈 소스 대안으로 언급되었습니다.레이더 광산 2또한 해당 그래픽 인터페이스칼Linux의 Hopper와 유사하지만 사용하지 않기 때문에 개인적으로 보증할 수는 없습니다.
또한 디버그 정보를 포함하여 대상 바이너리를 컴파일하므로 함수 및 변수의 원래 이름을 얻을 수 있습니다.
더욱 주목할만한 점은 주석이 어떤 방식으로든 바이너리 실행 파일로 컴파일되지 않기 때문에 소스 코드의 주석을 다시 가져올 수 없다는 것입니다.
출력 소스의 품질을 개선하고 바이너리에 대한 이해를 높이려면 항상 시간과 조사 작업이 필요합니다. 디컴파일러는 제한된 작업만 수행할 수 있습니다.
디버그 정보가 없는 호퍼 출력의 예:
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;
Hopper 그래픽 인터페이스는 사용하기도 매우 쉽습니다(이 그림에서는 여러 기능이 동시에 확장됩니다).
관련 질문도 참조하세요진실은 왜 그렇게 거짓인가?