修改 ELF 二进制文件中的 asm 指令

Modify asm instructions in an ELF binary

我有以下 ASM 代码,来自一个简单的混淆 C 程序,作为作业给我。

   0x00000000004006a0 <+147>:   lea    -0x20(%rbp),%rax
   0x00000000004006a4 <+151>:   mov    %rdx,%rsi
   0x00000000004006a7 <+154>:   mov    %rax,%rdi
   0x00000000004006aa <+157>:   callq  0x400713 <SECRET>   <======
   0x00000000004006af <+162>:   movl   [=10=]x0,-0x24(%rbp)
   0x00000000004006b6 <+169>:   jmp    0x4006d8 <main+203>
   0x00000000004006b8 <+171>:   mov    -0x24(%rbp),%eax

目标是找到并删除导致分段错误的函数(修补程序二进制文件)。我已经找到导致段错误的函数,但我不知道如何修补二进制文件。

我的问题是如何打补丁

 0x00000000004006aa <+157>:   callq  0x400713 <SECRET>

这样我就不会调用 SECRET 函数了。

如果我在 运行 时单步执行时通过修改程序计数器来使用 gdb 到 skip/jump SECRET,程序将完成执行并提供我想要的输出.

我想要的是可执行二进制文件的永久修改副本,它总是在不使用调试器的情况下跳过。

我很好奇 GDB 还能做什么。我设法用 GDB 更改了程序集,修补后的程序可以正常工作。

我尝试使用 nop 但它没有用,然后我寻找跳转函数。我的补丁是如何工作的:

(gdb) set {unsigned char *}0x4006aa = 0xEB
(gdb) set {unsigned char *}0x4006ab = 0x0C

我做的是跳远。 短跳转操作码是 EB XX 其中 XX 是相对于 IP/PC 的跳转。 所以在这种情况下,我必须向前跳转 12 个字节,指令也是 2 个字节,所以我将它写在连续的内存位置。我将新修改的二进制文件写入硬盘,一切都很好。

我花了一天的时间进行实验,但最后我学到了很多东西。 :D