格蠹信息科技有限公司
GDB · 夏训 ·
产生和分析core文件
www.nanocode.cn
盛格塾 2024 暑期公益课程
GDB暑假训练营
在浩瀚的软件海洋中,GDB 不仅是深海探险的潜水艇,更是识别程序崩溃秘密的照妖镜。今天,我们将潜入这片未知的海域,使用 GDB 这一强大的工具,产生并深入分析 core 文件,揭开程序崩溃背后的真相。想象一下,当程序在汹涌的波涛中遭遇危险,GDB 便是那艘勇敢的探险船,用其敏锐的声纳系统,扫描并定位问题的源头。
直播启航:GDB与Core文件的深海探索
随着直播的开始,我简要回顾了 GDB 在变量查看中的强大功能,给大家复习了一下探索 GDB 查看内存的操作,多种查看内存的命令组合。包括解释基本的命令格式,用 set 修改内存的值等等。不过,最值得一提的就是张老师向我们展示了一个属于 GDB 高手才知道的独家命令组合,那就是 x/100ga address。这个命令一般在栈上使用,是用于检查堆栈内容的高级指令。在编程的海洋世界里,GDB不仅能够帮助我们在程序运行时探查其内部状态,还能在程序遭遇不测、沉入海底(崩溃)后,通过 core 文件这一珍贵遗迹,重现崩溃的瞬间,分析导致沉没的元凶。
数码照片——生成Core文件
首先,我先解释了 core 文件时如何在 Linux 系统中生成的。在此之前,我一直以为 core 文件只有在程序崩溃的时候才能生成。但是,张老师告诉我,并不是这样。core 文件就相当于一个照片,你可以在你觉得值得纪念的时候按下拍摄按钮。只不过是说,在程序崩溃的时候操作系统会自动生成 core 文件,以收集出现的问题。
我们先是使用 gdb 的 generate-core-file 命令产生了两个 core 文件。
然后我们又通过修改系统设置,让操作系统自动产生 core 文件。
实验时,我们使用了一个故意设计的空指针崩溃实例——由空指针导致崩溃的程序,我们亲眼见证了系统如何在危机时刻迅速捕捉并生成 core 文件,为我们留下宝贵的线索。
“现在,大家和我一起操作起来,一起探索这个秘密。”我边说边启动 GDB,并加载 core 文件作为探索目标。在 GDB 的指引下,我们看到了程序崩溃时的代码。
我展示了如何使用 bt 命令来查看崩溃时的调用栈。调用栈揭示了程序在沉没前的航行轨迹,是寻找问题根源的重要线索。
进阶——潜入深海
然而,探险之路从不乏意外。在深入分析一个由数组越界访问引起的崩溃时,我们遭遇了 GDB 的 “不解之谜”。面对 GDB 无法直接识别的困境,张老师以其深厚的技术功底和丰富的经验,引领我们踏上了一场别开生面的“黑客式”探索之旅。我们深入程序的底层世界,逐步揭开隐藏在崩溃背后的秘密。原来是我在无意间写的一个越界赋值,却精准的覆盖掉了保存在栈上的 main 函数返回地址。
深海勘探
我们先是按照原来的步骤分析 core 文件,没想到 GDB 无法识别当前执行点对应的函数名或源代码行。
为了进一步探究真相,我跟随张老师的脚步,通过查看 i r;x/100ga;info shared 等命令,一步步探索真相。我们发现我误打误撞的使用到黑客的技术思想造成了这个“漏洞”。
黑客可能会利用程序中的漏洞来篡改栈上的指针值。例如,他们可能通过向程序中注入恶意数据,这些数据会覆盖栈上的某些值,包括指针值。当程序尝试使用这些被篡改的指针时,就可能导致未定义行为,如访问无效的内存地址、执行任意代码等。通过张老师的指导我们通过屏幕上的代码非常清晰的体会到之一操作原理。
直播尾声
随着直播的尾声渐近,我总结了 GDB 在生成和分析 core 文件方面的卓越能力,并鼓励观众在编程的海洋世界中勇敢地航行,利用 GDB 这一强大的工具来应对各种挑战和未知。
在告别之际,我还分享了陪伴我度过 GDB 暑假训练营的学习伙伴——幽兰笔记本,它以其卓越的性能和贴心的设计,成为我们探索编程世界的得力助手。“用幽兰,做软件高手”,这不仅是一句口号,更是我们对未来编程之路的美好期许。
此次直播,不仅让我领略了 GDB 的深邃与强大,更让我有了意外的收获——对黑客如何利用程序漏洞有了更直观的认识。这不仅是一次知识的传递,更是一次心灵的启迪。让我们带着 GDB 赋予的智慧与勇气,继续在编程的海洋中扬帆远航,探索未知。
知识点归纳
序号 | 命令 | 描述 |
01 | generate-core-file | 产生core文件 |
02 | generate-core-file 815.core | 产生名为815.core的core文件 |
03 | ./gearr1 | 执行gearr1的可执行文件 |
04 | cat /proc/sys/kernel/core_pattern | 查看当前的核心转储文件名模式 |
05 | sudo su | 切换到超级用户 |
06 | echo “core-%e-%t” > /proc/sys/kernel/core_pattern | 修改core文件路径 |
07 | ulimit -c | 查看core文件大小 |
08 | ulimit -c unlimited | 修改core文件大小 |
09 | gdb gearr1 core-gearr1-1723703178 | 使用GDB调试core文件 |
10 | gdb --core core-gearr1-1723703178 gearr1 | 使用GDB调试core文件 |
11 | where | 查看所在位置 |
12 | bt -past-main on | 回到main 函数之前的调用栈 |
13 | x/10i $pc | 显示从 $pc 指向的地址开始的10条指令 |
14 | info file | 查看文件信息 |
15 | x/16gx $sp | 以16个64位单元的形式显示栈指针指向的内存区域 |
16 | p $pc | _ |
17 | info shared | 显示当前调试会话中加载的所有共享库 |
18 | info symbol 0xf7e084c4 | 用于查询指定地址处存储的符号 |
19 | p/x 666 | 显示666的16进制数 |
20 | disp/3i $pc | 查看PC周围的3条指令 |
21 | ni | 执行下一条汇编指令 |
对于此次未能参与直播的朋友们,无需遗憾!我们的直播回放已准备就绪,等待着你们的点击与探索。错过直播的朋友可以到 格友视频号 观看录像,重温每一个精彩瞬间,感受GDB内存查看的每一个细节。
以下是具体操作截图,仅供参考
STEP
01
generate-core-file
//默认生成了 core.8476 文件
generate-core-file 815.core
//指定了输出文件名为 815.core 的文件
STEP
02
调试 815.core 的核心转储文件
STEP
03
file gdb
//加载被调试的可执行程序文件
STEP
04
./gearr1
//执行一个名为 gearr1 的程序
cat /proc/sys/kernel/core_pattern
//查看当前系统的核心转储文件处理模式
echo "core-%e-%t" > /proc/sys/kernel/core_pattern
//命令修改核心转储模式
STEP
05
ulimit -c unlimited
//设置核心转储文件的大小为无限制
ls -l
//以长列表格式显示了文件和子目录的详细信息
STEP
06
用GDB打开核心转储文件
STEP
07
where
//查看具体位置
bt -past-main on
//查看main函数之前的调用栈
x/10i $pc
//显示从 $pc 指向的地址开始的10条指令
STEP
08
info file
//输出每个文件的详细信息
STEP
09
gdb 试图显示栈帧的信息
但无法确定该地址处的函数名
STEP
10
x/16gx $sp
//查看当前栈指向的地址接下来16个内存单元的内容
STEP
11
p $pc
//打印程序计数器的地址
info shared
//列出了当前调试会话中加载的共享对象库
STEP
12
p/x arr[10]
//以十六进制形式查看数组arr的第11个元素
info symbol 0xf7e084c4
//查找与地址0xf7e084c4相关联的符号,显示没有匹配的符号
x/20ga $sp
//查看从栈指针当前值指向的地址开始的20个内存单元的内容
STEP
13
x/gx &arr[10]
//查看数组元素地址0x7fffffec38处的内存内容
x/10i 0x0000007ff7e084c4
//查看该地址处之后的10条指令
STEP
14
x/20ga $sp
//显示栈指针当前指向的内存地址开始的20个内存单元
STEP
15
p/x 666
//查看666的16进制值
ni
//单步执行程序中的下一条汇编指令
disp/3i $pc
//每次执行时都会显示当前$pc周围的3条指令
这有助于在单步执行或继续执行程序时
跟踪程序的执行流程
STEP
16
x/3i $pc
//显示当前程序计数器指向的指令以及随后的两条指令
x $sp
//显示栈指针的值,即当前栈顶的地址
STEP
17
【盛格塾】
正心诚意,格物致知
以人文情怀审视软件,以软件技术改变人生
格友公众号
盛格塾小程序
扫描上方二维码或在微信中搜索“盛格塾”小程序
可以阅读更多文章和有声读物
往期推荐