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

(Расширение в первой строке означает разыменование указателя 0x301DDC3C, в следующей строке видно, что находится в месте разыменования 0x87F56190 в ОЗУ)
После разыменования указателя есть указатели обратно в виртуальное адресное пространство процесса.
Как возможно, что приложение пользовательского режима имеет действительный указатель на системное адресное пространство?
Означает ли это, что указатель в ячейке 0x301DDC3C указывает на ячейку в системном адресном пространстве? Итак, процесс, который я изучаю, использует режим ядра?
проверить наличие IMAGE_FILE_LARGE_ADDRESS_AWARE в IMAGE_FILE_HEADER.Characteristics
@RbMm Хороший намек. Спасибо. Это определено. Так что это должен быть обычный адрес в приватном адресном пространстве приложения...
да, если вы запускаете 32-битное приложение с IMAGE_FILE_LARGE_ADDRESS_AWARE - до FFFE0000 доступно для 32-битного кода. действительно пользовательское пространство до 7FFFFFFF0000
Установка флага /LARGEADDRESSAWARE для моего приложения устранила мою проблему. Когда вы пишете ответ с дополнительным объяснением, в каких случаях может появиться указатель> 0x7FFFFFFFF, я могу пометить его как правильный ответ. (мне очень помогло)





ВСЕ адресов, которые вы видите, являются адресами виртуальный из процесс (не «физическими» адресами). Процесс пользовательского пространства может использовать указатели, которые приходят из «системного пространства», но это означает, что НЕТ означает, что процесс может свободно обращаться к ресурсам ядра, и не означает, что эти указатели обязательно отображаются на адреса физический.
Вот еще одна ссылка Microsoft, которая может помочь прояснить:
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.
...
Также стоит отметить разницу между режим ядра и пользовательский режим:
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.
...
Windows Server 2008 была первой ОС Microsoft, выпущенной только для 64-разрядной версии. «/LARGEADDRESSAWARE» — это анахронизм — он не используется/не нужен в текущих версиях Windows.
/LARGEADDRESSAWARE это вариант линкера. он установил флаг IMAGE_FILE_LARGE_ADDRESS_AWARE в IMAGE_FILE_HEADER.Characteristics и конечно же это не анахронизм
32-битные (и 16-битные DOS-приложения) ЯВЛЯЮТСЯ анахронизмы. Исходный вопрос OP, похоже, был о времени выполнения, а не о компиляции/связывании. Что касается проблем на уровне исходного кода: A) приложение не должно знать - или заботиться - если значение указателя меньше или больше 2 ^ 31, B) В той степени, в которой приложению может потребоваться >> 2 ГБ непрерывного пространства, оно В любом случае было бы разумно создать приложение для 64-битных систем. Точки ГЛАВНЫЙ, которые я должен был передать ПЫТАЮЩИЙСЯ: A) «пространство пользователя» и «системное пространство», B) различие между физическими и виртуальными адресами в любом пространстве и C) «режим пользователя» и «режим ядра».
пока 32битные приложения не анахронизмы по факту. то, как приложение связано, влияет на время выполнения. я просто замечу, что если мы установим флаг IMAGE_FILE_LARGE_ADDRESS_AWARE в 32-битном PE - 64-битные окна позволят ему работать с 4 ГБ пространства. без этого флажка - всего 2гб. Технически это делается с помощью резерв (чтобы предотвратить выделение) некоторого пространства памяти от FFFE0000 (если 4 ГБ) или 7FFF0000 до 64-битной ntdll.dll обычно.
от Ограничения памяти и адресного пространства
Ограничения на память и адресное пространство зависят от платформы, операционной системы и от того, установлен ли флаг 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:
если 32-битный исполняемый файл, помеченный
/LARGEADDRESSAWARE, запускается под 64-битными окнами - для приложения доступно все 4 ГБ пространства