如何忽略某行二进制文件的执行?
How to ignore execution of some line of binary file?
我想让我的程序在黑客面前更强大,所以我有一个 program::validator
class 可以通过一些参数验证我的环境。我:
- 编译
program::validator
共享库。
- 使用
-O2
和--ffast-math
和link编译程序到libprogramvalidator.so
。
- 运行用GDB的程序。
- 找到实际调用
program::validator::is_valid_system()
的行。
我想知道我可以忽略那些行的执行吗?
这是常见错误 "Thinking that you can trust your environment, even when you cannot trust your environment" 的另一种变体。
您隐含地相信编译器是真正的编译器,链接器是真正的链接器,GDB 是真正的 GDB,反汇编器是真正的反汇编器。您为黑客提供了四种而不是一种方式来攻击您的程序。
i just want avoid call to is_valid_system function in my ELF executable binary file.
有几种简单的方法。您可以使用 GDB jump $address
或 return
命令来实现此目的。示例:
#include <stdio.h>
int is_valid_system()
{
return 0;
}
int main()
{
if (is_valid_system()) {
printf("Life is good\n");
return 0;
}
printf("Invalid system detected\n");
return 1;
}
如您所见,运行 上面的程序将始终打印 Invalid system
并以错误代码 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]
好的,现在让程序打印Life is good
。让我们通过 return
做到这一点。为此,在所需函数上设置断点,将 return 寄存器(x86_64
上的 $rax
)设置为所需值,并 return
强制函数立即 return:
(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]
或者,您可以 "jump over" 该函数。反汇编调用程序,中断 CALL
指令,将 return 寄存器设置为所需值,然后跳转到下一条指令:
(gdb) disas main
Dump of assembler code for function main:
0x0000555555555140 <+0>: push %rbp
0x0000555555555141 <+1>: mov %rsp,%rbp
0x0000555555555144 <+4>: mov [=13=]x0,%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 [=13=]x0,%eax
0x0000555555555163 <+35>: jmp 0x555555555176 <main+54>
0x0000555555555165 <+37>: lea 0xea5(%rip),%rdi # 0x555555556011
0x000055555555516c <+44>: callq 0x555555555030 <puts@plt>
0x0000555555555171 <+49>: mov [=13=]x1,%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_system
。 this answer.
中的详细信息
我想让我的程序在黑客面前更强大,所以我有一个 program::validator
class 可以通过一些参数验证我的环境。我:
- 编译
program::validator
共享库。 - 使用
-O2
和--ffast-math
和link编译程序到libprogramvalidator.so
。 - 运行用GDB的程序。
- 找到实际调用
program::validator::is_valid_system()
的行。
我想知道我可以忽略那些行的执行吗?
这是常见错误 "Thinking that you can trust your environment, even when you cannot trust your environment" 的另一种变体。
您隐含地相信编译器是真正的编译器,链接器是真正的链接器,GDB 是真正的 GDB,反汇编器是真正的反汇编器。您为黑客提供了四种而不是一种方式来攻击您的程序。
i just want avoid call to is_valid_system function in my ELF executable binary file.
有几种简单的方法。您可以使用 GDB jump $address
或 return
命令来实现此目的。示例:
#include <stdio.h>
int is_valid_system()
{
return 0;
}
int main()
{
if (is_valid_system()) {
printf("Life is good\n");
return 0;
}
printf("Invalid system detected\n");
return 1;
}
如您所见,运行 上面的程序将始终打印 Invalid system
并以错误代码 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]
好的,现在让程序打印Life is good
。让我们通过 return
做到这一点。为此,在所需函数上设置断点,将 return 寄存器(x86_64
上的 $rax
)设置为所需值,并 return
强制函数立即 return:
(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]
或者,您可以 "jump over" 该函数。反汇编调用程序,中断 CALL
指令,将 return 寄存器设置为所需值,然后跳转到下一条指令:
(gdb) disas main
Dump of assembler code for function main:
0x0000555555555140 <+0>: push %rbp
0x0000555555555141 <+1>: mov %rsp,%rbp
0x0000555555555144 <+4>: mov [=13=]x0,%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 [=13=]x0,%eax
0x0000555555555163 <+35>: jmp 0x555555555176 <main+54>
0x0000555555555165 <+37>: lea 0xea5(%rip),%rdi # 0x555555556011
0x000055555555516c <+44>: callq 0x555555555030 <puts@plt>
0x0000555555555171 <+49>: mov [=13=]x1,%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_system
。 this answer.