Ваш код, скорее всего, был скомпилирован как Позиционно-независимый исполняемый файл (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) в целом (что крайне важно для разделяемых библиотек), посмотрите на статью Ульриха Дреппера «Как писать общие библиотеки» .