汇编中如何封装已有的函数
有时候反编译后发现函数是类的一个方法,因此调用函数的时候有部分参数是通过eax或者esi传进来的,不是直接push进堆栈。这时候我们如果要使用c语言进行调用会比较麻烦,所以我的想法是把这种函数进行二次封装,让eax或者esi作为push的形式传进去,这样c语言调用的时候就可以直接进行函数调用。
首先,我们需要扩展这个软件的内存,如果软件可以找到确定可用的内存地址块也可以直接使用,否则可以自行扩展,扩展内存后找到扩展内存的起始地址,写入汇编代码,这个汇编代码是我们封装已有函数的代码,这个起始地址则为我们调用函数的地址。
这时候这里有一个坑要注意,传参堆栈中不是直接拿的esp作为第一个参数,通过push传参数,然后call+目标地址,此时传进的参数不是[esp],
即不是栈顶,因call的时候会相当于把call指令下一行的地址push到栈顶,所以在call的函数里面拿参数要栈顶往下4个byte,即[esp+4]
来拿这个参数。
最后,我们就可以使用c语言进行调用,但是直接调用hex地址还是不够优雅,我们需要用c函数封装一下,后面使用起来也不容易用错,例如:
void createView(int viewAddr, int layerIndex, int offsetX, int offsetY)
{
((void (*)(int, int, int, int))0x894000)(viewAddr, layerIndex, offsetX, offsetY);
}