Использование gdb для пошагового ассемблерного кода за пределами указанного исполняемого файла приводит к ошибке «не удается найти границы текущей функции» - PullRequest
78 голосов
/ 11 марта 2010

Я вне целевого исполняемого файла GDB, и у меня даже нет стека, соответствующего этой цели. В любом случае я хочу сделать один шаг, чтобы я мог проверить, что происходит в моем коде сборки, потому что я не являюсь экспертом в сборке x86. К сожалению, GDB отказывается делать эту простую отладку на уровне сборки. Это позволяет мне устанавливать и останавливаться на соответствующей точке останова, но как только я пытаюсь сделать шаг вперед, GDB сообщает об ошибке «Не удается найти границы текущей функции», и EIP не изменяется.

Дополнительные детали:

Машинный код был сгенерирован операторами gcc asm, и я скопировал его в область памяти ядра, где он выполняется, из вывода objdump -d. Я не возражаю против простого способа использовать загрузчик для загрузки моего объектного кода по перемещенному адресу, но имейте в виду, что загрузка должна выполняться в модуле ядра.

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

(Для тех, кто действительно хочет знать, я вставляю код во время выполнения в пространство данных ядра Linux внутри виртуальной машины VMware и отлаживаю его с помощью удаленной отладки gdb с помощью встроенной заглушки gdb рабочей станции VMware. Примечание. не пишу эксплойты ядра; я аспирант безопасности, пишу прототип.)

(Я могу установить точку останова для каждой инструкции в моей сборке. Это работает, но через некоторое время станет довольно трудоемким, поскольку размер сборочных инструкций x86 меняется, и расположение сборки будет меняться при каждой перезагрузке.)

Ответы [ 3 ]

140 голосов
/ 11 марта 2010

Вместо gdb, запустите gdbtui. Или запустите gdb с переключателем -tui. Или нажмите C-x C-a после ввода gdb. Теперь вы находитесь в режиме TUI GDB.

Введите layout asm, чтобы сделать сборку дисплея верхнего окна - это будет автоматически следовать за указателем вашей инструкции, хотя вы также можете изменять кадры или прокручивать их во время отладки. Нажмите C-x s , чтобы войти в режим SingleKey, где run continue up down finish и т. Д. Сокращены до одной клавиши, что позволяет очень быстро просматривать вашу программу.

   +---------------------------------------------------------------------------+
B+>|0x402670 <main>         push   %r15                                        |
   |0x402672 <main+2>       mov    %edi,%r15d                                  |
   |0x402675 <main+5>       push   %r14                                        |
   |0x402677 <main+7>       push   %r13                                        |
   |0x402679 <main+9>       mov    %rsi,%r13                                   |
   |0x40267c <main+12>      push   %r12                                        |
   |0x40267e <main+14>      push   %rbp                                        |
   |0x40267f <main+15>      push   %rbx                                        |
   |0x402680 <main+16>      sub    $0x438,%rsp                                 |
   |0x402687 <main+23>      mov    (%rsi),%rdi                                 |
   |0x40268a <main+26>      movq   $0x402a10,0x400(%rsp)                       |
   |0x402696 <main+38>      movq   $0x0,0x408(%rsp)                            |
   |0x4026a2 <main+50>      movq   $0x402510,0x410(%rsp)                       |
   +---------------------------------------------------------------------------+
<b>child process 21518 In: main                            Line: ??   PC: 0x402670</b>
(gdb) file /opt/j64-602/bin/jconsole
Reading symbols from /opt/j64-602/bin/jconsole...done.
(no debugging symbols found)...done.
(gdb) layout asm
(gdb) start
(gdb)
101 голосов
/ 11 марта 2010

Вы можете использовать stepi или nexti (который может быть сокращен до si или ni), чтобы пройти по вашему машинному коду.

23 голосов
/ 11 марта 2010

Самое полезное, что вы можете сделать здесь, это display/i $pc, прежде чем использовать stepi, как уже предложено в ответе Р. Самуэля Клатчко. Это говорит gdb разбирать текущую инструкцию перед каждой печатью приглашения; тогда вы можете просто нажать Enter, чтобы повторить команду stepi.

(см. мой ответ на другой вопрос для более подробной информации - контекст этого вопроса был другим, но принцип тот же.)

...