Упаковщики исполняемых файлов в LINUX-BSD

       

расшифровка файла непосредственно в IDA Pro


Тот факт, что функция _dl_map_object_deps()

вызывается из стартового кода, дает в наши руки универсальный способ распаковки elf-файлов, упакованных практически любым упаковщиком. Если только упаковщик не сопротивляется отладчику, достаточно всего лишь установить точку останова на _dl_map_object_deps()

и... дождаться когда она сработает. Тут же в стеке по адресу [ESP+08h] будет адрес возврата из CALL __libc_start_main, а по адресу [ESP+0Ch] указатель непосредственно на саму main. Если, конечно, нам повезет… Проблемы начинаются с того, что gdb с большой неохотой устанавливает точки останова на shared-функции и потому точка останова обязательно должна быть аппаратной, причем срабатывать она может несколько раз. Левые срабатывая распознаются легко. Если по [ESP+08h] и [ESP+0Ch] лежит совсем не то, что ожидалось (а это легко определить по диапазону адресов), пропускаем текущее срабатывание точки останова и продолжаем выполнение программы командой 'c'.

Примерный сеанс работы с отладчиком может выглядеть так:

root@5[elf_crypt]# gdb elfcrypt-demo            ; загружаем программу в отладчик

(gdb) hbreak *0x4000BBD0                 ; ставим

бряк на _dl_map_object_deps

Hardware assisted breakpoint 1 at 0x4000bbd0

(gdb) r                                         ; запускаем программу

Breakpoint 1, 0x4000bbd0 in _dl_map_object_deps () from /lib/ld-linux.so.2

; первое всплытие установленной точки останова

; сейчас будем проверять - "наше" ли оно или нет

(gdb) x $esp+8                                  ; смотрим стек



0xbffffa6c:     0x40100498               ; адрес указывает на libc.so.6

(gdb) c                                         ; это "левое" всплытие, идем дальше

Continuing.

Breakpoint 1, 0x4000bbd0 in _dl_map_object_deps () from /lib/ld-linux.so.2

; второе всплытие установленной точки останова

; проверяем - "наше ли оно или нет

(gdb) x $esp+8                                  ; должен быть ret


из call main

0xbffffafc:     0x080482e1               ; судя по адресу, это возможно так и есть

(gdb) x $esp+0xC                         ; должен быть указатель на main

0xbffffb00:     0x08048390               ; судя по адресу это так и есть

(gdb) disassemble

0x80482e1              ; проверяем наше предположение

Dump of assembler code for function _start:     ; дизассемблер

показывает типичный

0x080482c0 <_start+0>:  xor %ebp,%ebp     ; стартовый код, значит, приложение

0x080482c2 <_start+2>:  pop %esi          ; уже распаковано!

0x080482c3 <_start+3>:  mov %esp,%ecx

0x080482c5 <_start+5>:  and $0xfffffff0,%esp

0x080482c8 <_start+8>:  push      %eax

0x080482c9 <_start+9>:  push      %esp

0x080482ca <_start+10>: push      %edx

0x080482cb <_start+11>: push      $0x8048410

0x080482d0 <_start+16>: push      $0x80483b0

0x080482d5 <_start+21>: push      %ecx

0x080482d6 <_start+22>: push      %esi

0x080482d7 <_start+23>: push      $0x8048390

0x080482dc <_start+28>: call      0x80482b0 <_init+56>

0x080482e1 <_start+33>: hlt

End of assembler dump.


Содержание раздела