函数调用约定
函数调用约定是对函数调用时传递参数的方式的一种约定。
如果想要控制函数的运行,控制函数的参数无疑是很好的一个突破口。正如罗斯柴尔德所说*“只要我能控制一个国家的货币发行,我不在乎谁制定法律”,同样的,我们也可以说“只要我能控制一个函数的参数传递,我不在乎函数的类型”*。想要控制一个函数的参数传递,首先需要掌握的就是参数的传递规律。
一、系统函数(内核接口)
1、x86架构32位系统调用
使用寄存器传递参数,eax为syscall_number(系统函数编号),ebx、ecx、edx、edi、esi、ebp用于将6个参数传递给系统调用。返回值保存在eax中。
2、x86架构64位系统调用
使用寄存器传递参数,不直接从栈中传递任何参数,eax仍为syscall_number,使用的寄存器有rdi、rsi、rdx、r10、r8、r9.系统调用通过syscall指令完成。返回值,系统调用的结果存放在eax中。
二、用户函数
1、x86架构32位函数调用
使用栈传递参数,由于参数的数量不定,参数不再通过寄存器传递,最后一个参数第一个被压入栈中,直到所有参数都被压入栈中,然后执行call指令调用函数。