Стабильность указателя в Windows Vista - PullRequest
14 голосов
/ 21 октября 2009

Я уже некоторое время использую Visual Studio 2005 под 64-битной Windows XP Pro для проектов на C и C ++. Один из популярных приемов, которые я использовал время от времени в отладчике, заключался в запоминании числового значения указателя из предыдущего прогона отладки программы (скажем, 0x00000000FFAB8938), добавлении его в окно просмотра с правильным типом передачи (скажем, ((MyObject *) 0x00000000FFAB8938)->data_field) и затем просмотрите память, занятую объектом во время следующего запуска отладки. Во многих случаях это довольно удобно и полезно, поскольку до тех пор, пока код остается неизменным, разумно ожидать, что расположение выделенной памяти также останется неизменным. Короче, работает.

Однако сравнительно недавно я начал использовать ту же версию Visual Studio на ноутбуке с 64-разрядной версией Windows Vista (Home Premium). Как ни странно, гораздо сложнее использовать этот прием в этой настройке. Фактический адрес памяти, по-видимому, довольно часто меняется от запуска к запуску без видимой причины, т. Е. Даже когда код программы не изменился вообще. Похоже, что реальный адрес не меняется совершенно случайно, он просто выбирает одно значение из фиксированного более или менее стабильного набора значений, но в любом случае это делает намного более сложным такой просмотр памяти.

Кто-нибудь знает причину такого поведения в Windows Vista? Что вызывает изменение в структуре памяти? Это какое-то внешнее вторжение в адресное пространство процесса от других [системных] процессов? Или это какая-то особенность реализации Heap API под Vista? Есть ли способ предотвратить это?

1 Ответ

30 голосов
/ 21 октября 2009

В Windows Vista реализовано рандомизация расположения адресного пространства, рандомизация кучи и рандомизация стека . Это механизм безопасности, который пытается предотвратить атаки переполнения буфера, основанные на знании того, где каждый фрагмент кода и данные находятся в памяти.

Можно отключить ASLR, установив значение реестра MoveImages . Я не смог найти способ отключить рандомизацию кучи, но какой-то парень из Microsoft рекомендует вычислять адреса относительно _crtheap. Даже если куча перемещается, относительный адрес может оставаться стабильным.

...