检查是否达到指令

逆向工程 拆卸 勾搭
2021-07-06 03:00:54

我正在为 CTF 做一个挑战,我必须反转加密方案才能找到标志。然而,尝试所有输入会更容易,但它们太多了。

有一个指令,当到达时意味着我们已经猜到了当前的字母。如果在程序结束之前达到该断点以及次数,我如何检入脚本。

我曾尝试使用 gdb python 接口,但我发现它没有很好的文档记录。我尝试过 frida,但我无法连接到地址,只能连接到函数。并且 r2pipe 无法轻松地将文本发送到 stdin。

2个回答

简单的愚蠢方法:用无效的指令修补指令,如果程序崩溃,您就知道指令已被命中

您可以启动 gdb 并使用-x命令行标志使用 python 脚本对其进行初始化这可以subprocess在另一个 python 实例中使用启动这可以为您提供一种暴力破解的方法。

一些代码。驱动程序文件driver.py

import subprocess
import sys
rax = sys.argv[1]
d = subprocess.Popen("gdb -q -ex 'py rax = " + str(rax) + "' -x ./gdb_attach.py ", shell=True, stdout=subprocess.PIPE).stdout.read().strip()
print "Breakpoint hit ::: ", "HIT" in d
print d

在 gdb 中gdb_attach.py使用一些预定义示例偏移量评估的 Python 脚本请注意,我的 gdb 是使用 python3 支持构建的。

import gdb

class MyBreakpoint(gdb.Breakpoint):
    def stop (self):
        print("HIT")
        return True

gdb.execute('file ./x')
# gdb.execute("set environment LD_PRELOAD /home/sudhakar/tools/preeny/x86_64-linux-gnu/desleep.so")
MyBreakpoint("*0x40050b")
gdb.execute("run")
gdb.execute('set $rax=0x%x' % rax)
gdb.execute("continue")
gdb.execute('quit')

二进制文件是一个简单的是/否检查。

#include <stdio.h>

int dum(){
    return 0;
    }
int main(int argc, char **argv)
{
    if(dum()) puts("Yeaa!");
    else puts("No!");
    return 0;
}

偏移量看起来像这样。

[0x00400400]> pdf @ main
┌ (fcn) main 58
│   main (int argc, char **argv, char **envp);
│           ; var char **local_10h @ rbp-0x10
│           ; var int local_4h @ rbp-0x4
│           ; arg int argc @ rdi
│           ; arg char **argv @ rsi
│           ; DATA XREF from entry0 (0x40041d)
│           0x004004f2      55             push rbp
│           0x004004f3      4889e5         mov rbp, rsp
│           0x004004f6      4883ec10       sub rsp, 0x10
│           0x004004fa      897dfc         mov dword [local_4h], edi   ; argc
│           0x004004fd      488975f0       mov qword [local_10h], rsi  ; argv
│           0x00400501      b800000000     mov eax, 0
│           0x00400506      e8dcffffff     call sym.dum
│           0x0040050b      85c0           test eax, eax
│       ┌─< 0x0040050d      740c           je 0x40051b
│       │   0x0040050f      bfb4054000     mov edi, str.Yeaa           ; 0x4005b4 ; "Yeaa!" ; const char *s
│       │   0x00400514      e8d7feffff     call sym.imp.puts           ; int puts(const char *s)
│      ┌──< 0x00400519      eb0a           jmp 0x400525
│      ││   ; CODE XREF from main (0x40050d)
│      │└─> 0x0040051b      bfba054000     mov edi, 0x4005ba           ; const char *s
│      │    0x00400520      e8cbfeffff     call sym.imp.puts           ; int puts(const char *s)
│      │    ; CODE XREF from main (0x400519)
│      └──> 0x00400525      b800000000     mov eax, 0
│           0x0040052a      c9             leave
└           0x0040052b      c3             ret

驱动程序文件启动一个 gdb 实例gdb_attach.py可以使用-ex标志传递额外的 python 变量gdb_attach.py在偏移量处设置断点并更改某些值。您可以在命中 bp 时打印值并在主驱动程序脚本中解析它们。这很hackish,但它可以完成工作。

这是它的外观

$ python driver.py 0
Breakpoint hit ::: True
Breakpoint 1 at 0x40050b
HIT
Breakpoint 1, 0x000000000040050b in main ()
No!
[Inferior 1 (process 3874) exited normally]
$ python driver.py 1
Breakpoint hit ::: True
Breakpoint 1 at 0x40050b
HIT
Breakpoint 1, 0x000000000040050b in main ()
Yeaa!
[Inferior 1 (process 3947) exited normally]

了解我如何能够打印/检测命中断点并使用另一个 python 脚本更改二进制文件的流程。希望这可以帮助。