[ Стек ]

И так что такое "стек" и как он работает и какие команды 
использует, для работы нам нужен "WinASM" и отладчик "Ollydbg", 
и так сначала поговорим о функциях "push" и "pop". Первая 
функция с перевода с английского то бишь "push" означает 
"толкать", таким образом с помощью "push" мы заталкиваем 
в "стек" все что угодно, а что бы получить то что мы 
затолкали в "стек" используется команда "pop", кароче вот пример:

.386
.model flat, stdcall
.code
start:
mov eax, 3 ;В регистор eax записываем 3
mov ecx, 2 ;В регистор eax записываем 2
push eax ;Заталкиваем в стек значения регистра
push ecx ;Заталкиваем в стек значения регистра
pop eax ;Получаем данные из стека о содержимом регистра eax
pop ecx ;Получаем данные из стека о содержимом регистра ecx
ret
end start

Если запустить в отладчике нашу программу, то с помощью 
трассировки F8 можно посмотреть как работает стек. Первая 
команда push заталкивает в стек содержимое регистра eax, 
следующая команда сохраняет в стеке регистор ecx, а имено число 2.
Другая команда pop выталкивает из стека число, помещенное 
туда последней командой push, а именно 2. Поэтому как видно 
в отладчике в регистре eax лежит число 2, а в ecx 3. Почему 
так происходит? Ну это понятно даже любому начиющему кракеру, 
помещенное в стек значение последним всегда выходит первым.
Еще пример:

mov eax, 1
mov exc, 2
mov edx, 3
push eax
push ecx
push edx
pop eax
pop ecx
pop edx

Надеюсь понятно каким будет результат, для тех кто в танке 
скажу что значение регистров eax = 3, ecx = 2, edx = 1. 
Конечно если ты попробуешь провести операцию с регистрами 
ax, edx то ничего хорошего ты не увидешь, потому что стек 
не может уместить содержимое 4-байтного регистра в 2-байтовом. 
Pop ax, разберет из стека последние два и разнесет ригистор 
edx пополам так сказать будет бомба, а команда pop edx, 
объединит половинку регистра edx, которая еще хранится в 
стеке, с регистром ax и всю бомбу запишет в edx, конечно 
можешь посмотреть как это будет выглядеть вот пример бомбы:

.386
.model flat, stdcall
.code
start:
mov ax, 231
mov edx, 34
push ax
push edx
pop ax
pop edx
ret
end start

Грузи в отладчик и смотри что будит, адское зрелище 
не так ли? :), но всетаки можно немного усложнить операцию 
для стека, скажем вот так:

mov eax, 8
add  eax, 8
mov ecx, 21
push ecx
push eax
pop ecx
pop eax

В принципе тут нечего сложного нет, в регистор eax кладется 
восьмерка, потом прибовляется еще восьмерка, посмотрев результат 
сложения регистров ты наверно обалдаешь потому что там не 16 а 
десять, но всеже едем дальше в регистор ecx мы кладем число 21,
потом в стек мы грузим данные регистра ecx и eax, и смотрим 
результат, конечно если хочешь бомбы то мы можем сделать вот так:

mov ax, ecx

То есть в регистре ax у нас содержимое регистра ecx, терь добавь 
эту команду к коду и увидешь что будет, для новичка вообще нечего 
не понятно будет :), для того кто знает как работает стек вообще 
скажет разврат какойто, но дело вообщем не в том как и кто что 
оценит, дело в том чего делать не надо. И так давай поговорим о 
дурах, не бойся я так называю "процедуры" :) Что бы понять для 
чего нужен стек невозможно без знакомства с процедурами. 
Процедура - обособленная часть программы выполняющая какую то 
определенную задачу. Процедуру нужны для того что бы понизить 
сложность программы, сделать ее понятной и управляемой.
И так на примере процедура AddDigs:

.386
.model flat, stdcall
option casemap:none
.code
start:
mov eax, 4
mov ebx, 2
call AddDigs
ret
AddDigs proc 
add eax, ebx <-сложить два регистра
ret
AddDigs endp <-Признак конца процедуры
end start

Вот тебе были приведены как работают команды push и pop, как 
вызывать процедуры и чего делать не стоит с регистрами, ну вот и 
все, с вами был Outlaw.

(c) Outlaw