什么是函数
函数就是一系列指令的几个
,为了完成某个会重复使用的特定功能
函数调用
- 用
JMP
来执行函数 - 用
CALL
来执行函数
函数的参数和返回值
通常情况下,会将函数的计算结果放到EAX寄存器中
EAX 通常用来放返回值
简单的加法函数
ADD ECX,EDX //传参
MOV EAX,ECX //传结果到EAX中
RETN
堆栈传参
如果参数很多怎么办?10个数相加
那么就可以使用堆栈传参
堆栈特性 先进后出
PUSH 1
PUSH 2
PUSH 3
PUSH 4
PUSH 5
call 0x41844d
//调用完毕后值就会存储在EAX中
MOV EAX,0x0 //假如地址是 :0x41844d
ADD EAX,DWORD PTR DS:[ESP+14] =>1
ADD EAX,DWORD PTR DS:[ESP+10] =>2
ADD EAX,DWORD PTR DS:[ESP+0xC] =>3
ADD EAX,DWORD PTR DS:[ESP+8] =>4
ADD EAX,DWORD PTR DS:[ESP+4] =>5
RETN
堆栈平衡
调用函数之前堆栈的状态跟调用函数后的状态一样,成为堆栈平衡
需要注意的点
- 如果要返回父程序,则当我们在堆栈中金星堆栈操作的时候,移动要保证在RET这条指令之前,ESP指向的是我们调用时压入栈中的地址
- 如果通过堆栈传递参数了,那么在函数执行完毕后,要平衡参数导致的堆栈变化
函数外部平衡堆栈: –外平栈
PUSH 1
PUSH 2
CALL XXX
ADD ESP,8
MOV EAX,DWORD PTR DS:[ESP+8]
ADD EAX,DWORD PTR DS:[ESP+4]
RETN
函数内部平衡堆栈 : –内平栈
PUSH 1
PUSH 2
CALL XXX
MOV EAX,DWORD PTR DS:[ESP+8]
ADD EAX,DWORD PTR DS:[ESP+4]
RETN 8
RETN X
RETN + 字节数
相当于
ADD ESP,8
RETN