Почему функция выполняется с того же адреса памяти каждый раз? - PullRequest
10 голосов
/ 31 марта 2010

Я разбираю исполняемый файл:

(gdb) disas main
Dump of assembler code for function main:
0x004012d0 <main+0>:    push   %ebp
0x004012d1 <main+1>:    mov    %esp,%ebp
...

Каждый раз адрес памяти один и тот же: 0x004012d0.

Разве адрес памяти не назначается динамически ОС?

UPDATE

Теперь я вижу, что это виртуальное пространство, и оно может быть случайным на некоторых платформах.

Может кто-нибудь опубликовать дамп gdb, который меняется?

Ответы [ 8 ]

3 голосов
/ 31 марта 2010

Это зависит от ОС.Большую часть времени адрес двоичного файла остается неизменным.Это важно для использования ошибок манипулирования памятью, таких как переполнения буфера .Адрес связанных библиотек в Linux всегда будет другим из-за ASLR.В Windows Vista и Windows 7 пространство виртуальной памяти двоичного файла также рандомизируется при каждом запуске, поэтому адрес функции будет отличаться для каждого запуска.

3 голосов
/ 01 апреля 2010

Я думаю, что проблема здесь (по крайней мере в Linux) может быть в том, что GDB пытается помочь из документации:

установить отключение-рандомизация

установить отключение-рандомизацию на

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

Эта функция реализована только в GNU / Linux. Вы можете получить то же поведение, используя

         (gdb) set exec-wrapper setarch `uname -m` -R

http://sourceware.org/gdb/current/onlinedocs/gdb/Starting.html

ОБНОВЛЕНИЕ: Сейчас я проверил это, и мне кажется, что это действительно так (на Linux 2.6.28). Скомпилируйте простую программу Hello World и запустите gdb без аргументов командной строки (мы не хотим загружать программу до переопределения параметра disable-randomization) и затем введите:

(gdb) set disable-randomization off
(gdb) file ./a.out
(gdb) break main
(gdb) run
(gdb) disas printf

Адрес printf отличается при каждом запуске программы.

2 голосов
/ 31 марта 2010

Перемещение исполняемых файлов

Некоторые исполняемые файлы установлены так, что они всегда загружаются по одному и тому же адресу. Некоторые настроены так, что они «перемещаемы». Опция, управляющая этим в компоновщике Visual Studio, называется / FIXED. Даже такие исполняемые файлы чаще всего загружаются по предпочтительному адресу. Более новые ОС (Win7, Vista) рандомизируют адрес загрузки для некоторых исполняемых файлов для повышения безопасности (процесс атаки, загруженный по неизвестному адресу, сложнее) - это называется ASLR . Примечание. Даже исполняемый файл, помеченный как / FIXED: NO, как предполагается, не подходит для ASLR. Разработчик должен явно разрешить ASLR для исполняемого файла.

Виртуальное адресное пространство

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

2 голосов
/ 31 марта 2010

Да и нет. Физическая память выделяется ОС, и только ОС знает, где находится ваша программа в физической памяти. Ваша программа видит только виртуальный адрес, который всегда будет одинаковым, если все загружено в одном и том же порядке.

1 голос
/ 31 марта 2010

Это виртуальный адрес. Физический адрес известен ОС, но каждый процесс имеет свое собственное виртуальное адресное пространство. Перемещаемый образ, вероятно, будет получать одно и то же отображение каждый раз, особенно основной исполняемый файл. Но это не гарантировано. Пример - библиотеки DLL. Библиотеки DLL могут загружаться в разном порядке, что приводит к различным виртуальным адресам между запусками, потому что, поскольку DLL 1 загружается, DLL 2 не может быть загружена в этот виртуальный адрес и должна получить свой собственный адрес.

0 голосов
/ 13 октября 2011

Это термины из компьютерной безопасности. В прошлом это был фиксированный адрес (<1996, согласно <a href="https://lkml.org/lkml/2010/11/30/110" rel="nofollow"> LKML , но только недавно исполняемый начал компилироваться как перемещаемый, чтобы реализовать ASLR . (Но очень давно все библиотеки были скомпилированы как перемещаемые, так что библиотеки могут быть перезагружены по разным адресам, если необходимо - читайте динамическое перемещение , но из-за порядка загрузки эти основные API syscall обычно загружаются в фиксированный адрес. ) Даже сегодня

выполнив команду gdb / bin / ls и выполнив "run", вы обнаружите, что адрес по умолчанию не изменился:

(gdb) разбирать __open Дамп кода ассемблера для открытой функции: 0xb7f017f0 <+0>: cmpl $ 0x0,% gs: 0xc 0xb7f017f8 <+8>: jne 0xb7f0181c

В любом случае ASLR создается с PaX - прочитайте вики, в нем много говорится о требованиях реализации ASLR.

Почему ASLR? Чтобы предотвратить 2 типа атак: http://en.wikipedia.org/wiki/Return-to-libc_attack и http://en.wikipedia.org/wiki/Return-oriented_programming,, потому что обе атаки приняли вашу область кода, если зафиксированы в памяти.

0 голосов
/ 31 марта 2010

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

0 голосов
/ 31 марта 2010

Почему ОС выбирает другой адрес?

Когда ОС выполняет процесс, она загружает исполняемый файл в пространство виртуальной памяти. Попутно он разрешит любые относительные и / или символические ссылки. Предполагая, что у вас есть тот же исполняемый файл и те же общие библиотеки, и вы запускаете его так же, как вы делали это в прошлый раз, ОС будет очень странно принять решение загрузить исполняемый файл в другой способ.

...