Live редактирование кода с помощью GDB - PullRequest
4 голосов
/ 24 февраля 2012

У меня нет большого опыта работы с GDB, поэтому я не уверен, возможно ли вообще то, что я спрашиваю, но возможно ли редактировать код в реальном времени с помощью GDB?

При запуске (после нажатияточка останова), disas выглядит так:

0x080487d8 <+9>:    movl   $0x80485e4,0x1c(%esp)
0x080487e0 <+17>:   movl   $0x8048640,0x20(%esp)
0x080487e8 <+25>:   movl   $0x804869c,0x24(%esp)
0x080487f0 <+33>:   movl   $0x8048719,0x28(%esp)

В попытке изменить адрес в одной из этих инструкций я сделал это:

set (*0x080487e1)=0x5b870408

Но вместо простого измененияКак я и ожидал, новые беды выглядели так:

0x080487d8 <+9>:    movl   $0x80485e4,0x1c(%esp)
0x080487e0 <+17>:   (bad)  
0x080487e1 <+18>:   or     %al,(%edi,%eax,4)
0x080487e4 <+21>:   pop    %ebx
0x080487e5 <+22>:   xchg   %al,(%eax,%ecx,1)
0x080487e8 <+25>:   movl   $0x804869c,0x24(%esp)
0x080487f0 <+33>:   movl   $0x8048719,0x28(%esp)

Итак, у меня есть 3 вопроса: возможно ли то, что я пытаюсь сделать?Если так, я делаю что-то не так?Если так, что я делаю не так и как я могу это исправить?

Ответы [ 2 ]

7 голосов
/ 24 февраля 2012

Возможно ли то, что я пытаюсь сделать?

Да, вы можете изменить .text двоичного файла.

Обратите внимание, что это изменение повлияет только на текущее выполнение;после run ваше изменение «испарится» (если вы хотите навсегда исправить бинарный файл, это тоже возможно, но процедура другая).

Если это так, я что-то не так делаю?

Вероятно.Вы не сказали нам, на что пытаетесь изменить инструкцию.

Если так, что я делаю не так и как я могу это исправить?

Использование(gdb) disas/r покажет вам фактические необработанные байты инструкции и, вероятно, облегчит вам понимание того, что вы сделали неправильно.Когда я использую его, я вижу это:

   0x080483ed <+9>: c7 44 24 1c d0 84 04 08 movl   $0x80484d0,0x1c(%esp)

То есть адрес (который вы, очевидно, хотели перезаписать) для инструкция выше [1] не начинается с &instruction+1 начинается с &instruction+4Кроме того, вы не должны обращать байты, когда просите GDB написать слово (я полагаю, вы хотели, чтобы новый адрес был 0x0804785b, а не 0x5b870408):

(gdb) set *(0x080483ed+4)=0x01020304
(gdb) disas
Dump of assembler code for function main:
   0x080483e4 <+0>: push   %ebp
   0x080483e5 <+1>: mov    %esp,%ebp
   0x080483e7 <+3>: and    $0xfffffff0,%esp
   0x080483ea <+6>: sub    $0x20,%esp
=> 0x080483ed <+9>: movl   $0x1020304,0x1c(%esp)
   0x080483f5 <+17>:    mov    0x1c(%esp),%eax
   0x080483f9 <+21>:    mov    %eax,(%esp)
   0x080483fc <+24>:    call   0x8048318 <puts@plt>
   0x08048401 <+29>:    mov    $0x0,%eax
   0x08048406 <+34>:    leave  
   0x08048407 <+35>:    ret    

[1] очень вероятно, что ваша инструкция:

0x080487e0 <+17>: movl   $0x8048640,0x20(%esp)

имеет ту же кодировку, что и моя инструкция:

0x080483ed  <+9>: movl   $0x80484d0,0x1c(%esp)

, поскольку они "одинаковые", и имеюттакой же длины в 8 байтов, но, как указал ФрэнкХ, может существовать другое кодирование одной и той же инструкции.В любом случае, disas/r покажет вам все, что вам нужно знать.

2 голосов
/ 24 февраля 2012

Во-первых, я никогда не использовал gdb для изменения текста программы, как вы, кажется, делаете.

Вы изменяете значение по адресу 0x080487e1, который находится перед счетчиком вашей программы.Эти значения являются машинным байт-кодом - например, кодировка для movl $ 0x8048640,0x20.

Что еще сложнее, так это то, что они имеют переменную длину в зависимости от инструкции, поэтому если вы испортили одну инструкцию, как вы, это изменит начальный адрес следующей инструкции, что означает, чтоинтерпретируется как другая инструкция .Это потому, что вы пишете между инструкциями.

Я не уверен, где вы получаете 0x080487e1 или что вы пытаетесь делать с ним.Если вы хотите изменить адрес, который movl использует в качестве первого параметра, вам нужно знать, как выглядит байт-код команды инструкции movl, а затем, возможно, заменить только ту часть, которая соответствует значению адреса.Но затем вы застреваете с тем, как заставить gdb записывать только определенные биты (инструкции даже не выровнены по битам).Звучит возможно, но сложно.

Возможно, вы пытаетесь перейти на другой адрес.Вы можете сделать это, перезаписав с помощью прыжка (имейте в виду, что это будет постоянное изменение на протяжении всей этой программы).Но применяются те же правила, что и для знания формата и поведения прыжков.

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