gdb exhanced features(GEF)工具的使用
gdb exhanced features(GEF)工具的使用
当我们遇到一些栈被破坏的情况时,gdb没有办法再解析出调用栈,这个时候,我们就可以用GEF工具来分析被破坏的调用栈。
安装
# 安装
git clone https://github.com/hugsy/gef
cp gef/gef.py ~/.gdbinit-gef.py
echo source ~/.gdbinit-gef.py >> ~/.gdbinit
# 调用gef,直接通过gdb命令就会默认加载gef插件
gdb
# 就会出现带gef>的界面了
gef➤
基本用法
可以输入gef查看常用命令。
比如checksec,efl-info等。
# 查看gef常用命令
gef➤ gef
# 查看gef配置
gef➤ gef config
# 查看命令的帮助
gef➤ help checksec
# 检查某个binary的安全性
gef➤ checksec /bin/ls
# 查看程序信息
gef➤ elf-info
# 合适的位置加断点,并开始运行
gef➤ start
# 查看内存映射
gef➤ vmmap
# xinfo看地址的页信息。
gef➤ xinfo $addr
# telescope看当前地址段,分别对应什么内容
gef➤ telescope
查看安全信息,打钩的越多,越安全。
不用运行程序,就可以看到程序的elf信息,功能和readelf类似
输入start命令,gef就会把断点放在合适的位置,并开始运行。
可以看到寄存器,调用栈等信息。
Vmmap可以看到当前内存映射信息,并高亮代码段,堆,栈的区域。
xinfo看地址的页信息。
telescope(显微镜)命令观察当前栈,或者pc位置的代码信息。
调试调用栈
我们可以通过telescope目录看到栈的具体内容,gdb原生的x命令输出不是很友好。
#include <stdio.h>
void test() {
int stack_array[100000000]; // 消耗栈空间
stack_array[0] = 0; // 防止编译器优化
}
int main() {
test();
return 0;
}
用gdb运行,然后停在test()函数,可以看到函数调用栈。
gdb ./stack_overflow
# 停在test
gef> b test
gef> r
gef> telescope $sp -l 20
调用流程:
_start: linux程序的入口。
__libc_csu_init: 初始化C运行时环境。
endbr64: 防止不可控的跳转。
__libc_start_main: 有一个参数是main函数的地址。
rbp: 栈帧基地址。
rsp: 栈顶地址。
如果继续之行,我们可以看到SEGSEV,表示segment fault。
stack overflow之后,有一个保护页stack guard page会被踩到,就会出现segment fault了。
rip是下一条要执行的内容,可以看到rsp。后续也可以看到rbp,操作的偏移量特别大。通常这种情况很容易导致栈溢出。
下面这个例子,把栈的内容写上0,1,2的数据,更方便观察。
#include <stdio.h>
#include <unistd.h>
#define TEST_DATA_LEN 1000
void test() {
long stack_array[TEST_DATA_LEN]; // 消耗栈空间
for (int i = 0; i < TEST_DATA_LEN; i++)
stack_array[i] = i; // 防止编译器优化
sleep(1);
}
int main() {
test();
return 0;
}
我们也可以通过内存地址映射来知道stack的首尾地址。
可以看到,栈里的数值是从0,1,2,不断往上增长的。
调试heap
# 检查use after free的情况
gef config heap-analysis-helper.check_uaf
# 运行时检查heap的使用情况
heap-analysis-helper
gef config heap-analysis-helper.check_
会打印出一些heap的malloc情况。