Выделение памяти в x86-64 - PullRequest
       36

Выделение памяти в x86-64

0 голосов
/ 26 февраля 2019

Я просто хочу прояснить для себя вопрос о распределении памяти (если это так, как я могу назвать это правильно) в c на архитектуре x64.

У меня есть одна программа, которая просто выводит местоположение переменной в памяти.Я запускаю его несколько раз, а затем вижу странную вещь:

Строка кода:

printf("[*] test_val @ 0x%016llx = %d 0x%016llx\n", &test_val, test_val, test_val);

1-й раз:

[*] test_val @ 0x00005612f1edb050 = -72 0x00000000ffffffb8

2-й раз:

[*] test_val @ 0x000055ec3b64f050 = -72 0x00000000ffffffb8

3-й раз:

[*] test_val @ 0x00005577e99d4050 = -72 0x00000000ffffffb8

Кажется, что место в памяти переменной test_int отличается каждый раз, за ​​исключением первых 2,5 бит (00005) и последних 1,5биты (часть 050 не изменяется).

Не было бы никаких вопросов, но в книге, которую я изучаю по этому адресу, постоянно все время.Основное отличие состоит в том, что эта книга о 32-битной архитектуре.

Правильно ли я понимаю, что память распределяется динамически в системах x64?Есть ли способ «предсказать», где будет переменная, учитывая тот факт, что мы знаем последние 1,5 бита, в данном случае 050?

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

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

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

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

0 голосов
/ 26 февраля 2019

Не было бы никаких вопросов, но в книге, которую я изучаю по этому адресу, постоянно все время.

Если эта книга на самом деле заявляла , что адреса должны оставаться постоянными в течение нескольких запусков одной и той же программы, это было неправильно.Фактически, даже во время одного и того же запуска одной программы локальные переменные с автоматической продолжительностью хранения могут получать разные адреса при нескольких вызовах в одном и том же запущенном экземпляре.Рассмотрим:

void foo()
{
    volatile int a = 12345;
    printf("%p\n", (void *)&a);
}
void bar()
{
    printf("In bar\n");
    foo();
}
int main()
{
    foo();
    bar();
    return 0;
}

Я получаю вывод:

00B6FE58
In bar
00B6FE54

Это потому, что вызов bar создает другой кадр в стеке при вводе foo, давая a другой адрес.В общем, единственное, что можно рассуждать безопасно, это то, что если переменная имеет статическую длительность хранения, ее адрес должен оставаться постоянным в течение однократного запуска программы.

Что касается того, почему вы наблюдаете разные адреса при многократном запуске вашей программы, это потому, что:

  1. Стандарт C не зависит от ABI, форматов исполняемых файлов и загрузчиков.
  2. Достижения в области безопасности обычно означают, что вы не должны ожидать появления одинаковых адресов при нескольких запусках программы пользовательского режима в современной операционной системе.
...