Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何忽略某行二进制文件的执行?_C++_Assembly_Gdb_Cracking - Fatal编程技术网

C++ 如何忽略某行二进制文件的执行?

C++ 如何忽略某行二进制文件的执行?,c++,assembly,gdb,cracking,C++,Assembly,Gdb,Cracking,我想让我的程序在黑客面前更强大,所以我有一个program::validator类,它通过一些参数验证我的环境。一: 编译程序::验证程序共享库。 使用-O2和-ffast math编译程序,并链接到libprogramvalidator.so。 使用GDB运行程序。 查找实际调用program::validator::is\u valid\u系统的行。 我想知道我可以忽略这些行的执行吗?这是一种常见错误的另一种变体,这种错误认为你可以信任你的环境,即使你不能信任你的环境 您隐式地相信编译器是真

我想让我的程序在黑客面前更强大,所以我有一个program::validator类,它通过一些参数验证我的环境。一:

编译程序::验证程序共享库。 使用-O2和-ffast math编译程序,并链接到libprogramvalidator.so。 使用GDB运行程序。 查找实际调用program::validator::is\u valid\u系统的行。
我想知道我可以忽略这些行的执行吗?

这是一种常见错误的另一种变体,这种错误认为你可以信任你的环境,即使你不能信任你的环境

您隐式地相信编译器是真正的编译器,链接器是真正的链接器,GDB是真正的GDB,反汇编程序是真正的反汇编程序。您为黑客提供了攻击您的程序的不是一种而是四种方法

我只想避免调用ELF可执行二进制文件中的is_valid_系统函数

有几种简单的方法。您可以使用GDB jump$address或return命令来实现这一点。例如:

包括 int是有效的系统 { 返回0; } int main { 系统是否有效{ printfLife是好的\n; 返回0; } 检测到printfInvalid系统\n; 返回1; } 如您所见,运行上述程序将始终打印无效的系统,并以错误代码1退出。让我们确认一下:

gcc t.c && gdb -q ./a.out
(gdb) run
Starting program: /tmp/a.out 
Invalid system detected
[Inferior 1 (process 180727) exited with code 01]
好的,现在让我们让程序打印生活是好的。让我们通过返回来实现这一点。为此,请在所需函数上设置断点,将x86_64上的返回寄存器$rax设置为所需值,然后返回以强制函数立即返回:

(gdb) b is_valid_system
Breakpoint 1 at 0x1139
(gdb) run
Starting program: /tmp/a.out 

Breakpoint 1, 0x0000555555555139 in is_valid_system ()
(gdb) set $rax = 1
(gdb) return
#0  0x000055555555514e in main ()
(gdb) c
Continuing.
Life is good
[Inferior 1 (process 196141) exited normally]
或者,您可以跳过该函数。解除调用方的装配,中断调用指令,将返回寄存器设置为所需值,然后跳转到下一条指令:

(gdb) disas main
Dump of assembler code for function main:
   0x0000555555555140 <+0>:     push   %rbp
   0x0000555555555141 <+1>:     mov    %rsp,%rbp
   0x0000555555555144 <+4>:     mov    $0x0,%eax
   0x0000555555555149 <+9>:     callq  0x555555555135 <is_valid_system>
   0x000055555555514e <+14>:    test   %eax,%eax
   0x0000555555555150 <+16>:    je     0x555555555165 <main+37>
   0x0000555555555152 <+18>:    lea    0xeab(%rip),%rdi        # 0x555555556004
   0x0000555555555159 <+25>:    callq  0x555555555030 <puts@plt>
   0x000055555555515e <+30>:    mov    $0x0,%eax
   0x0000555555555163 <+35>:    jmp    0x555555555176 <main+54>
   0x0000555555555165 <+37>:    lea    0xea5(%rip),%rdi        # 0x555555556011
   0x000055555555516c <+44>:    callq  0x555555555030 <puts@plt>
   0x0000555555555171 <+49>:    mov    $0x1,%eax
   0x0000555555555176 <+54>:    pop    %rbp
   0x0000555555555177 <+55>:    retq   
End of assembler dump.
(gdb) b *0x0000555555555149
Breakpoint 2 at 0x555555555149
(gdb) run
Starting program: /tmp/a.out 

Breakpoint 2, 0x0000555555555149 in main ()
(gdb) set $rax = 1
(gdb) jump *0x000055555555514e
Continuing at 0x55555555514e.
Life is good
[Inferior 1 (process 205378) exited normally]

您还可以使用GDB临时或永久地修补is_valid_系统。详细信息,请参见。

是否要在正常执行期间或一次测试期间运行gdb并忽略该行?是的,您可以跳过指令并使用调试器更改寄存器。您也可以通过修补二进制文件本身来实现这一点。当您说忽略这些行的执行时,是否要避免执行调用is_valid_系统的整行,包括该行中任何表达式产生的任何其他副作用,或者你只是想避免执行“是否有效”系统?所述问题非常不清楚。“你到底想实现什么?”塞巴斯蒂安,是的。对不起,我不明白你的意思。哇,太好了。但我是用另一种方式做的。首先,我使用objdump转储二进制文件,找到检查系统验证并在该部分使用dd写入\x90的行,系统验证消失了。@Kate我链接到的另一个答案显示了如何使用GDB修补二进制文件,这比使用dd要容易一些。