Нахождение функции в разборке

Я занят изучением руководства, в котором автор использует DUMPBIN для вывода списка экспортируемых файлов и OllyDbg для получения кода сборки для экспортируемой функции. Как мне найти код функций в полном дизассемблировании, учитывая, что таблицы экспорта RVA не соответствуют реальным адресам в дизассемблировании.

Ответов (3)

Решение

RVA - это перемещаемый виртуальный адрес. Чтобы найти реальный адрес в пространстве процесса, вам необходимо знать базовый адрес, по которому модуль был загружен в процесс. Добавьте этот базовый адрес в RVA, и вы получите настоящий адрес. Я не использовал ollydbg, но был бы удивлен, если бы он не предоставил базовый адрес для модулей, загруженных в процессе, к которому он был присоединен. Если по какой-то причине он не предоставляет эту информацию, вы можете получить ее с помощью процедуры procxp.exe из инструментов sysinternal.

Если вы используете radare2 , вы можете использовать -AA флаг для анализа функции в двоичном формате (возможно), а затем использовать afl команду для перечисления всех функций. Например :

% r2 -AA hello
[Cannot analyze at 0x00400420g with sym. and entry0 (aa)
[x] Analyze all flags starting with sym. and entry0 (aa)
[Cannot analyze at 0x00400420ac)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Check for objc references
[x] Check for vtables
[x] Type matching analysis for all functions (aaft)
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
[x] Finding function preludes
[x] Enable constraint types analysis for variables
-- Greetings, human.
[0x00400430]> afl
0x00400430    1 41           entry0
0x00400410    1 6            sym.imp.__libc_start_main
0x00400460    4 50   -> 41   sym.deregister_tm_clones
0x004004a0    4 58   -> 55   sym.register_tm_clones
0x004004e0    3 28           entry.fini0
0x00400500    4 38   -> 35   entry.init0
0x004005b0    1 2            sym.__libc_csu_fini
0x004005b4    1 9            sym._fini
0x00400540    4 101          sym.__libc_csu_init
0x00400526    1 21           main
0x00400400    1 6            sym.imp.puts
0x004003c8    3 26           sym._init
[0x00400430]>

Версия для Windows для radare2 -> Cutter

Довольно хорошим индикатором функции, по крайней мере, для программ, написанных на языках высокого уровня, является код, который устанавливает фрейм стека.

Если вы знаете компилятор, который использовался для генерации рассматриваемого кода, вы сможете узнать, что искать.

Пример

$ cat main.c
int main(int argc, char **argv) {
        return 1;
}
$ gcc -m32 -S main.c
$ cat main.s 
        .file     "main.c"
        .text
.globl main
        .type    main, @function
main:
        leal     4(%esp), %ecx
        andl     $-16, %esp
        pushl    -4(%ecx)
        pushl    %ebp
        movl     %esp, %ebp
        pushl    %ecx
        movl     $1, %eax
        popl     %ecx
        popl     %ebp
        leal     -4(%ecx), %esp
        ret
        .size    main, .-main
        .ident   "GCC: (Debian 4.3.3-4) 4.3.3"
        .section    .note.GNU-stack,"",@progbits

В моем примере инструкция movl% esp,% ebp является последней инструкцией этого установочного кода.

Коммерческий дизассемблер IDA Pro, для которого доступна для загрузки бесплатная версия, неплохо справляется с автоматическим поиском функций.