栈破坏的分析

2023-10-27

在程序运行中,栈主要用来保存局部变量,函数参数,函数调用的返回地址以及栈底。以x86为例,与栈关系比较大的几个寄存器主要是:

ebp:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部

esp:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶

eip:指令寄存器(extended instruction pointer),其内存放着一个指针,该指针永远指向下一条等待执行的指令地址

在函数的一层层调用过程中每个函数都会有自己的一段栈,一般把它叫做函数的栈帧。每个函数的栈帧都保存了自己的局部变量,自己栈帧底的值,返回地址以及上一次函数的参数。这样文字描述比较抽象,下面用一个例子和图表来说明。假设程序中函数的调用关系是:funcA调用funcB,funcB调用funcC,funcA->funcB->funcC,用伪代码来表示就是:

funcC()
{
.....
}

funcB()
{
...
  funcC();
...
}

funcA()
{
...
  funcB();
...
}

那么这个调用关系的函数栈帧就可以用下面这个图来大致描述:

从这个图上可以看到,首先栈是从高地址往低地址延展,所以funcA在上面高地址处,funcC在低地址处。每个函数栈帧的结构都差不多,这里主要就是要说明一些图片里面的:返回地址,保存的ebp。返回地址指的是被调用函数的返回地址,保存的ebp是指自己的栈帧底部的值。已funcB为例,返回地址就是funcC返回到funcB的地址,保存的ebp就是funcB的栈帧底的值。

程序在正常运行中,就是通过这样的方式保存了每个函数的现场,当返回的时候就可以恢复如初。如果程序运行过程中出现错误导致crash,我们也可以使用gdb工具通过分析coredump文件,查看函数调用关系来确定问题出现的范围。但是如果函数的栈帧被破坏掉了,就是返回地址核保存的ebp值出错,这样gdb是没办法获取函数的调用关系,也就无法确定问题的大致范围,会造成问题难以处理。不过如果好好的理解上面这个函数栈帧图后,还是可以通过自己手动去分析。下面具体看下分析的过程。

下面这个是测试用的源码:

char names[] = "book cat dog building vegetable curry";
  
void func(void)
{
    char buf[5];
    strcpy(buf,names);
}

int main(void)
{
     func();                                                                                                                                                             
     return 1;
}

 这个函数是使用了strcpy的一个漏洞,通过names里面的值把函数的栈帧全部给填充了,造成栈帧破坏。
下面先编译这个程序:

gcc -g -fno-stack-protector -o stack_test stack_test.c  #这里关闭了栈保护,来模拟堆栈完全破坏的情况

运行程序后,会coredump,产生core文件,使用gdb加载coredump文件和可执行文件。可以看到,栈被破坏都无法显示调用关系了,所以也就无法确定问题出现的情况。

看下寄存器的信息

可以看到,ebp和esp的值都不是太对,按道理ebp应该和esp不会差太多,eip表示的是代码执行地址

按照x86 ELF文件的布局,正常应该在0x08040000附近

根据函数调用栈的关系,可以知道调用函数的时候会将ebp和返回地址压栈,函数返回的时候,会先将ebp弹出,然后弹出返回地址给eip,eip就是pc指针,cpu就会跳转到eip保存的地址里面去。这里正是因为eip的值不正确,导致程序异常退出了。我们知道,栈的方向是从高地址向低地址方向生长,而数据是从低地址向高地址,所以栈被破坏应该是从某个地址往高地址方向,也就是外层函数的栈被破坏了,但是正在执行的这个函数,有部分栈并没有被破坏,是有可能寻找到一些信息的。

将esp前面的一段内存输出,看看情况可以看到这段内存里面,按照地址从高到低,保存了eip和ebp的值,同时可以看到红框的两个地址,很明显是代码的执行地址(0x0804xxxx),可以看下这两个地址的代码是什么

 

先看看0x0804a040

可以看到,没有反汇编出函数名

下面看看0x08048422地址

可以看到,反汇编出函数名为:func,然后就可以定位到问题,应该就在func函数里面。

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

