Вот один из способов сделать это.
Для иллюстрации предположим, что программа имеет вид:
#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;
}
Я скомпилирую ее с gcc -O3 -fno-inline t.c
и наблюдаю эту разборку в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.
Предположим также, что искомое возвращаемое значение равно 125
.
Первый шаг - установить условную точку останова в инструкции retq
:
(gdb) b *0x00005555555551a6 if $rax == 125
Breakpoint 2 at 0x5555555551a6
Теперь давайте вызовем hash()
в цикле:
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
Итак, вызов hash(1250)
дает желаемое значение.
QED.