Невозможно вставить точки останова.Адрес с низкими значениями - PullRequest
0 голосов
/ 12 июня 2018

Я пытаюсь отладить эту простую программу на C:

#include <stdio.h>
int main(int argc, char *argv[]) {
    printf("Hello\n");
}

Но когда я разбираю основную функцию, я получаю это:

(gdb) disas main
Dump of assembler code for function main:
    0x000000000000063a <+0>:    push   rbp
    0x000000000000063b <+1>:    mov    rbp,rsp
    0x000000000000063e <+4>:    sub    rsp,0x10
    0x0000000000000642 <+8>:    mov    DWORD PTR [rbp-0x4],edi
    0x0000000000000645 <+11>:   mov    QWORD PTR [rbp-0x10],rsi
    0x0000000000000649 <+15>:   lea    rdi,[rip+0x94]        # 0x6e4
    0x0000000000000650 <+22>:   call   0x510 <puts@plt>
    0x0000000000000655 <+27>:   mov    eax,0x0
    0x000000000000065a <+32>:   leave  
    0x000000000000065b <+33>:   ret    
End of assembler dump.

И это уже довольно странно, потому чтоя думаю, что адреса начинаются с префикса 4 ... для 32-битных исполняемых файлов и 8 ... для 64-битных исполняемых файлов.

Но затем я ставлю точку останова:

(gdb) b *0x0000000000000650
Breakpoint 1 at 0x650

Я запускаю его и получаю сообщение об ошибке:

Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x650

1 Ответ

0 голосов
/ 12 июня 2018

Ваш код, скорее всего, был скомпилирован как Позиционно-независимый исполняемый файл (PIE) , чтобы разрешить Рандомизация размещения адресного пространства (ASLR) .В некоторых системах gcc по умолчанию настроен на создание PIE (что подразумевает передачу параметров -pie -fPIE в gcc).

Когда вы запускаете GDB для отладки PIE, он начинает читать адреса с 0,поскольку ваш исполняемый файл еще не был запущен , но еще , и поэтому не перемещен (в PIE все адреса, включая раздел .text, можно перемещать, и они начинаются с 0, подобно динамическому общему объекту).Это пример вывода:

$ gcc -o prog main.c -pie -fPIE
$ gdb -q prog
Reading symbols from prog...(no debugging symbols found)...done.
gdb-peda$ disassemble main
Dump of assembler code for function main:
   0x000000000000071a <+0>:     push   rbp
   0x000000000000071b <+1>:     mov    rbp,rsp
   0x000000000000071e <+4>:     sub    rsp,0x10
   0x0000000000000722 <+8>:     mov    DWORD PTR [rbp-0x4],edi
   0x0000000000000725 <+11>:    mov    QWORD PTR [rbp-0x10],rsi
   0x0000000000000729 <+15>:    lea    rdi,[rip+0x94]        # 0x7c4
   0x0000000000000730 <+22>:    call   0x5d0 <puts@plt>
   0x0000000000000735 <+27>:    mov    eax,0x0
   0x000000000000073a <+32>:    leave
   0x000000000000073b <+33>:    ret
End of assembler dump.

Как вы можете видеть, это показывает аналогичный вывод с .text адресами, начинающимися с низких значений.

Перемещение происходит после запускаваш исполняемый файл, поэтому после этого ваш код будет размещен по некоторому случайному адресу в памяти вашего процесса:

gdb-peda$ start
...
gdb-peda$ disassemble main
Dump of assembler code for function main:
   0x00002b1c8f17271a <+0>:     push   rbp
   0x00002b1c8f17271b <+1>:     mov    rbp,rsp
=> 0x00002b1c8f17271e <+4>:     sub    rsp,0x10
   0x00002b1c8f172722 <+8>:     mov    DWORD PTR [rbp-0x4],edi
   0x00002b1c8f172725 <+11>:    mov    QWORD PTR [rbp-0x10],rsi
   0x00002b1c8f172729 <+15>:    lea    rdi,[rip+0x94]        # 0x2b1c8f1727c4
   0x00002b1c8f172730 <+22>:    call   0x2b1c8f1725d0 <puts@plt>
   0x00002b1c8f172735 <+27>:    mov    eax,0x0
   0x00002b1c8f17273a <+32>:    leave
   0x00002b1c8f17273b <+33>:    ret
End of assembler dump.

Как вы можете видеть, адреса теперь принимают "реальные" значения, для которых вы можете установить точки останова.Обратите внимание, что обычно вы все равно не увидите эффекта ASLR в GDB, поскольку он по умолчанию отключает рандомизацию (отладка программы со случайным расположением будет громоздкой).Вы можете проверить это с помощью show disable-randomization.Если вы действительно хотите увидеть эффект ASLR в вашем пироге, set disable-randomization off.Затем каждый прогон будет перемещать ваш код на случайные адреса.

Итак, суть в следующем: при отладке кода PIE start ваша программа сначала в GDB , а затем вычисляет адреса.

Кроме того, вы можете явно отключить создание кода PIE и скомпилировать ваше приложение, используя gcc filename.c -o filename -no-pie -fno-PIE.Моя система не обеспечивает создание PIE по умолчанию, поэтому, к сожалению, я не знаю о последствиях отключения PIE для такой системы (был бы рад видеть комментарии по этому поводу).

Для более подробного объясненияпозиционно-независимый код (PIC) в целом (что крайне важно для разделяемых библиотек), посмотрите на статью Ульриха Дреппера «Как писать общие библиотеки» .

...