2012-01-23 4 views
5

Я сделал две программы на С, которые были точной копией друг друга. Скомпилировали их на платформе Linux (Ubuntu 10.04) с использованием gcc-компилятора и получили два отдельных исполняемых файла. Затем я получил сборку код обоих исполняемых файлов с использованием objdump и обнаружил, что код сборки был точно таким же и даже адрес соответствующих инструкций в двух файлах сборки был таким же. Программа должна была напечатать адрес переменной в нем. Программы при запуске создают другой адрес и, кроме того, одна и та же программа создает другой адрес при каждом запуске. Кодирование строк кода одинаково в двух программах, но адрес переменной изменяется даже для одной и той же программы каждый раз, когда она выполняется. Я думаю, что адрес, напечатанный переменной на экран является виртуальным адресом, но если его виртуальный, почему он не может быть таким же каждый раз. Является адресом, указанным в коде сборки, полученном objd ump также является виртуальным?Почему адрес переменной продолжает меняться между прогонами

+0

Практически все видимые адреса являются виртуальными в современных ЦП + ОС. Кроме того, адрес не обязательно должен быть таким же, потому что для большинства языков программирования нет необходимости. –

ответ

5

Это связано с address space layout randomization.

Цитирую Википедию:

Адрес раскладка пространство рандомизации (ASLR) является метод компьютерной безопасности, который включает в себя случайным образом устраивая позиции ключевых областей данных, как правило, в том числе основания исполняемым и положение библиотек, кучи , и стек, в адресном пространстве процесса.

Преимущества

адресного пространства рандомизации препятствует некоторые типы атак, делая его более трудным для атакующего предсказать целевые адреса. Например, злоумышленники, пытающиеся выполнить атаки return-to-libc, должны найти код, который должен быть выполнен, тогда как другие злоумышленники, пытающиеся выполнить shellcode, введенные в стек, должны сначала найти стек. В обоих случаях соответствующие адреса памяти скрыты от злоумышленников. Эти значения следует угадать, и ошибочное предположение обычно не восстанавливается из-за сбоя приложения.

Например, когда я повторно запустить тот же исполняемый файл, полученный из следующего кода C на моей Ubuntu 10.10 коробке:

#include <stdio.h> 

int g = 0; 

int main() { 
    int x = 0; 
    printf("%p %p\n", &x, &g); 
} 

адрес локальной переменной (x) постоянно меняется, но адрес глобальной переменной (g) остается неизменной.

+0

Можете ли вы объяснить, почему адрес глобальной переменной остается прежним? Когда мы произвольно меняем адреса ключевых областей данных. Это также изменит диапазон адресов раздела «данные» в виртуальной памяти процесса, который содержит эту глобальную переменную. – user3834119

1

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

Смежные вопросы