栈破坏的分析 的相关文章

  • gdb:显示源代码和asm中的相应行

    在 TUI 模式下运行 gdb 并显示源代码和汇编时 是否有一个选项可以突出显示映射到选定源代码行的指令集 您可以使用 GDB Dashboard 部分完成此操作 https github com cyrus and gdb dashboa
  • C++ 程序在执行 std::string 分配时总是崩溃

    我一直在尝试调试崩溃的应用程序中的崩溃 即断言 检测到 glibc free 无效指针 0x000000000070f0c0 当我尝试对字符串进行简单分配时 请注意 我正在使用 gcc 4 2 4 的 Linux 系统上进行编译 优化级别设
  • 如何将 gdb 附加到 docker 容器中运行的进程?

    我在 docker 容器中有一个长时间运行的进程 我想将 gdb 附加到该进程以查看正在运行的线程并获取堆栈跟踪 我可以从主机附加到进程 但无法解析任何符号 因为可执行文件位于文件系统中的不同位置 位于 docker 安装的卷中 并且共享系
  • 如何判断共享库加载到进程地址空间中的位置?

    我正在尝试调试一个共享库 其中有使用 gdb 的源代码和调试符号 我没有实际使用此共享库的进程的调试符号或代码 我自己编译它 所以我可以拥有一切 但生成的二进制文件被剥离 以模拟我没有代码的情况 该进程打印我正在尝试调试的目标函数 foo
  • 用于分析 Node.js 核心转储的工具 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 如果我使用 gcore 制作 Node js 进程的代码转储 分析它的最佳工具是什么 灵感来自 jav
  • 将大核心文件转换为“minicore”文件

    如何将核心文件减少到仅线程堆栈 我希望能够运行 gdbthread apply all bt在迷你核心上 仅此而已 我正在处理大型 gt 4GB 多线程 Linux ELF 核心文件 这些文件太大而无法返回进行分析 我见过谷歌断点器 htt
  • fork 后调试子进程(配置了 follow-fork-mode 子进程)

    我正在开发一个应用程序 父级分叉子级来处理某些任务 我遇到一个问题 我已将 gdb 配置为 follow fork mode 子级 但在 fork 后 到达断点后 它发送 SIGTRAP 但子级以某种方式终止并向父级发送 SIGCHLD 我
  • 如何在 gdb 中打印长字符串的完整值?

    我想在 GDB 中打印 C 字符串的完整长度 默认情况下它是缩写的 如何强制 GDB 打印整个字符串 set print elements 0 来自GDB手册 https sourceware org gdb onlinedocs gdb
  • 使用 gdb 调试时彻底退出 valgrind

    我正在使用 valgrind 和 gdb 调试程序 然而 我以一种野蛮的方式终止了这些调试会话 这真的是它应该做的吗 设置调试会话 按照来自的指示valgrind 官方网站 http valgrind org docs manual man
  • 在 gdb 中设置应用程序关联

    有没有一种简单的方法可以设置我正在调试的应用程序的亲和力 而无需将 gdb 锁定到同一核心 我问的原因是应用程序以实时优先级运行 并且需要在单核上运行 目前我使用这个命令行 taskset c 3 gdbserver 1234 app ou
  • 哪个信号被传递到信号处理程序中死锁的进程

    我有一个来自调用信号处理程序后死锁的进程的核心转储 如何确定传送了哪个信号以及是谁发送的 GDB 为接收信号的线程生成的回溯如下 信号处理程序在第 15 帧中被调用 gdb bt 0 0x00007fa9c204654b in sys fu
  • Eclipse 调试模式下的 GDB 找不到 stdlib/rand.c

    我试图让 gdb 在 ubuntu 上与 eclipse cdt 一起运行 以开始调试一些简单的程序 所以我做了我认为必要的步骤来让它运行 1 创建可执行项目 2 Compile 3 Run 4 创建文件 gdbinit 并将其放在主项目文
  • gdb 中的 是什么意思?

    gdb n 134 a b c 0xdeadbeef uint32 t length initval gdb n gdb p a 30
  • gdb 不会从外部架构读取核心文件

    我正在尝试在 Linux 桌面上读取 ARM 核心文件 但似乎无法找出我的核心文件 有什么方法可以指示 gdb 我的核心文件是什么类型吗 file daemon daemon ELF 32 bit LSB executable ARM ve
  • 如何将整个 GDB 会话转储到文件中,包括我输入的命令及其输出?

    在 bash 中 我可以使用script命令 它将 shell 上显示的所有内容转储到文件中 包括 键入的命令 PS1 line 命令的 stdout 和 stderr gdb 中的等效项是什么 我试着跑shell script从 GDB
  • 没有可用的符号表信息

    我正在测试第三方的库 它崩溃了 当我想查看崩溃的原因时 我的 gdb 告诉我没有可用的调试符号 Program received signal SIGSEGV Segmentation fault Switching to Thread 0
  • 如何模拟ARM处理器运行环境并加载Linux内核模块?

    我尝试加载我的vmlinux into gdb并使用 ARM 内核模拟器 但我不明白为什么我会得到Undefined target command sim 这是外壳输出 arm eabi gdb vmlinux GNU gdb GDB 7
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 使用 math.h 函数时 gdb 给出奇怪的输出[重复]

    这个问题在这里已经有答案了 可能的重复 为什么 gdb 将 sqrt 3 计算为 0 https stackoverflow com questions 5122570 why does gdb evaluate sqrt3 to 0 这里
  • 如何让 UIAutomation、模拟器和 Xcode 调试器同时运行?

    谁能向我指出有关如何使 Instruments 运行 UIAutomation 脚本并使用在模拟器中运行的调试器启动 iPhone 应用程序的文档 限制条件 我只有 iPhone 3g 硬件来测试和调试 而 UIAutomation 无法可

