I want to make my program more strong in front of hackers, so i have a program::validator
class which validate my environment by some parameters. I :
program::validator
shared library.-O2
and --ffast-math
and link to libprogramvalidator.so
.program::validator::is_valid_system()
.and i want know that i can ignore execution of those line ?
i just want avoid call to is_valid_system function in my ELF executable binary file.
There are several easy ways. You can use GDB jump $address
, or return
commands to achieve this. Example:
#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;
}
As you can see, running above program will always print Invalid system
and exit with error code 1. Let's confirm that:
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]
Ok, now let's make the program print Life is good
. Let's do that via return
. To achieve that, set a breakpoint on the desired function, set return register ($rax
on x86_64
) to desired value, and return
to force the function to immediately 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]
Alternatively, you can "jump over" the function. Disasemble the caller, break on the CALL
instruction, set return register to desired value, and jump to next instruction:
(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]
You could also use GDB to temporarily or permanently patch the is_valid_system
out. Details in this answer.