Устойчивость указателя в Windows Vista
Я использовал Visual Studio 2005 под 64-разрядной версией Windows XP Pro для проектов на C и С++. Одним из популярных трюков, которые я использовал время от времени в отладчике, было запоминание значения числового указателя из предыдущего прогона отладки программы (скажем 0x00000000FFAB8938
), добавьте его в окно просмотра с надлежащим типом (например, ((MyObject *) 0x00000000FFAB8938)->data_field
), а затем просмотрите память, занятую объектом во время следующего прогона отладки. Во многих случаях это довольно удобно и полезно, поскольку до тех пор, пока код остается неизменным, разумно ожидать, что выделенный макет памяти останется неизменным. Короче говоря, он работает.
Однако сравнительно недавно я начал использовать ту же версию Visual Studio на ноутбуке с 64-разрядной версией Windows Vista (Home Premium). Как ни странно, гораздо сложнее использовать этот трюк в этой настройке. Фактический адрес памяти, по-видимому, довольно часто изменяется от запуска до запуска без видимых причин, то есть даже когда код программы вообще не изменился. Похоже, что фактический адрес не изменяется полностью случайным образом, он просто выбирает одно значение из фиксированного более или менее стабильного набора значений, но в любом случае гораздо труднее сделать этот вид наблюдения за памятью.
Кто-нибудь знает причину такого поведения в Windows Vista? Что вызывает изменение в макете памяти? Это какое-то внешнее вторжение в адресное пространство процесса из других [системных] процессов? Или это какая-то причуда/особенность реализации Heap API под Vista? Есть ли способ предотвратить это?
Ответы
Ответ 1
Windows Vista реализует рандомизацию расположения пространства адресов, рандомизацию кучи и рандомизацию стека. Это механизм безопасности, который пытается предотвратить атаки переполнения буфера, которые полагаются на знание того, где каждая часть кода и данных находится в памяти.
Можно отключить ASLR, установив значение реестра MoveImages. Я не мог найти способ отключить рандомизацию кучи, но какой-то парень Microsoft рекомендует вычислять адреса по сравнению с _crtheap
. Даже если куча перемещается, относительный адрес может оставаться стабильным.