Використання gdb для одноетапного коду збірки поза вказаним виконуваним файлом викликає помилку "не вдається знайти межі поточної функції"


86

Я перебуваю поза цільовим виконуваним файлом gdb, і у мене навіть немає стека, який відповідає цій цілі. Я все одно хочу зробити крок, щоб я міг перевірити, що відбувається в моєму коді збірки, оскільки я не фахівець у збірці x86. На жаль, gdb відмовляється виконувати цю просту налагодження на рівні збірки. Це дозволяє мені встановити та зупинити відповідну точку зупинки, але як тільки я спробую зробити крок далі, gdb повідомляє про помилку "Не вдається знайти межі поточної функції", і EIP не змінюється.

Додаткові деталі:

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

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

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

(Я можу встановити точку зупинки для кожної інструкції всередині моєї збірки. Це працює, але через деякий час це стане досить трудомістким, оскільки розмір інструкцій з монтажу x86 змінюється, і розташування збірки змінюватиметься при кожному перезавантаженні.)


Розумні ksplice.com люди INJECT даних і коду в ядро по збірці «підроблені» модулі ядра і завантажувати їх. І якщо вони можуть це зробити, чому ви не можете? ;-)
ефемієнт

Відповіді:


116

Ви можете використовувати stepiабо nexti(що може бути скорочено до siабо ni) для переходу до свого машинного коду.


1
Ого. В ретроспективі я не знаю, як я забув про степі. Я припускаю, що я просто припустив, оскільки gdb не мав вихідного коду, і цей крок повернеться до інструкцій з монтажу.
Пол

1
Примітка: Ви часто не можете ввести "break main", "run" для програм збірки. Натомість введіть "layout asm", "start". Я зрозумів це, прочитавши повідомлення нижче, але хтось, хто читає цей пост, може бути не таким терплячим.
Дмитро

1
@Dmitry startеквівалентно, за tbreak mainяким слід run(примітка: tbreakзамість break)
Руслан

151

Замість gdb, біжи gdbtui. Або бігайте gdbз -tuiперемикачем. Або натисніть C-x C-aпісля входу gdb. Тепер ви перебуваєте в режимі TUI GDB .

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

   + ------------------------------------------------- -------------------------- +
B +> | 0x402670 <головне> натиснути% 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> під $ 0x438,% rsp |
   | 0x402687 <main + 23> mov (% rsi),% rdi |
   | 0x40268a <основний + 26> movq $ 0x402a10,0x400 (% rsp) |
   | 0x402696 <основний + 38> movq 0x0,0x408 $ (% rsp) |
   | 0x4026a2 <основний + 50> movq $ 0x402510,0x410 (% rsp) |
   + ------------------------------------------------- -------------------------- +
дочірній процес 21518 В: основна лінія: ?? ПК: 0x402670
(gdb) file / opt / j64-602 / bin / jconsole
Читання символів з /opt/j64-602/bin/jconsole...done.
(символів налагодження не знайдено) ... зроблено.
(gdb) макет asm
(gdb) старт
(ГДБ)

26

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

(Див. Мою відповідь на інше запитання для більш детальної інформації - контекст цього питання був іншим, але принцип той самий.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.