I am working on a bomb project, meaning that I need to figure out the correct inputs for a program, but I don't have access to the original code.
Currently, I am trying to figure out how to get a function called func4
to output a 1. func4
only takes in a single integer argument. I have examined the assembly instructions for this function, but it looks like func4
is some kind of hash function, which would make it very painful to try and backtrack to the correct input.
Is there some way I can run func4
repeatedly while I'm using gdb? I would like to iterate the function with inputs 1240, 1241, 1242, and so on until I reach a certain break point (meaning that the input was correct).
Here is one way to do it.
For illustration purpose, let's assume that the program is:
#include <stdio.h>
int hash(unsigned int x) {
return ((x << 20) % 191) | (x % 57);
}
int main()
{
int j = 1;
printf("%d: %d\n", j, hash(j));
return 0;
}
I compile it with gcc -O3 -fno-inline t.c
, and observe this disassembly in GDB:
gdb -q ./a.out
Reading symbols from ./a.out...
(gdb) start
Temporary breakpoint 1 at 0x1050
Starting program: /tmp/a.out
Temporary breakpoint 1, 0x0000555555555050 in main ()
(gdb) disas hash
Dump of assembler code for function hash:
0x0000555555555170 <+0>: mov %edi,%ecx
0x0000555555555172 <+2>: mov $0xab8f69e3,%edx
0x0000555555555177 <+7>: shl $0x14,%ecx
0x000055555555517a <+10>: mov %ecx,%eax
0x000055555555517c <+12>: mul %edx
0x000055555555517e <+14>: mov %edi,%eax
0x0000555555555180 <+16>: shr $0x7,%edx
0x0000555555555183 <+19>: imul $0xbf,%edx,%edx
0x0000555555555189 <+25>: sub %edx,%ecx
0x000055555555518b <+27>: mov $0x1f7047dd,%edx
0x0000555555555190 <+32>: mul %edx
0x0000555555555192 <+34>: mov %edi,%eax
0x0000555555555194 <+36>: sub %edx,%eax
0x0000555555555196 <+38>: shr %eax
0x0000555555555198 <+40>: add %eax,%edx
0x000055555555519a <+42>: mov %ecx,%eax
0x000055555555519c <+44>: shr $0x5,%edx
0x000055555555519f <+47>: imul $0x39,%edx,%edx
0x00005555555551a2 <+50>: sub %edx,%edi
0x00005555555551a4 <+52>: or %edi,%eax
0x00005555555551a6 <+54>: retq
End of assembler dump.
Let's also assume that the return value I am looking for is 125
.
The first step is to set a conditional breakpoint on the retq
instruction:
(gdb) b *0x00005555555551a6 if $rax == 125
Breakpoint 2 at 0x5555555551a6
Now let's call hash()
in a loop:
set $j = 1240
while $j < 1260
> call (int)hash($j++)
> end
$1 = 63
$2 = 47
$3 = 189
$4 = 174
$5 = 191
$6 = 190
$7 = 177
$8 = 114
$9 = 119
$10 = 118
Breakpoint 2, 0x00005555555551a6 in hash ()
The program being debugged stopped while in a function called from GDB.
Evaluation of the expression containing the function
(hash) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb) p $j
$11 = 1251
So, calling hash(1250)
produces the desired value.
QED.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments