Reverse learning - drawing stack map

0x00: EDITORIAL

For many beginners, it is very difficult to reverse entry, many need to take the high ground to climb, then the stack for many people is a highland, how to conquer the stack? Stack Figure painting is a good way to understand the stack.

0x01: Introduction Stack

Stack is a kind of a data item data structure in sequence, only one end (referred to as a top of the stack (Top)) to insert and delete data items.

Important: stack: Stack random order: LIFO (Last-In / First-Out)

1, the stack area (stack) - released automatically allocated by the compiler, the storage function parameters, local variables, and the like. Operate similarly to a stack data structure.
2, the heap area (heap) - typically assigned by the programmer is released, if the programmer does not release at the end of the program may be recovered by the OS. Note that this data structure is totally different in the stack, similar to the distribution list touches

0x02: started

Preparation: OD (my love crack dedicated OD)

         Drawing tools excel

         Program: Helloworld.exe (link: https: //pan.baidu.com/s/130job_JfoQLEWQxKn0SMYQ Password: 71xq)

Here then we add OD loader F2 breakpoint at 00,401,168.

00401168 Helloworld.exe here is a function of the entry point wherein

Here, when a program break, attention register window EIP: 00401168, then this bit is the next hop of the program at this time.

Observation register windows ESP, EBP

Then the initial stack lower graph of FIG.

Step by step down the F8 execution

First look at the push 0x2 00,401,168 position (push 0x2 (16 hex))

 

 

 Since two push is a type of assembler instruction. Write - put together

Press-fitted into the stack 0x2 and 0x1 (note are hexadecimal), then the stack into two ESP (stack -8) = 0012FF2C, EBP (stack bottom no change), 1, and 2 are pushed to be used .

Next to this function the call HelloWor.0040100A

So F7 directly into the call in

 

At this point the stack change ESP = 0012ff28

 可以看到是到了jmp指令处,jmp(直接跳转,无条件),直接回车跟随jmp后的地址

 

 00401040就是jmp后的地址,也是我们下一步执行的命令 push ebp

 

把EBP压入栈中,此时ESP-4

接着F8执行mov ebp,esp

 

 把esp(栈顶的值赋给ebp),此时ESP和EBP相等

再顺序执行sub esp,0x40,esp-40(换算为16进制就是64,那么栈顶向下移动16个空格(堆栈由下向上是递减的)一格4个字节(32位))

 

F8单步过至push ebx,push esi,push edi

把ebx,esi,edi的值压入堆栈,相当于把这三个寄存器的值放到堆栈进行保存

lea edi,dword ptr ss:[ebp-0x40] :意思是把edp-0x40的地址值保存到edi中

EDI=0012FEE4

接下来到了循环处,ecx(循环寄存器)赋值0x10,eax赋值0xcccccccc,rep循环10次,且edi的地址每次循环+4,eax赋给其代表值

 

 堆栈图为下图(VC会将未初始化的栈内存上的指针全部填成 0xcccccccc,翻译中文就是烫烫烫烫烫烫烫烫。。。

接下来执行

mov eax,dword ptr ss:[ebp+0x8]  将ebp+0x8的值赋给eax

add eax,dword ptr ss:[ebp+0xc]   将ebp+0xc的值和eax进行add相加

那么此时的eax=00000003堆栈图如下

 

 接着执行pop edi,pop esi,pop ebx。让保存的3个寄存器值取出来恢复。

mov esp,ebp将ebp值赋给esp

 

 pop ebp(将栈顶出栈赋给ebp)

 

 最后函数最后retn进行返回,retn转换为汇编代码就是 pop esi

 

最后一步 add esp,0x8

 

 进行对比可知,一次函数执行的前后,堆栈是最终恢复成函数执行初始的样子,对比第一步和最后一步ESP,EBP即可知。

那么经过堆栈图的制作,我们通过过程得知了这个函数功能很简单,就是传参然后实现相加并返回结果。

0x04:总结

堆栈在逆向,程序开发中都尤为重要,知道代码运行过程中堆栈的变化会让逆向清晰起来。

一个函数的调用前和return结束过程后,堆栈不会发生变化,遵循堆栈平衡

cc对应着int 3调试中断,堆栈中的存放的局部数据一般情况下是只读的,当发生意外执行堆栈里面的数据就会引发该调试中断,可以把0xccccccc理解为占位符,防止堆栈空白导致程序出错

 

Guess you like

Origin www.cnblogs.com/Tkitn/p/12354131.html