什么是函数

函数就是一系列指令的几个,为了完成某个会重复使用的特定功能

函数调用

  1. JMP来执行函数
  2. 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

堆栈平衡

调用函数之前堆栈的状态跟调用函数后的状态一样,成为堆栈平衡

需要注意的点

  1. 如果要返回父程序,则当我们在堆栈中金星堆栈操作的时候,移动要保证在RET这条指令之前,ESP指向的是我们调用时压入栈中的地址
  2. 如果通过堆栈传递参数了,那么在函数执行完毕后,要平衡参数导致的堆栈变化

函数外部平衡堆栈: –外平栈

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