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

когда я прочитал здесь, виртуальное адресное пространство 32-битного приложения Windows имеет 2 ГБ памяти (от 0x00000000-0x7FFFFFFFF). Остальные 2 ГБ зарезервированы для системного адресного пространства.

Однако я нашел указатель в 32-битной программе (использующей Cheat Engine), которая указывает на адрес, который не находится в диапазоне виртуального адресного пространства. Адреса в моем последнем исследовании были 0x301DDC3C -> 0x87F56190, как вы можете видеть на картинке: Виртуальное адресное пространство Windows

(Расширение в первой строке означает разыменование указателя 0x301DDC3C, в следующей строке видно, что находится в месте разыменования 0x87F56190 в ОЗУ)

После разыменования указателя есть указатели обратно в виртуальное адресное пространство процесса.

Как возможно, что приложение пользовательского режима имеет действительный указатель на системное адресное пространство?

Означает ли это, что указатель в ячейке 0x301DDC3C указывает на ячейку в системном адресном пространстве? Итак, процесс, который я изучаю, использует режим ядра?

если 32-битный исполняемый файл, помеченный /LARGEADDRESSAWARE, запускается под 64-битными окнами - для приложения доступно все 4 ГБ пространства

RbMm 21.01.2019 22:57

проверить наличие IMAGE_FILE_LARGE_ADDRESS_AWARE в IMAGE_FILE_HEADER.Characteristics

RbMm 21.01.2019 23:00

@RbMm Хороший намек. Спасибо. Это определено. Так что это должен быть обычный адрес в приватном адресном пространстве приложения...

JulianH 21.01.2019 23:06

да, если вы запускаете 32-битное приложение с IMAGE_FILE_LARGE_ADDRESS_AWARE - до FFFE0000 доступно для 32-битного кода. действительно пользовательское пространство до 7FFFFFFF0000

RbMm 21.01.2019 23:09

Установка флага /LARGEADDRESSAWARE для моего приложения устранила мою проблему. Когда вы пишете ответ с дополнительным объяснением, в каких случаях может появиться указатель> 0x7FFFFFFFF, я могу пометить его как правильный ответ. (мне очень помогло)

JulianH 22.01.2019 09:19
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
3 606
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

ВСЕ адресов, которые вы видите, являются адресами виртуальный из процесс (не «физическими» адресами). Процесс пользовательского пространства может использовать указатели, которые приходят из «системного пространства», но это означает, что НЕТ означает, что процесс может свободно обращаться к ресурсам ядра, и не означает, что эти указатели обязательно отображаются на адреса физический.

Вот еще одна ссылка Microsoft, которая может помочь прояснить:

Virtual Address Space

When a processor reads or writes to a memory location, it uses a virtual address. As part of the read or write operation, the processor translates the virtual address to a physical address.

...

The range of virtual addresses that is available to a process is called the virtual address space for the process. Each user-mode process has its own private virtual address space. For a 32-bit process, the virtual address space is usually the 2-gigabyte range 0x00000000 through 0x7FFFFFFF.

...

Processes like Notepad.exe and MyApp.exe run in user mode. Core operating system components and many drivers run in the more privileged kernel mode. For more information about processor modes, see User mode and kernel mode. Each user-mode process has its own private virtual address space, but all code that runs in kernel mode shares a single virtual address space called system space. The virtual address space for a user-mode process is called user space.

...

In 32-bit Windows, the total available virtual address space is 2^32 bytes (4 gigabytes). Usually the lower 2 gigabytes are used for user space, and the upper 2 gigabytes are used for system space.

...

Code running in user mode has access to user space but does not have access to system space. This restriction prevents user-mode code from reading or altering protected operating system data structures. Code running in kernel mode has access to both user space and system space. That is, code running in kernel mode has access to system space and the virtual address space of the current user-mode process.

...

Также стоит отметить разницу между режим ядра и пользовательский режим:

User mode and kernel mode

When you start a user-mode application, Windows creates a process for the application. The process provides the application with a private virtual address space and a private handle table. Because an application's virtual address space is private, one application cannot alter data that belongs to another application. Each application runs in isolation, and if an application crashes, the crash is limited to that one application. Other applications and the operating system are not affected by the crash.

... In addition to being private, the virtual address space of a user-mode application is limited. A processor running in user mode cannot access virtual addresses that are reserved for the operating system. Limiting the virtual address space of a user-mode application prevents the application from altering, and possibly damaging, critical operating system data.

