You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在GDB中调试逆向C编译程序fopen调用的技术咨询

处理GDB中fopen调用的实用技巧

针对你逆向的这个C程序——它尝试打开无权限的/home/user00/.pass并检查返回值的场景,我整理了几个在GDB里处理这个fopen调用的常用方法,帮你绕过权限限制或者调试后续逻辑:

1. 修改fopen返回值,直接绕过权限检查

从你给出的汇编代码来看,程序会把fopen的返回值(存在rax寄存器里)存入[rbp-0x8],然后和0比较,非0就跳转到成功分支。我们可以手动篡改这个返回值:

  • 先在fopen调用后的存值指令处设断点:
    b *0x4008ad
    
  • 运行程序到断点:r
  • 此时fopen已经执行完毕,你可以直接修改rax为一个非0值(随便一个有效指针地址就行,只要能触发跳转):
    set $rax = 0x12345678
    
  • 或者直接修改栈上存储返回值的位置:
    set *(long long)$rbp-0x8 = 0x1
    
  • 最后继续执行:c,程序就会进入成功分支的逻辑。

2. 替换目标文件路径,让程序读取你有权限的文件

如果你想让程序正常读取内容而非单纯绕过检查,可以用GDB的路径替换功能:

  • 先准备一个你有权限访问的测试文件,比如/tmp/my_test_pass,随便写入一些测试内容
  • 在GDB里设置路径替换规则:
    set substitute-path /home/user00/.pass /tmp/my_test_pass
    
  • 运行程序,fopen会自动去打开你指定的替代文件,这样就能正常执行后续的读取逻辑。

3. Hook fopen函数,自定义参数或返回值

你可以直接在fopen函数被调用时拦截,修改传入的参数或者强制返回自定义值:

  • 给fopen设函数断点:
    b fopen
    
  • 运行到断点后,查看当前传入的参数(x86_64下第一个参数存在rdi,第二个在rsi):
    info args
    
  • 如果你想修改要打开的文件名,直接修改rdi寄存器:
    set $rdi = "/tmp/my_test_pass"
    
  • 然后继续执行fopen:c,程序就会打开你指定的文件
  • 或者直接跳过fopen的实际调用,手动返回一个非0指针:
    return 0xdeadbeef
    
    这样程序会直接从fopen返回,使用你设置的指针值。

4. 强制跳转到成功分支,跳过权限检查逻辑

从汇编代码看,0x4008b6处的jne指令会在返回值非0时跳转到成功分支0x4008e6。我们可以直接强制跳转或者修改指令:

  • 方法一:在cmp指令处设断点,然后强制跳转到成功分支:
    b *0x4008b1
    r
    jump *0x4008e6
    
  • 方法二:修改jne指令为无条件跳转jmp,让程序不管返回值如何都进入成功分支:
    set *(unsigned char *)0x4008b6 = 0xeb
    
    (注:jne的机器码是0x75,短跳转jmp的机器码是0xeb,修改后程序每次都会执行成功分支)

内容的提问来源于stack exchange,提问作者LotoLo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:51:05