随机推荐

  • mysqldump where子句使用

    mysqldump 的 where 条件子句适用于这种情况 导出某张表的部分数据 where name 参数详情 w where name Dump only selected records Quotes are mandatory 使用
  • python下复制excel某行数据,xlwings

    不是专业码农 朋友课题遇到一个问题 调研了90个人 有14个sheet的数据 每个人的数据在14个sheet里面都有 位置也相同 比如张三的数据 在14个sheet里面都是在18行 需要把其中16个人的数据拿出来 还是这14个sheet都要
  • spring如何做到循环引用

    spring如何做到循环引用 总结 源码中的流程 如果看官觉得有点用 点赞一下 鼓励一下我吧 总结 spring的循环引用只有一种情况 单例且无参构造 多例情况不支持 有参构造不支持 原因 无参构造可以完成创建在堆内存中的引用 即使这个引用
  • spring-boot配置slf4j日志

    SLF4J 即简单日志门面 Simple Logging Facade for Java 不是具体的日志解决方案 它只服务于各种各样的日志系统 按照官方的说法 SLF4J 是一个用于日志系统的简单 Facade 允许最终用户在部署其应用时使
  • socks5代理ip账号密码_VMlogin中文版配置使用911S5代理

    一 911 S5代理设置 打开911 S5代理并去往 程序 Program 页面 在程序列表 program list 中随机添加一个程序 911 S5程序需要用户选择一个程序 请您不要在此处添加VMlogin 因为它会收到干扰 前往 设置
  • Dynamic Region-Aware Convolution

    旷视提出 DRConv 动态区域感知卷积 提升分类 检测 分割性能 Dynamic Region Aware Convolution 是2020年旷视在arXiv上的新论文 该论文实际上是在动态卷积 local形式 上引入了空间上的分组 从
  • 亚马逊云科技上实现 “端到端”安全

    亚马逊云科技认为 安全是构建生成式 AI 不可回避的重要议题 企业只有在 AI 旅程中做好数据 模型和应用的安全防护 才能更好地借助 AI 加速业务创新 同时在全球业务规划做好战略布局 亚马逊云科技在五大领域为用户提供全方位的云安全服务 威
  • Qt环境生成dump解决异常崩溃

    背景 对于经常使用C C 的伙伴来说 程序有问题动不动就罢工崩溃的问题简直不能太熟悉了 比如本地测试通过打包发布的release版本Qt程序 在客户环境下仍可能出现异常崩溃的问题 一般通过客户反馈以及分析系统运行日志 问题基本都能够得到快速
  • 洛谷表达式求值

    题目描述 给定一个只包含加法和乘法的算术表达式 请你编程计算表达式的值 输入输出格式 输入格式 一行 为需要你计算的表达式 表达式中只包含数字 加法运算符 和乘法运算符 times 且没有括号 所有参与运算的数字均为 000 到 231 1
  • CentOS 7下启动、关闭、重启、查看MySQL服务

    1 启动命令 root xufeng Desktop service mysqld start Redirecting to bin systemctl start mysqld service 2 关闭命令 root xufeng ser
  • 栈系列之 递归实现一个栈的逆序

    算法专题导航页面 算法专题 栈 栈系列之 栈排序 栈系列之 最小栈的实现 栈系列之 用栈实现队列 栈系列之 递归实现一个栈的逆序 题目 使用递归来完成一个栈的逆序操作 其他限制 不能借助任何其他数据结构 图示 无 分析 递归思想原本就和栈这
  • 力扣第五十三道最大子数组和

    题目 给你一个整数数组 nums 请你找出一个具有最大和的连续子数组 子数组最少包含一个元素 返回其最大和 子数组 是数组中的一个连续部分 输入 nums 2 1 3 4 1 2 1 5 4 输出 6 解释 连续子数组 4 1 2 1 的和
  • Exploring Large Language Models for Knowledge Graph Completion

    本文是LLM系列文章 针对 Exploring Large Language Models for Knowledge Graph Completion 的翻译 探索用于知识图谱补全的大型语言模型 摘要 1 引言 2 相关工作 3 方法 4
  • C/C++中的日期和时间

    C C 中的日期和时间 撰文 周翔 摘要 本文从介绍基础概念入手 探讨了在C C 中对日期和时间操作所用到的数据结构和函数 并对计时 时间的获取 时间的计算和显示格式等方面进行了阐述 本文还通过大量的实例向你展示了time h头文件中声明的
  • 数据结构---单链表的增删改查(C语言实现)

    链表的创建 链表元素插入 头插 尾插 指定位置插入 链表元素的删除 链表元素的查看 1 链表的创建 有头链表 有头链表的创建就是创建一个头结点代表此链表 用一个结构体指针指向头结点 通常称为头指针 方便找到此链表 头结点的数据域一般不做处理
  • 软件测试笔记(五)- 动态黑盒测试

    了解在没有代码的情况甚至不懂得编程的情况下的软件测试技术 一 动态黑盒测试 戴上眼罩测试软件 不深入代码细节测试软件的方法称为 动态黑盒测试 它是动态的 因为程序在运行 软件测试员像用户一样使用它 同时 它是黑盒子 因为测试时不知道程序如何
  • STViT-R 代码阅读记录

    目录 一 SwinTransformer 1 原理 2 代码 二 STViT R 1 中心思想 2 代码与原文 本次不做具体的训练 只是看代码 所以只需搭建它的网络 执行一次前向传播即可 一 SwinTransformer 1 原理 主要思
  • H5C3部分面试题汇总

    1 HTML和HTML5 CSS和CSS3相比 有什么变化 HTML5中新增的内容有 自定义属性 data id 语义化更好的内容标签 header nav footer aside article section 音频 视频标签 audi
  • 复习之linux系统中的软件管理

    一 linux系统中软件包 1 软件包的类型 注意在rhel8中只能使用绿色软件 源码编译软件和rpm软件 类型 支持的条件 DEB UBlinux DEBlinux 用不了 RPM redhat centOS fadora bz2 gz
  • 栈破坏的分析

    在程序运行中 栈主要用来保存局部变量 函数参数 函数调用的返回地址以及栈底 以x86为例 与栈关系比较大的几个寄存器主要是 ebp 基址指针寄存器 extended base pointer 其内存放着一个指针 该指针永远指向系统栈最上面一