Разные компиляторы (Visual Stuidio C++, Borland Delphi, OPEN WATCOM, GCC и др.) по разному создают код исполняемого файла. Если вам интересно, попробуйте скомпилировать одну и ту же программу на разных компиляторах и посмотреть результат в IDA.
Мы будем рассматривать только компилятор Visual Studio C++.
С чего начинать изучать дизасемблирование? Во первых нужно взять какой то один компилятор- например мы возьмем Visual Studio C++ 2005. Во вторых нужно создать простую программу вроде:
int main(void) { return 0; }
Откомпилировать и посмотреть ее в IDA. Вы увидите что у функции есть пролог и эпилог - сохранение регистров процессора в начале функции и восстановление их в конце.
Во вторых, нужно взять разные конструкции С++ (switch, if, else, for и др.), сделать программу с функцией main и только с этими конструкциями (для простоты) и посмотреть в IDA как они выглядят. Одним словом нужно писать свои программы и изучать дизасемблированный код в IDA этих своих программ.
Далее, можно взять какой то исходный код из интернета какой то известной программы написанной профессиональными программистами, откомпилировать этот исходный код, и изучать его в IDA. В чем здесь смысл- вы смотрите исходный код программы в Visual Studio C++ (или др. компилятор), и сразу же изучаете ассемблерный листинг в IDA.
Таким образом можно научиться определять в ассемблерном листинге IDA что имел ввиду программист, когда писал исходный код этой программы, и у вас появиться возможность самому декомпилировать программы - то есть на базе ассемблерного листинга IDA обратно писать код на С++.
Так же необходимо знать язык Ассемблера, т.к. в IDA листинг выглядит на ассембреле. Например возьмите компилятор MASM и напишите следующий код, затем откомпилируйте и результирующий ЕХЕ файл откройте в IDA. Программа на ассемблере ниже просто выводит строку текста на экран.
.MODEL SMALL .STACK 100h .DATA HelloMessage DB 'Hello World',13,10,'$' .CODE START: mov ax,@data mov ds,ax mov ah,9 mov dx,OFFSET HelloMessage int 21h mov ax, 0 int 16h ; Wait for keystroke mov ah,4ch int 21h END START
Когда вы в коде дизасемблированной программы определили функцию main() или WinMain() необходимо определить какие параметры передаются в первую вызываемую функцию, и затем отслеживать каждую следующую функцию и передаваемые параметры. Так вы не потеряете логическую цепочку при исследовании дизасемблированных программ.
К примеру есть известная игра Quake 1 - исходный код опубликован в интернете, можно загрузить. Вы загружаете исходный код Quake 1, компилируете при помощи Visual Studio 2005 (предварительно сделав несколько исправлений в коде С++). Затем проверяете - берете скомпилированый ЕХЕ файл, запускаете игру, все работает. Далее открываете этот ЕХЕ файл в IDA ищете функцию WinMain(), и паралельно держите открытым Visual Studio 2005 с исходным кодом игры - вы заглядываете в исходный код в Visual Studio 2005 и смотрите дизассемблированный код ЕХЕ файла в IDA, и таким образом изучаете дизасемблированный код. Так же вы можете взять любую программу, и работать с ней этим методом.