Нахождение функции в разборке
Я занят изучением руководства, в котором автор использует DUMPBIN для вывода списка экспортируемых файлов и OllyDbg для получения кода сборки для экспортируемой функции. Как мне найти код функций в полном дизассемблировании, учитывая, что таблицы экспорта RVA не соответствуют реальным адресам в дизассемблировании.
Ответов (3)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]>
Довольно хорошим индикатором функции, по крайней мере, для программ, написанных на языках высокого уровня, является код, который устанавливает фрейм стека.
Если вы знаете компилятор, который использовался для генерации рассматриваемого кода, вы сможете узнать, что искать.
Пример
$ 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, для которого доступна для загрузки бесплатная версия, неплохо справляется с автоматическим поиском функций.