博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何使用gdb查看linux ELF64文件某一函数栈中的指定变量
阅读量:2731 次
发布时间:2019-05-13

本文共 1159 字,大约阅读时间需要 3 分钟。

在NJUPT2019 ctf比赛过程中我遇到这样一题。

==Difficulty: easy==

flag格式NCTF{.*}
此题单纯考察调试
flag一调就出哦~~~
==Author QQ: 1403517540==

这题目一看很简单就一个名为debug的文件,用ida pro打开看看。

在这里插入图片描述
找到关键代码,就是把输入的flag和一个名为*s的指针执向的字符串进行比较,然后比较成功就显示flag正确。
检查了一下*s的内存位置。
在这里插入图片描述
发现它在main函数里面,偏移位是-210H,那么接下来我们用gdb来调试这个程序。
在这里插入图片描述
等到程序要求我们输入flag的时候按下ctrl+c给予程序中断信号,然后gdb就会进入控制模式,我们可以在这里输入命令查看栈信息。
在这里插入图片描述
输入backtrace(简写bt)可以打印函数到目前为止调用的栈。
在这里插入图片描述
可以看到__libc_start_main函数所在栈帧是6
注意到其中,main=0x555555554ae6,这个就是我们main函数的基址,很多同学问为什么要这么做,实际上,在linux里面执行main函数的时候是由__libc_start_main来执行的(甚至main函数没有一个独立的栈帧,是和__libc_start_main共享的),因此要找到main函数的栈基址,就要把断点设置在main函数这里,然后查看esp的内容
在这里插入图片描述
输入 b *0x555555554ae6设置断点
然后再输入run,让程序重新运行。
重新运行就会断点断在main函数开头,此时输入info r查看寄存器的值
在这里插入图片描述
可以看到rsp的值是0x7fffffffe168,同时结合ida pro里面的汇编代码可以判断,0x555555554ae6存放的是push rbp命令。

sub esp 8mov [esp] rbp

那么这个0x7fffffffe168值是存储rbp的地址加上8,那么就可以得到rbp的地址是0x7fffffffe160,对应ida里面的偏移0

在这里插入图片描述
加上之前得到的变量地址偏移是-210H,那么我们可以判断flag藏在0x7fffffffe160-210的位置也就是0x7FFFFFFFDF50
此时输入c,让程序恢复运行,在要输入flag的时候继续按ctrl+C中断,然后输入tele 0x7FFFFFFFDF50就可以得到flag。
此时再输入c,把程序恢复运行,输入你刚才得到的flag就可以验证是否正确。
在这里插入图片描述
在这里插入图片描述
当然,这样看main函数的地址其实还是有点麻烦,更简单的办法是info file命令
在这里插入图片描述
我们可以看到这里面entrypoint的值是0x5555555546f0
这个段号就是对应ida里面的.text段的开头
在这里插入图片描述
此时可以算出偏移为0x555555554000然后后面的代码只要加上偏移地址即可。

转载地址:http://pistd.baihongyu.com/

你可能感兴趣的文章
C++虚函数实现原理
查看>>
C++虚函数与纯虚函数区别和重载的概念
查看>>
设计模式之建造者模式
查看>>
列向量互信息计算
查看>>
Leetcode——3. Longest Substring Without Repeating Characters
查看>>
Leetcode——14. Longest Common Prefix
查看>>
Leetcode——27. Remove Element
查看>>
C++11 decltype关键字
查看>>
C++11 模板改进
查看>>
C++11 基于范围的for循环
查看>>
Windows进程线程相关概念
查看>>
Windows创建进程
查看>>
Windows进程管理
查看>>
Windows进程通信——匿名管道
查看>>
MFC只运行一个实例窗口
查看>>
C++STL 仿函数
查看>>
Windows线程管理和调度机制概述
查看>>
Windows线程同步——临界区对象
查看>>
Leetcode——15. 3Sum
查看>>
Leetcode——18.4Sum
查看>>