Linux 바이너리가하는 일 이해


52

나는 최근에 바이너리 리눅스 프로그램을 이해하는 일을하고 있었다. 그러나 프로그램은 이진 형식이었습니다.

나는 명령을 사용 file, strings그리고 objdump그것이 무엇을하고 있었는지에 약간의 아이디어를 가지고, 그것은 호출 무슨 기능.

바이너리가 디버깅 정보로 컴파일 된 것 같습니다. 그것에 대해 무엇을 더 배울 수 있습니까?


3
이 바이너리가 무엇을하고 있는지에 대한 아이디어가 있습니까? 시스템에 해를 끼치 도록 설계된 일부 맬웨어 일 것으로 의심 됩니까? 그렇다면, 그 질문에 들어가야합니다 (가능한 해를 제한하기 위해 특별한주의가 필요하기 때문에)
Basile Starynkevitch

법의학적인 도전입니다.

1
ldd와 strace는 당신의 친구입니다
user2497

답변:


83

이미 사용한 명령을 포함하여 실행 파일에서 일부 포렌식 작업을 수행하기 위해 수행 할 수있는 작업에 대해 자세히 설명하겠습니다.

humble 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 실행 속성을 볼 수 있습니다.

  • 대상이되는 아키텍처;
  • OS;
  • 동적으로 또는 정적으로 링크 된 경우;
  • 디버깅 정보로 컴파일 된 경우.

이 예제에서 "not stripped"는 디버깅 정보가 포함되어 컴파일되었음을 나타냅니다.

$ 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하나 이상의 객체 파일에 대한 정보를 표시합니다. 옵션은 표시 할 특정 정보를 제어합니다. 이 정보는 대부분 컴파일 및 작업을 원하는 프로그래머와 달리 컴파일 도구를 사용하는 프로그래머에게 유용합니다.

바이너리 만 생성 한 후 바이너리 만 실행할 목적으로 만 VM에서 바이너리를 실행할 수 있습니다. 사용은 strace, ltrace, gdbsysdig런타임에 수준을 부르는 이진 시스템에서 수행됩니다에 대한 정보를 얻으실 수 있습니다.

$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시스템 문제 해결, 분석 및 탐색을위한 도구입니다. 시스템 호출 및 기타 OS 이벤트를 캡처, 필터링 및 디코딩하는 데 사용할 수 있습니다. sysdig는 라이브 시스템을 검사하거나 나중에 분석 할 수있는 추적 파일을 생성하는 데 사용할 수 있습니다.

sysdig는 강력한 필터링 언어를 포함하고 사용자 정의 가능한 출력을 가지며 chisels라는 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 ...은 검사 할 객체 파일입니다. ELF 파일이 포함 된 아카이브와 마찬가지로 32 비트 및 64 비트 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 바이너리를 디 컴파일해야하는 기술적 인 문제가있었습니다.

Boomerang과 Snowman을 사용하려고했습니다. 부메랑 프로젝트는 포기한 것으로 보이며 두 가지의 한계에 감명받지 못했습니다. Avast에서 릴리스 한 최근 소스를 포함하여 오픈 소스 / 프리웨어 / 오래된 몇 가지 다른 대안은 32 비트 바이너리 만 디 컴파일했습니다.

MacOS에서 Hopper 데모를 시도했습니다 (Linux 버전도 있습니다).

응용 프로그램을 분해, 디 컴파일 및 디버깅 할 수있는 리버스 엔지니어링 도구 인 Hopper Disassembler.

Hopper는 OS / X, Linux 및 Windows 용 32 비트 또는 64 비트 바이너리를 디스 어셈블하고 디 컴파일합니다. 라이센스가있을 때 큰 바이너리를 처리 할 수 ​​있습니다.

또한 함수 / 프로그램 구조 및 변수의 플로우 그래프를 작성합니다.

또한 적극적으로 유지 관리 및 업데이트되고 있습니다. 그러나 상업적입니다.

나는 그것을 사용하고 라이센스를 구입 한 결과물을 너무 많이 사용했습니다. 이 라이센스는 헥스 레이보다 훨씬 저렴합니다.

이 답변에 대한 의견에서 @ d33tah와 @Josh는 오픈 소스 대안으로 radare2 와 Linux의 Hopper와 유사한 해당 그래픽 인터페이스 Cutter를 언급 했지만 사용하지 않기 때문에 개인적으로 보증 할 수 없습니다.

또한 대상 바이너리가 디버그 정보로 컴파일되었으므로 원래 함수 및 변수 이름을 얻을 수 있습니다.

특히, 바이너리 코드로 어떤 식 으로든 컴파일되지 않았기 때문에 소스 코드의 주석을 다시 얻지 못할 것입니다.

출력 소스의 품질을 개선하고 바이너리를 이해하면 항상 시간과 탐정 작업이 필요합니다. 디 컴파일러는 많은 작업을 수행합니다.

디버그 정보가없는 호퍼 출력의 예 :

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 그래픽 인터페이스도 매우 유용합니다 (이 그림에서 여러 기능이 동시에 확장 됨).

여기에 이미지 설명을 입력하십시오

나는 또한 Hopper에 대해 대답했다 .SO- 좋은 C 디 컴파일러는 무엇입니까?

관련 질문을 참조하십시오 왜 참과 거짓이 그렇게 큰가?


1
strace -f자식 스레드 / 프로세스를 추적하는 것을 잊지 마십시오 . 이 각각의 PID에 대해 별도의 파일로 출력을 분할하는 옵션은, 아니면 그냥 할 수 /12345 있는 less검색하고 관심있는 PID로 시작하는 라인을 강조. 일이 너무 함께 뒤죽박죽하지 않는 경우 (예를 들어, 쉘 스크립트는 다른 시작 동시 스레드가 아닌 프로세스)를 사용할 수 있습니다. 그러나 그렇습니다 . 설치 방법에 만족하지 않는 이유를 알아 내려고 할 때 혼란스러운 일부 소프트웨어가 읽으려고하는 구성 / 기타 파일을 보는 것이 매우 유용합니다.
Peter Cordes

4
좋은 답변입니다! 난 그냥 radare2목록에 추가 합니다.
d33tah

2
Cutter는 radare2를 중심으로 한 GUI 래퍼입니다. Hopper와 비슷할 수도 있습니다 (무료).
Josh

2
wrt ldd : 일부 상황에서 (예 : 프로그램이 ld-linux.so 이외의 ELF 인터프리터를 지정하는 경우) 일부 버전의 ldd는 프로그램을 직접 실행하여 종속성 정보를 얻으려고 시도 할 수 있습니다 (이로 인해 프로그램의 ELF 인터프리터에 정의 된 모든 코드의 실행 및 프로그램 자체의 실행) 따라서 신뢰할 수없는 실행 파일에 ldd를 사용하면 안됩니다. 임의 코드가 실행될 수 있습니다. 신뢰할 수없는 실행 파일을 처리 할 때보다 안전한 대안은 다음과 같습니다.
Pryftan

2
$ objdump -p / path / to / 프로그램 | grep NEEDED
Pryftan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.