Всем привет!
Заранее извиняюсь, если такие нубские вопросы тут не задают (если это так, то пошлите меня в верном направлении, пожалуйста:))
Давно интересуюсь реверсингом и всяким прочим низкоуровневым, но только сейчас решил всё-таки заняться этим делом (хотя были раньше попытки начать, которые в итоге провалились, каюсь )).
Сразу же огромная куча вопросов возникла, многие из которых даже не знаю как задать.
Поставил перед собой для начала такую задачу: компилирую разными компиляторами (clang, gcc, cl.exe) с разными флагами оптимизации и под разные операционные системы (FreeBSD, Linux, Windows7) один и тот же простой хеллоуворлд на С. А потом смотрю на все получившиеся варианты через IDA Pro и пытаюсь понять ВСЁ. Потом буду потихоньку код усложнять, чтобы увидеть во что реально превращаются всевозможные массивы указателей на структуры, которые содержат массивы строк :)))
В связи с чем вопросов у меня будет очень много, но начну пока с самых бросающихся в глаза.
Для начала код на C:
Вот, что я вижу в IDA, когда компилирую его Clang'ом под FreeBSD:Code:#include <stdio.h> int main(void) { printf("Hello, World!\n"); return 0; }
В комментариях в коде, собственно, четыре вопроса к вам.Code:main proc near var_8 = dword ptr -8 var_4 = dword ptr -4 push rbp mov rbp, rsp sub rsp, 10h ; 1) ДЛЯ ЧЕГО РЕЗЕРВИРУЕТСЯ 16 БАЙТ В СТЕКЕ? mov rdi, offset format ; "Hello, World!\n" mov [rbp+var_4], 0 ; 2) ЗАЧЕМ В СТЕК КЛАДЁТСЯ ЭТОТ НОЛЬ? mov al, 0 ; 3) ЭТО МЫ СООБЩАЕМ КОЛИЧЕСТВО ПЕРЕДАННЫХ FLOAT-ПАРАМЕТРОВ? ПОЧЕМУ ТОГДА AL, А НЕ EAX? call _printf mov ecx, 0 mov [rbp+var_8], eax ; 4) ЗАЧЕМ? В EAX ВОЗВРАЩАЕТСЯ РЕЗУЛЬТАТ ФУНКЦИИ PRINTF? А ЗАЧЕМ ЕГО В СТЕКЕ СОХРАНЯТЬ? mov eax, ecx add rsp, 10h pop rbp retn main endp
В целом, мне понятно, что делает этот код. Увидев его, я бы без проблем понял, что он делает. Но мне непонятно то, ЗАЧЕМ он делает некоторые вещи.
А вот, что я вижу в IDA, когда компилирую gcc (тоже под FreeBSD, если это важно):
И опять, вопрос в комментарии в кодеCode:main proc near sub rsp, 8 ; ДЛЯ ЧЕГО РЕЗЕРВИРУЕТСЯ 8 БАЙТ В СТЕКЕ? mov edi, offset s ; "Hello, World!" call _puts mov eax, 0 add rsp, 8 retn main endp
И вот ещё, компилируем clang под Linux:
В чём был смысл перебрасывать через стек RAX в RCX?Code:main proc near push rax ; ЗАЧЕМ-ТО СОХРАНЯЕМ RAX В СТЕКЕ mov edi, offset s ; "Hello, World!" call _puts xor eax, eax pop rcx ; А ПОТОМ ЗАЧЕМ-ТО ВЫТАСКИВАЕМ ЭТО ЗНАЧЕНИЕ УЖЕ В RCX. retn endp
Может, я и заморачиваюсь больше нужного, но мне не даёт покоя то, что есть вещи, остающиеся непонятыми :) Хотелось бы в конечном итоге прийти к тому, чтобы мне была понятна вообще каждая строчка, которую я вижу в IDA, от самого начала до cамого конца, а не только дизассемблированные функции, которые мной же и были написаны.



Reply With Quote
Thanks
