裸函数_与调用约定

注意1:int __declspec(naked) __fastcall Test_fastcall(int x,int y,int m,int n) 顺序不能乱

- 空函数

void Plus10()
{
}
----------
  288:   Plus10();
004119D8  call        004110DC 
----------
    6: void Plus10()
    7: {
00411450  push        ebp  
00411451  mov         ebp,esp  
00411453  sub         esp,0C0h  
00411459  push        ebx  
0041145A  push        esi  
0041145B  push        edi  
0041145C  lea         edi,[ebp+FFFFFF40h]  
00411462  mov         ecx,30h  
00411467  mov         eax,0CCCCCCCCh  
0041146C  rep stos    dword ptr es:[edi]  
     8: 
     9: }
0041146E  pop         edi  
0041146F  pop         esi  
00411470  pop         ebx  
00411471  mov         esp,ebp  
00411473  pop         ebp  
00411474  ret  

- 裸函数

int  __declspec(naked)Plus11(int x, int y)
{
}
--------------
call        004110DC
004110DC    int3

- 裸函数–正常执行

因为call执行的过程相当于 push eip+4

int  __declspec(naked)Plus11(int x, int y)
{
    ret
}

- 裸函数–默认 cdecl

   289:      Plus11(1,2); 
004119DD  push        2  
004119DF  push        1  
004119E1  call        0041114F  
004119E6  add         esp,8  
-------------
int  __declspec(naked)Plus11(int x, int y)
{
    /***
    *你们别管我了,让我自生自灭。
    *return; 具有“naked”特性的函数中不允许“return”
    *
    *
    *画堆栈图:
    *         最重要的是参数、局部变量、返回值
    *参数:
    *         当函数执行到这的时候,参数在不在堆栈里?
    *         已经在堆栈了.call之前就入栈了.
    *
    *局部变量:
    *         debug版存到缓冲区。
    *
    *返 回 值:
    *         一般存在eax,还可以写在内存中
    *
    *调用方式:
    *        默认是__cdecl,根据参数外平栈。
    *
    *******************************************************/

    //
    __asm   // _asm也行
    {
        //提升堆栈 --大脑有图
        push ebp                        // 保留调用前的栈底
        mov ebp,esp                     // 提升堆栈
        sub esp,0x40    
        push edx                        // 保留现场
        push esi
        push edi
        lea edi,dword ptr ds:[ebp-0x40] // 填充缓冲区
        mov ecx,0x10
        mov eax,0xCCCCCCCC
        rep stosd                       // 我理解的可以这样,mov edi,ebp;sld,

        // 函数功能
        mov eax ,dword ptr ds:[ebp+0x08]
        add eax ,dword ptr ds:[ebp+0x0C] 

        // 恢复现场
        pop edi
        pop esi
        pop edx

        // 
        add esp,0x40 // lea esp,dword ptr ds:[esp+0x40] --第一遍写成sub了,注意
                     // mov esp,ebp
        pop ebp
        // 返回
        ret
    }   

}

- 裸函数–stdcall

   308:     Test_stdcall(1,2);
004119D8  push        2  
004119DA  push        1  
004119DC  call        00411104  
--------------------------
int  __declspec(naked) __stdcall  Test_stdcall(int x,int y)   // stdcall 写前面是“语法错误”
{

    __asm
    {
        // 保存原栈底。---开栈                                // push ebp
        push ebp                                              // mov ebp,esp
        mov ebp,esp                                           // sub esp,0x40
        sub esp,0x40    // lea esp,dword ptr ds:[esp-0x44]    // mov ecx,0x10
                        // add esp,-0x44                      // mov eax,0xCCCCCCCC
        push edx                                              // lea edi,dword ptr ss:[ebp-0x4]
        push esi                                              // std
        push edi                                              // rep stos dword ptr es:[edi]
                                                              // cld
        mov eax,0xCCCCCCCC                  
        mov ecx,0x10
        lea edi,dword ptr ds:[ebp-0x40]         
        rep stosd                           

        mov eax,[ebp+0x8]
        add eax,[ebp+0xC]

        // 恢复现场
        pop edi
        pop esi
        pop ebx

        mov esp,ebp
        pop ebp

        ret 8
    }

}

- 裸函数–fastcall—–结合内联汇编

main 函数中:
__asm
    {
        push 4
        push 3
        mov edx ,0x2
        mov ecx,0x1
        call Test_fastcall; 
    }
    -----
int  __declspec(naked) __fastcall 
Test_fastcall(int x,int y,int m,int n)   
{
    __asm
    {       
        push ebp                            
        mov ebp,esp                     
        sub esp,0x40

        push edx                        
        push esi                        
        push edi
        push ecx

        mov eax,0xCCCCCCCC                  
        mov ecx,0x10
        lea edi,dword ptr ds:[ebp-0x40]         
        rep stosd                           

        pop ecx

        mov dword ptr ds:[ebp-0x4],ecx
        mov dword ptr ds:[ebp-0x8],edx

        mov eax,[ebp+0x8]
        add eax,[ebp+0xC]
        add eax, dword ptr ds:[ebp-0x8]
        add eax, dword ptr ds:[ebp-0x4]
        // 恢复现场
        pop edi
        pop esi
        pop ebx

        mov esp,ebp
        pop ebp

        **ret 8**
    }

}

你可能感兴趣的:(汇编)