CTF场景下如何使用GDB调用可执行文件中带参数的函数
解决方案
先确认参数匹配规则
从给出的反编译代码可知,flag函数的参数校验逻辑为:
if ((param_1 == -0x21524111) && (param_2 == -0x3f212ff3))
两个参数在32位有符号整型体系下对应常用魔数,两种写法都可正常匹配:
- param_1:
-0x21524111= 无符号32位值0xDEADBEEF - param_2:
-0x3f212ff3= 无符号32位值0xC0DED00D
不需要通过BOF攻击,直接在GDB中即可正确调用带参数的flag函数,你之前调用失败大概率是参数格式错误,或者调用时机不对。
GDB调用带参函数的两种可行方法
方法1:使用call命令(最简单)
操作步骤:
- 加载目标程序:
gdb ./vuln - 在main函数入口打断点,等待程序完成基础初始化后再执行调用,避免触发异常:
b main run
- 直接调用flag函数,传入符合要求的参数即可:
# 直接传入反编译给出的负十六进制值 call flag(-0x21524111, -0x3f212ff3) # 也可以传入对应无符号十六进制魔数 call flag(0xdeadbeef, 0xc0ded00d)
本地测试时请先在当前目录创建flag.txt写入测试内容,否则会触发fopen失败分支,程序直接输出提示后退出。
方法2:手动设置寄存器/栈后跳转(全场景兼容)
如果call命令存在兼容性问题,可以手动模拟函数传参规则后跳转执行:
32位程序(参数通过栈传递)
- 先通过
disass flag查看flag函数的反汇编,找到ret指令的地址,在该位置打个断点,避免执行完flag后程序崩溃:
b *<flag函数ret指令的地址>
- 按从右到左的顺序压入参数和返回地址:
# 压第二个参数param_2 set $esp -= 4 set *(int *)$esp = -0x3f212ff3 # 压第一个参数param_1 set $esp -=4 set *(int *)$esp = -0x21524111 # 压入返回地址,填刚才打ret断点的地址即可 set $esp -=4 set *(int *)$esp = <ret断点的地址>
- 跳转执行flag函数:
jump *flag
64位程序(前两个参数通过rdi、rsi寄存器传递)
- 同样先在flag函数的ret位置打个断点
- 直接设置参数寄存器:
set $rdi = -0x21524111 set $rsi = -0x3f212ff3
- 跳转执行:
jump *flag
内容的提问来源于stack exchange,提问作者Jenny Patel
相关产品推荐
相关产品推荐