...

Ограничения памяти и адресного пространства - Ограничение в 64-битной Windows — 4 ГБ с установленным IMAGE_FILE_LARGE_ADDRESS_AWARE
RbMm 21.01.2019 23:05

Windows Server 2008 была первой ОС Microsoft, выпущенной только для 64-разрядной версии. «/LARGEADDRESSAWARE» — это анахронизм — он не используется/не нужен в текущих версиях Windows.

paulsm4 21.01.2019 23:13
/LARGEADDRESSAWARE это вариант линкера. он установил флаг IMAGE_FILE_LARGE_ADDRESS_AWARE в IMAGE_FILE_HEADER.Characteristics и конечно же это не анахронизм
RbMm 21.01.2019 23:15

32-битные (и 16-битные DOS-приложения) ЯВЛЯЮТСЯ анахронизмы. Исходный вопрос OP, похоже, был о времени выполнения, а не о компиляции/связывании. Что касается проблем на уровне исходного кода: A) приложение не должно знать - или заботиться - если значение указателя меньше или больше 2 ^ 31, B) В той степени, в которой приложению может потребоваться >> 2 ГБ непрерывного пространства, оно В любом случае было бы разумно создать приложение для 64-битных систем. Точки ГЛАВНЫЙ, которые я должен был передать ПЫТАЮЩИЙСЯ: A) «пространство пользователя» и «системное пространство», B) различие между физическими и виртуальными адресами в любом пространстве и C) «режим пользователя» и «режим ядра».

paulsm4 22.01.2019 01:59

пока 32битные приложения не анахронизмы по факту. то, как приложение связано, влияет на время выполнения. я просто замечу, что если мы установим флаг IMAGE_FILE_LARGE_ADDRESS_AWARE в 32-битном PE - 64-битные окна позволят ему работать с 4 ГБ пространства. без этого флажка - всего 2гб. Технически это делается с помощью резерв (чтобы предотвратить выделение) некоторого пространства памяти от FFFE0000 (если 4 ГБ) или 7FFF0000 до 64-битной ntdll.dll обычно.

RbMm 22.01.2019 02:07
Ответ принят как подходящий

от Ограничения памяти и адресного пространства

Ограничения на память и адресное пространство зависят от платформы, операционной системы и от того, установлен ли флаг IMAGE_FILE_LARGE_ADDRESS_AWARE в файле IMAGE_FILE_HEADER.Characteristics. IMAGE_FILE_LARGE_ADDRESS_AWARE (Приложение может обрабатывать адреса размером более 2 ГБ.) устанавливается или очищается с помощью опции компоновщика /LARGEADDRESSAWARE.

по умолчанию IMAGE_FILE_LARGE_ADDRESS_AWARE очищен для 32-битного PE и установлен для 64-битного PE, но мы можем перезаписать значение по умолчанию:

поэтому 32-битный процесс с установленным флагом IMAGE_FILE_LARGE_ADDRESS_AWARE - доступен до 4Gb памяти.

на самом деле конечно [0, 0x800000000000) (win8.1+) или [0, 0x80000000000) (до win 8.1) место в памяти доступно для пользовательского режима в x64 windows. но система искусственно ограничивает это, резервируя большой диапазон памяти (это выделение защищено и не может быть свободным)

для 32-битного процесса это резервирование начинается с 7FFF0000 или FFFE0000 и до 64-битного ntdll.dll. очень интересно, что в 64-битном процессе, где очищался IMAGE_FILE_LARGE_ADDRESS_AWARE - тоже было такое зарезервированное пространство памяти, начинающееся с 0x80000000. также интересно, что в этом случае ядро32.dll загружается по другому адресу, в отличие от обычного 64-битного процесса. так что база ядро32.dll не одинакова вообще во всех 64-битных процессах. но ntdll.dll все равно загружается по одному и тому же адресу во всех процессах.

обычное распределение памяти на окнах x64:

  1. 32 битный процесс, IMAGE_FILE_LARGE_ADDRESS_AWARE очищен (по умолчанию)
  2. 32 битный процесс, IMAGE_FILE_LARGE_ADDRESS_AWARE набор
  3. 64 битный процесс, IMAGE_FILE_LARGE_ADDRESS_AWARE очищен
  4. 64 битный процесс, установлен IMAGE_FILE_LARGE_ADDRESS_AWARE (по умолчанию)

Другие вопросы по теме