利用栈溢出控制程序运行的跳转小实验

利用栈溢出控制程序跳转运行的小实验

之前写代码的时候总是会提示memcpy 是不安全的,建议的函数进行替代.不知道为什么不安全的,今天做了个小实验.

实验目标:通过栈溢出的方式让程序不按照原来的逻辑运行.

步骤1:用C语言写一个栈溢出的代码

#include<windows.h>
CHAR szText[] = { "HelloWorldPe" };
CHAR szText2[] = { "Touch Me!" };
DWORD szShellCode[] = { 0xffffffff,0xdddddddd,0x01211888 ,0 };

INT _memCopy(LPSTR  _lpSrc)
{
    CHAR buf[4] = { 0 };
    INT i = 0;
    while (0!=_lpSrc[i])//只是检测值为0 szShellCode 数组的大小是 sizeof(DWORD) * 4 .目标数组的大小是4个字节肯定能够溢出。
    {
        buf[i] = _lpSrc[i];
        i++;
    }
    return 0;
}

INT main()
{
    _memCopy((LPSTR)szShellCode);
    MessageBoxA(NULL, szText, NULL, MB_OK);//正常执行完_memCopy() 之后要先弹出一个 "HelloWorldPe"的会话框然后再弹出一个 "Touch Me!"的对话框
    MessageBoxA(NULL, szText2, NULL, MB_OK);
    return 0;
}
  • 使用vs 编译程序的时候需要把这个选项改成默认值

在这里插入图片描述

  • 如果不改的话,以为vs 有个运行时检查,即便是栈溢出了程序好像还是可以正常执行.

在这里插入图片描述

  • 关掉之后程序终于如我所愿崩了

在这里插入图片描述

步骤2 使用x64dbg调试程序.

  • 在程序的main 函数处下个断点.F9 执行到断点

在这里插入图片描述

  • F7 步进,到_memCopy 代码处,在步进的过程中,可以看到栈中的值不断的被修改成了数组 szShellCode 中的值,大概是因为 _memCopy 中的 目标数据 buf 是局部变量,局部变量是在栈上开辟的.

在这里插入图片描述

  • 图中栈区00CFFD88 记录的数据,是本来子函数执行完成之后要程序要执行的下一个指令的地址.因为栈溢出的缘故,这个地址将会被我修改.

在这里插入图片描述

  • 子函数执行完成之后,成功跳转到我修改之后的执行地址.实现的效果就是,跳过 原来 “HelloWorldPe” 的massgeBox 不弹出. 直接弹出后面的 “Touch Me!”.

在这里插入图片描述

其他问题补充

  1. “图中栈区00CFFD88 记录的数据,是本来子函数执行完成之后要程序要执行的下一个指令的地址.因为栈溢出的缘故,这个地址将会被我修改.” 不难看出,栈上的数据都是从szShellCode 处复制过来的.第三个 dword 值就是.函数执行完成之后EIP 的值.就是下一个会执行的指令的地址.
    1. 为什么这个第三个dword ?函数调用的时候是要压栈的,调用完成之后是要弹栈的,至于为什么弹到这个值到 EIP .我不是很懂就不班门弄斧了.
    2. szShellcode 的第三个 dword. 的值就是 下一个执行的指令的值.我事先是不知道的,我随便乱写一个值,程序执行是会崩溃的,但是没有关系,我就随便乱写了.我使用x64 dbg 调试的时候.我就能够看到,我先要跳的指令的地址:01241851. 我在内存中找到 HelloWorldPe 这个字符串,就能发现szShellCode 数据的值就在它附近.

因为全局变量都是放在静态储存区(面试八股文,背是背熟了).汇编里面就是.data 段.pe结构里面的.data 节.

​ 然后把第三个dword 改成:01241851目的就达成.

  1. 如果使用flexHex 这类的二进制编辑工具,找到szShellcode ,将第三个 dword 的值修改成01241851.会发现程序没有办法正常执行,程序被加载到内存中的地址,貌似会改变.可能跟重定位有关.所以szShellcode 的构造,是一门我还不懂的学问.
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值