从编译的可执行文件或共享对象中只运行一个函数?

逆向工程 反编译 雷达2 仪器仪表
2021-06-26 07:49:52

Radare 让我可以查看函数的汇编代码和伪 C 代码。我可以在流程之外运行这些指令吗?也许自己设置寄存器?

如果是这样,我将如何做这件事?有这方面的指南或教程吗?

我是新手,我在想的是必须有某种易于设置的入口点,函数正在使用的寄存器,运行代码直到 aret然后看看发生了什么?

3个回答

我认为您正在寻找允许您模拟代码的 ESIL

专门aei用于初始化VM并将aeipPC设置为curekek。您可以使用列出寄存器aer并将它们设置为aer eax=1

您可以在此处此处找到更多信息

[0x00000000]> ae?
|Usage: ae[idesr?] [arg]ESIL code emulation
| ae [expr]                  evaluate ESIL expression
| ae?                        show this help
| ae??                       show ESIL help
| ae[aA][f] [count]          analyse esil accesses (regs, mem..)
| aec[?]                     continue until ^C
| aecs [sn]                  continue until syscall number
| aecu [addr]                continue until address
| aecue [esil]               continue until esil expression match
| aef [addr]                 emulate function
| aei                        initialize ESIL VM state (aei- to deinitialize)
| aeim [addr] [size] [name]  initialize ESIL VM stack (aeim- remove)
| aeip                       initialize ESIL program counter to curseek
| aek [query]                perform sdb query on ESIL.info
| aek-                       resets the ESIL.info sdb instance
| aep[?] [addr]              manage esil pin hooks
| aepc [addr]                change esil PC to this address
| aer [..]                   handle ESIL registers like 'ar' or 'dr' does
| aets[?]                    ESIL Trace session
| aes                        perform emulated debugger step
| aesp [X] [N]               evaluate N instr from offset X
| aesb                       step back
| aeso                       step over
| aesu [addr]                step until given address
| aesue [esil]               step until esil expression match
| aetr[esil]                 Convert an ESIL Expression to REIL
| aex [hex]                  evaluate opcode expression

正如您正确提到的,这是一个伪 C 代码,它输出类似 C 的代码。无法编译此代码,因为它不是有效的 C 代码。可以使用pdc命令显示此输出

radare2 包含用于反编译器的插件,如 Snowman 和 retdec。你可以在这里阅读更多关于它和我的回答使用这些反编译器,您很有可能成功编译生成的代码。一般情况下,不建议依赖反编译来实现与原始源代码1:1的结果。反编译非常复杂,极有可能失败并遗漏一些信息。

关于对寄存器进行更改——尽管它不是“在进程之外”,但您可以使用dr命令在radare 内部进行

例如,要将 EAX 更改为 0x20,您只需执行:

dr eax=0x20

如果您一般询问是否可以自己更改寄存器,答案是肯定的。只需将 ASM 代码插入到您的 C 程序中:

__asm {
  mov eax, 5
  add eax, 3
}

其他一些方法可能是:

  1. 使用 IDA 的AppCall功能。它并不是一个众所周知的特性(它应该是!)但 IDA 努力让您独立使用二进制文件中的函数。查看链接了解使用详情。
  2. 使用调试器。这可能不是您要问的,但您可以轻松提供寄存器值并执行函数,直到ret使用任何调试器指令
  3. 使用众多动态检测和仿真器之一,您可以模拟给定函数和状态(即寄存器等)的执行。angr就是这样一种工具。