Как вы выполняете функцию в gdb с различными входами, пока не получите успешное возвращаемое значение - PullRequest
1 голос
/ 25 октября 2019

Я работаю над проектом бомбы, это означает, что мне нужно определить правильные входные данные для программы, но у меня нет доступа к исходному коду.

В настоящее время я пытаюсь выяснитьКак получить функцию с именем func4 для вывода 1. func4 принимает только один целочисленный аргумент. Я изучил инструкции по сборке для этой функции, но похоже, что func4 - это какая-то хеш-функция, из-за которой было бы очень больно пытаться вернуться к правильному вводу.

Есть ли способ, которым яможно запустить func4 несколько раз, пока я использую GDB? Я хотел бы повторять функцию со входами 1240, 1241, 1242 и т. Д. До тех пор, пока не достигну определенной точки прерывания (что означает, что ввод был правильным).

1 Ответ

2 голосов
/ 25 октября 2019

Вот один из способов сделать это.

Для иллюстрации предположим, что программа имеет вид:

#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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...