打破常规——巧用寄存器
按照默认的函数调用约定,在调用 API 时有些寄存器(如 EBP、ESI、EDI 等)总是被保存在栈中。把函数调用信息存在寄存器中而不是存在栈中会给 shellcode 带来很多好处。比如大多数函数的运行过程中都不会使用 EBP 寄存器,故我们可以打破常规,直接使用 EBP 来保存数据,而不是把数据存在栈中。
一些 x86 的寄存器有着自己特殊的用途。有的指令要求只能使用特定的寄存器;有的指令使用特定寄存器时的机器码要比使用其他寄存器短。此外,如果寄存器中含有调用函数时需要的数值,尽管不是立刻要调用这些函数,可能还是要考虑提前把寄存器压入栈内以备后用,以免到时候还得另用指令重新获取。