三种call解释(一): cdcall stdcall naked call等在hook时,保持堆栈平衡

本文详细介绍了三种call调用约定:cdcall、stdcall和naked call的工作原理,特别是在函数hook时如何保持堆栈平衡。通过实例分析了各自的特点,如cdcall在函数外部释放堆栈,stdcall在函数内部释放,naked call则不生成保存和恢复寄存器的代码,要求手动维护堆栈平衡。

exe调用某个函数时:  int TestFun(int a, int b);
EBP+C: second parameter
EBP+8: first parameter
EBP+4: return address
EBP:   previous EBP       ===》 旧的ebp值(调用者的ebp)
EBP-4: local variable
EBP-8: local variable

内存地址的增长方向:
对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;
对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长;

(1)cdcall  堆栈资源释放在函数执行外面,一般的c语言调用。    CALL  XXX;   ADD ESP, xxH

fun xxx(){

   push eax

   CALL  XXX;    //xxx(int)  ==>  cdcall;

   ADD ESP,04H   // 增加值由xxx函数,入栈参数个数确定;

}
(2)stdcall 在函数的里面释放堆栈,一般的windows API。                 CALL  XXX;

fun xxx(){

     push ebp
     mov  ebp,esp

     ///  插入新代码
     ...
     ///  插入新代码 end;

    mov  ebp,esp
    pop  ebp

retn

}
(3) naked call。 进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。 (这些代码称作 prolog and epilog code,一般,ebp,esp的保存是必须的). 但是naked call不产生这样的代码。  ==> 维持堆栈平衡;

xxx函数使用naked call被调用时: 保持堆栈平衡;
fun xxx(){
     __asm
    {
         push ebp
         mov  ebp,esp
     }

     ... 代码;

}

例子:

__declspec(naked) void __stdcall My_MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{// Jmpcode.addr=(DWORD)(My_MessageBox)-(DWORD)(MessageBoxA)-5;
    __asm
    {
            PUSH EBP
            MOV EBP,ESP
    }
    printf("取得参数 %x,%s,%s,%x\n",hWnd,lpText,lpCaption,uType);
    __asm
    {
            mov ebx,old_MessageBoxA  //讲MessageBoxA地址赋给EBX
            add ebx,5                //EBX+5
            jmp ebx
    }  
}

__asm  硬编码
{
_emit 0x8b
_emit 0xd4   // MOV EDX,ESP
_emit 0x0f
_emit 0x34   // SYSENTER
}

(4)取数据的方法:
A:基址 + 偏移地址;
B:函数取代;  ==》 参数相同的函数;              ==》 hook函数地址
C:函数增加;  ==》 参数不同的函数;加入一个函数;==》 hook地址,增加函数(保持堆栈平衡),调用地址之后代码;
D:多个函数协同调用;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值