Как вы читаете напрямую из физической памяти?

В C или C++ (Windows), как вы читаете оперативную память, указав физический (не виртуальный) адрес? Это означает, что вы не будете использовать систему виртуальной памяти (таблицы mmu) и будете привязаны к одному процессу.

Я уже знаю API ReadProcessMemory, который читает из оперативной памяти (используется большинством тренеров), но только для определенного процесса.

Я провел поиск в MSDN и обнаружил, что Device\PhysicalMemory, похоже, дает такую ​​возможность. , но я не нашел практического примера, и эта функция, похоже, была отключена пакетами обновлений Windows (для исправления некоторой уязвимости).

Я знаю, что это возможно, потому что это делает WinHex (если вы выберете «инструменты»> «открыть оперативную память»> «физическая память»). Затем он отобразит содержимое ОЗУ от 0x00000000 до your_ram_size, как при открытии традиционного файла. Требуются права администратора, но нет драйвера для установки (что означает, что WinHex делает это из пользовательского режима).

РЕДАКТИРОВАТЬ: добавлена ​​информация о os.


person tigrou    schedule 06.12.2011    source источник
comment
попробуйте link -dump -imports на WinHex и посмотрите, какие функции он вызывает.   -  person John Knoeller    schedule 06.12.2011
comment
@Alexandre C.: Я хотел бы написать трейнер для игры. Я никогда не знаю заранее, где (в каком процессе) будут значения, поэтому я подумал, что будет проще все просканировать (винхекс делает это очень быстро). Я уже могу сделать это вручную (используя winhex), но лучше, чтобы это делала какая-нибудь автоматическая программа.   -  person tigrou    schedule 06.12.2011
comment
Отображение физической памяти довольно нестабильно и содержит гораздо больше памяти, чем игровой процесс. Итак, кажется, что это шаг назад от ReadProcessMemory.   -  person MSalters    schedule 06.12.2011
comment
Если вы пишете чит-программу для игры, то вы, по крайней мере, знаете, что нужное вам значение будет находиться в памяти этого процесса. Кроме того, память этого процесса не обязательно будет находиться в физической оперативной памяти в то время, когда вы ее ищете, поэтому функция ReadProcessMemory действительно является идеальной функцией для ваших нужд. Он будет читать из файла подкачки и позволит вам использовать стабильные адреса.   -  person Rob Kennedy    schedule 06.12.2011
comment
Для вашего тренера вы все равно захотите сделать смещения от базового VA, так как образ в памяти исполняемого файла будет меняться от выполнения к выполнению. Таким образом, вам лучше определить местоположение интересующей переменной, вычислить смещение и использовать его для получения VA процесса.   -  person tdenniston    schedule 06.12.2011
comment
К OP: вы, вероятно, захотите использовать комбинацию CreateRemoteThread(Ex) и LoadLibrary. Вся эта ерунда с физической памятью совершенно не нужна.   -  person Seth Carnegie    schedule 06.12.2011
comment
Вы уверены, что WinHex не использует для этого драйвер? Это просто не похоже на то, что должно быть возможно в пользовательском режиме, даже с административными привилегиями...   -  person Martin B    schedule 06.12.2011
comment
Несмотря на то, что он довольно старый, этот codeproject.com/KB/system/soviet_kernel_hack.aspx по крайней мере интересно было бы попробовать ;-)   -  person alk    schedule 06.12.2011
comment
... или что означает, что WinHex использует для этого драйвер KM.   -  person 0xC0000022L    schedule 29.03.2016


Ответы (7)


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

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

Таким образом, MmAllocateContiguousMemory() — это функция режима ядра Windows, которая сопоставляет непрерывную физическую память с системной памятью и является частью ntoskrnl.exe.

Также вы не можете вызывать эти API из приложений пользовательского режима. Ими могут пользоваться только водители. Приложения пользовательского режима НЕ МОГУТ получить доступ к физической памяти без помощи драйвера. Драйвер может либо обрабатывать запросы от пользовательского API, либо использовать IOCTL и сопоставлять свои ресурсы с виртуальной памятью API. В любом случае вам понадобится помощь драйвера, который должен быть установлен менеджером plug n play. PnP должен выбрать установку драйвера самостоятельно либо с помощью аппаратной активации, т. е. горячей замены, либо каким-либо другим методом, например, драйвером шины, который всегда включен.

Дальнейшие окна случайным образом назначают виртуальный адрес, так что трудно определить какой-либо шаблон или определить его физическое местоположение.

person marshal craft    schedule 05.01.2015
comment
DOLLx8KD - это dll, которую вы можете использовать для доступа к оперативной памяти до Windows 7 (на самом деле это драйвер режима ядра ^ с драйвером пользовательского режима, вы можете вызвать его функцию через dll. в c) - person marshal craft; 09.01.2015
comment
Другим распространенным использованием может быть прямой доступ к памяти или DMA. В этом случае независимое оборудование обращается к физической памяти напрямую, минуя процессор или диспетчер памяти. - person marshal craft; 09.05.2015
comment
Также похоже, что ReadProcessMemory() — это просто метод, который позволяет осуществлять межпроцессное взаимодействие через память. это все равно будет адрес виртуальной памяти. - person marshal craft; 09.05.2015
comment
Вторая ссылка, похоже, сделана Microsoft, которая управляет физической памятью и предназначена для использования в некоторых настройках. Это не метод фактического приобретения этих объектов. - person marshal craft; 09.05.2015
comment
не уверен насчет winHex, вы видели исходники? откуда вы знаете, что он не вызывает драйвер? - person marshal craft; 09.05.2015

Ни язык C, ни C++ не определяют термин «память». Вещи определяются в абстрактных терминах, таких как «хранилище» и «классификаторы хранения». Указатели — это абстрактные вещи — их значения могут быть любыми, совершенно не связанными с физическими или виртуальными адресами.

Только в контексте системы и ее реализации вводятся такие термины, как память и адресное пространство. И поскольку это специфичные для системы вещи, для доступа к ним необходимо использовать методы, предоставляемые ОС.

Даже при реализации ядра ОС вы должны делать доступ к вещам самого низкого уровня не через C (потому что он просто не может), а через методы, специфичные для реализации и архитектуры. Обычно это делается с помощью набора низкоуровневых функций, запрограммированных на ассемблере, которые написаны таким образом, чтобы они соответствовали типу машинного кода, генерируемого компилятором. Это позволяет вызывать из C функции, написанные на ассемблере, как если бы они были скомпилированы компилятором.

person datenwolf    schedule 06.12.2011
comment
дата это правильно? Единственное, что вы не можете сделать с C, это получить доступ к указателю инструкций. Как только вы настроите это и сообщите ЦП, с чего начать выполнение, вы можете начать выполнение скомпилированного кода. Теперь вы, возможно, не захотите делать это без приличного, компетентного API, но вы можете легко указать непосредственно на физическую память через скомпилированный код, если хотите столько же, сколько могли бы использовать сборку - для современных машин это все зависит от MMU, конечно, в любом случае. Но на меньших машинах или старых машинах вы можете получить доступ к физической памяти через скомпилированный код. - person cdcdcd; 10.01.2017
comment
@cdcdcd: Да, скомпилированный код, представляющий собой двоичную архитектуру, конечно, может обращаться к памяти. Но язык программирования C (и C++ тоже) не имеют встроенного механизма для прямого доступа к произвольным ячейкам памяти. Указатель всегда должен быть получен путем применения оператора адреса (&) к действительному объекту хранения C. Или реализация может предоставлять зависимый от реализации доступ к произвольным ячейкам памяти. Например, в ядре Linux для каждой архитектуры есть реализация доступа к памяти, например. для x86: lxr.free-electrons.com/source/arch/x86/include/asm/io.h - person datenwolf; 10.01.2017
comment
@cdcdcd: Просто чтобы прояснить, что исходный код ядра Linux использует встроенный ассемблер для определения интерфейсов функций C, тела которых написаны не на C, а написаны непосредственно на машинном языке, потому что C не имеет определяемого языком механизма для доступа к памяти. . - person datenwolf; 10.01.2017
comment
Вы в этом уверены? Можете ли вы предоставить ссылку. Возможность прямого доступа к физической памяти не имеет ничего общего с языком. Ваш аргумент является одним из мышления. Вы могли бы так же легко написать компилятор для создания того же машинного кода из .c, что и созданный вручную машинный код, на который вы ссылаетесь. Учитывая вашу логику, можно утверждать, что сборка не может получить доступ к адресу памяти, потому что для этого требуется ассемблер. Конечно, как в C, так и в случае ассемблера исходный код не обращается напрямую к памяти (до тех пор, пока не скомпилирован и не загружен), но и машинный код не обращается к нему до тех пор, пока не будет выполнен. - person cdcdcd; 10.01.2017
comment
....daten добавляю сюда, что современные системы используют MMU. Как и в Linux, но ядро ​​имеет логическое адресное пространство, которое напрямую отображается в физическую память и может использоваться для прямого доступа к памяти (это, насколько я знаю, было написано на C). Тем не менее, по-прежнему существуют системы с одним пространством плоской памяти, и C используется для прямого доступа к физической памяти (см. встроенные системы). Исторически сложилось так, что многие игры для DOS были написаны на C, поскольку они позволяли прямой доступ к памяти VGA для существенного ускорения рендеринга (см. DOOM на github). - person cdcdcd; 10.01.2017
comment
@cdcdcd: Это не имеет абсолютно никакого отношения к доступности MMU, виртуальной памяти или DMA и всему этому. Язык программирования C совершенно не зависит от памяти на аппаратном уровне. Конечно, C знает о памяти в очень абстрактном смысле. Но C называет это объектами хранения, и вы можете выделить хранилище из автоматической памяти (которая будет стеком в обычных системах) или из динамической памяти (называемой кучей в обычных системах). Но в чистом C нет способа сказать "эй, я хочу получить доступ к области памяти с адреса, скажем, 0x00001000 до 0x01000000". - person datenwolf; 10.01.2017
comment
@cdcdcd: Если вы хотите получить доступ к памяти по определенному адресу (будь то виртуальный, физический или в области ввода-вывода), вам нужен какой-то вспомогательный метод, который в глубине души может быть написан не на C, а на ассемблере, и даст вам указатель, который придерживается семантики памяти C. C не является ассемблером высокого уровня! Некоторые реализации C позволяют вам приводить целые числа к указателям, которые интерпретируются как адреса в адресном пространстве программ (практически каждая реализация C для микроконтроллеров), но для чего-то, что работает в виртуальном адресное пространство не полагайтесь на это. - person datenwolf; 10.01.2017
comment
@cdcdcd: Подводя итог: стандарт языка C не определяет никакого метода абсолютной адресации памяти машины, на которой будет выполняться программа. За кулисами компилятор, конечно же, переводит все в обращения к необработанным адресам памяти. И на этапе связывания вы обычно можете заставить компоновщика (используя скрипт компоновщика) разместить определенные символы в определенных адресных местах; например, вы можете заставить компоновщик разместить символ int foo; по адресу 0x0010; но если вы позже написали int *p = 0x0010;, нет никаких оснований ожидать, что это на самом деле будет указывать на foo. - person datenwolf; 10.01.2017
comment
@cdcdcd: Но вполне возможно объявить функцию void *at_addr(long address);, которая внутренне реализована на ассемблере, и если вы использовали эту функцию вот так int *q = at_addr(0x0010);, то она фактически укажет на это место, потому что внутренности at_addr может быть написан таким образом, чтобы соответствовать тому, что вы заставили компоновщик сделать со сценарием компоновщика. Но все это выходит за рамки спецификации языка программирования C, и поэтому мы можем сказать, что это невозможно сделать, используя только C. - person datenwolf; 10.01.2017
comment
@cdcdcd: И просто для полноты, способ прямого доступа к физической памяти в *nix-подобных ОС будет следующим: сначала вы делаете int fd_mem = open("/dev/mem", O_RDWR);, а затем можете void *ptr = mmap(0, size, PROT_READ|PROT_WRITE, 0, fd_mem, address);, затем ptr будет указывать на физическую память, начиная с address до address+size . Но глубоко внутри ядра ОС реализация mmap на /dev/mem сводится к некоторым манипуляциям с регистрами ЦП на уровне ниже уровня C. - person datenwolf; 10.01.2017
comment
danten, если бы вы были правы, то самый простой 8/16-битный встроенный код микросистемы дал бы сбой, и самолеты начали бы падать с неба. Таким образом, для 16-битной системы с одним плоским адресным пространством памяти (физическая память — виртуальной памяти нет, только DMA), используя static int16* ptr = 0x100, вы можете писать и читать в/из этого физического адреса путем разыменования ptr. Если вы хотите читать/записывать в ячейку памяти в сборке, вы также должны уважать это (общий диалект CISC: ptr: .dword 0x100h, а затем использовать mov ax, 0[ptr]). Мы говорим о противоположных целях здесь? - person cdcdcd; 10.01.2017
comment
Почему я спрашиваю, так это то, что я не могу поверить в то, что вы говорите как опытный программист. Если вы компилируете на системном уровне, компилятору все равно, и вы можете заставить его принимать жестко закодированные адресные пространства - это будет сохранено вплоть до машинного кода. Доступ к памяти в конечном итоге зависит от программной реализации. В современных ОС это управляется в виртуальной памяти - даже на уровне ядра (даже если это просто сопоставление смещения). Но это не означает, что код C нельзя жестко запрограммировать с адресами физической памяти. - person cdcdcd; 10.01.2017
comment
@cdcdcd: Нет, я пытаюсь вам сказать, что стандарт языка C не знает и не заботится о том, что называется адресами физической памяти. Это не так по той простой причине, что C был написан таким образом, что его можно использовать в любой мыслимой компьютерной архитектуре. Вполне возможно построить машины, которые не работают с плоской линейной памятью, а организуют данные в структурах более высокого уровня (таких как списки CAR/CDR LISP или реализация словаря аппаратного уровня). Компилятор (то есть реализация) должен фактически принять решение о фактическом расположении данных. - person datenwolf; 10.01.2017
comment
@cdcdcd: Когда дело доходит до фактической реализации (то есть компиляторов), некоторые реализации могут фактически указывать в четко определенном вопросе, что адреса физической или виртуальной памяти могут быть приведены к указателю. Но подумайте о следующем: стандарт языка C предписывает(!!!), что арифметический ноль при приведении к указателю всегда приводит к нулевому указателю; поэтому невозможно правильно получить доступ к адресу памяти 0x0. Но у довольно многих машин есть значимые вещи. Видишь, в чем проблема? О, и к вашему сведению, вы неправильно используете термин DMA. - person datenwolf; 10.01.2017
comment
Дантен, ты становишься немного колючим. Я только веду дискуссию. Я возражал против вашей ошибочной точки зрения, что вы не можете получить прямой доступ к физической памяти с помощью C. Все, что вы утверждаете о C, верно и для ассемблера. Большая разница в C и ассемблере заключается в доступе к указателю инструкции. вам необходимо иметь доступ к регистру адреса инструкций. Вот и все. Стандарт C определяет только правила преобразования символьного кода в машинные инструкции. От них ядро ​​ОС и время выполнения определяет все остальное. Но это регулируется реализацией ОС! - person cdcdcd; 10.01.2017
comment
В простой встроенной системе этот слой тонкий как бумага. И да, это требует сборки в самом начале по причинам, которые я привел. Но если скомпилированный C ссылается на физические адреса, эти адреса будут использоваться. И да, C может указывать на 0x0 (хотя и не рекомендуется), но в современных системах ядро ​​​​выдает исключение, потому что есть промах TLB (отсутствие отображения), и у ядра нет записи о его буферизации; это программное обеспечение, которое управляет этим в современной ОС (и не обязательно). В небольшой встроенной системе без ОТОБРАЖЕНИЯ такого исключения нет, и вы можете получить доступ к этому местоположению. - person cdcdcd; 10.01.2017
comment
К вашему сведению, я освоил 8-битные системы, поэтому знаю, что и как работает DMA. Это позволяет вам читать и записывать в и из ОЗУ и ввода-вывода без необходимости участия ЦП. И да, вы можете сделать это в C, используя прямые отображения памяти. - person cdcdcd; 10.01.2017
comment
@cdcdcd: Хорошо, вот немного пищи для размышлений: как вы читаете из ячейки памяти 0x00 на 8-битном, используя просто C? Вы не можете сделать char *p = (char*)0x00; char v = *p;, потому что это вызовет неопределенное поведение, а оптимизирующий компилятор может легально преобразовать это во что угодно. - person datenwolf; 10.01.2017
comment
То, что вы можете, не означает, что вы должны. Учитывая, что некоторые системы позволяют вам, и вы можете прочитать значение байта в 0x00 - здесь нет неопределенного поведения, порядок событий предсказуем и для системы, где это допустимо, и нацелен на компилятор; он справится с этим правильно (прочитает и запишет содержимое в v). Компилятор для современной платформы может выдать предупреждение. Помните, что многие системы имеют собственные компиляторы. Опять же, вы можете написать ассемблер, чтобы делать то же самое. Если вы беспокоитесь об оптимизации, просто используйте volatile. - person cdcdcd; 10.01.2017
comment
Я должен добавить, что при написании компилятора для конкретной фиксированной системы любое адресное пространство для стека будет начинаться с заранее заданного адреса, и хотя вы можете получить к нему доступ, его не следует использовать для явных операций чтения/записи. Раньше вы могли сделать это для большинства систем, и это вызывало всевозможный хаос! Отсюда и появление таких вещей, как MMU. - person cdcdcd; 10.01.2017
comment
@cdcdcd: Нет, ты не можешь сделать char *p=0; char c=*p;. Выполнение этого всегда приводит к неопределенному поведению… никаких исключений! И MMU были введены не только из-за затирания стека (если вы хотите, чтобы простого MPU было достаточно). MMU дают гораздо больше, чем просто виртуальное адресное пространство. - person datenwolf; 10.01.2017
comment
Кстати, у тебя есть привычка вкладывать слова в мой рот. Я никогда не говорил, что MMU появился из-за проблем со стеком. Посмотрите на указанное выражение и обратите внимание на стек в кавычках. Дело в том, что в одном плоском пространстве памяти вы можете получить доступ к любой части памяти, не имея (или намеренно) никакого представления о том, где будут храниться локальные переменные. Короче, утомительно все это. MMU, среди прочего, обеспечивает аппаратную защиту и разрешения. Если вы не можете признать свою неправоту в одном гребаном пункте — несмотря на всю работу над 8/16-битной системой — тогда, кажется, нет особого смысла продолжать. - person cdcdcd; 10.01.2017
comment
Неопределенное поведение просто означает, что выражение приведет к коду, который не предписан спецификациями языка (стандартом, если хотите). Это просто означает, что, учитывая стандарт, все ставки сняты, если вы не ЗНАЕТЕ, что данный компилятор играет в мяч. Однако для данной среды это может быть полностью действительным и не будет неопределенным для данной реализации компилятора. Но не верьте мне на слово, пожалуйста, прочитайте многие ответы ваших коллег здесь (в частности, те, которые связаны со встроенными системами): stackoverflow.com/questions/21104702/ - person cdcdcd; 10.01.2017
comment
@cdcdcd: то, что вы описали, является реализацией определенного поведения. Это нечто отличное от поведения undefined. Разыменование нулевого указателя является поведением undefined, и на самом деле реализация не может переопределять его как определенную реализацией. - person datenwolf; 06.12.2017
comment
В вопросе есть окна тегов, поэтому он предполагает вызовы, зависящие от архитектуры, и ваш ответ бессмысленен. -1 - person ; 09.01.2018

Перейдите по этой ссылке: Доступ к физической памяти, порту и пространству конфигурации PCI

Но начните с Windows Vista, даже WinHex не может открыть физическую память.

person Shawnone    schedule 06.12.2011
comment
Однако это требует написания драйвера. ОП утверждает, что WinHex может сделать это без драйвера, хотя я довольно скептически к этому отношусь. - person Martin B; 06.12.2011

Я бы подумал, что драйвер устройства должен разрешать доступ к физической памяти, поскольку доступ к таким устройствам, как карты PCI, должен осуществляться таким образом. Если вы можете сделать это из драйвера, напишите собственный распределитель для вашей программы режима «пользователь» (больше похожей на администратора), чтобы легко связываться с С++.

person Timmah    schedule 06.12.2011
comment
Драйверы PCI используют схемы прямого доступа к памяти для передачи данных, поэтому процессор (используемый для кода) не задействован. Так что для всех практических целей это не должно помочь. - person gnometorule; 06.12.2011

В Windows следует использовать вызовы NativeAPI NtOpenSection и NtMapViewOfSection

Пример от Марка Руссиновича

static BOOLEAN MapPhysicalMemory( HANDLE PhysicalMemory,
                            PDWORD Address, PDWORD Length,
                            PDWORD VirtualAddress )
{
    NTSTATUS            ntStatus;
    PHYSICAL_ADDRESS    viewBase;
    char                error[256];

    *VirtualAddress = 0;
    viewBase.QuadPart = (ULONGLONG) (*Address);
    ntStatus = NtMapViewOfSection (PhysicalMemory,
                               (HANDLE) -1,
                               (PVOID) VirtualAddress,
                               0L,
                               *Length,
                               &viewBase,
                               Length,
                               ViewShare,
                               0,
                               PAGE_READONLY );

    if( !NT_SUCCESS( ntStatus )) {

        sprintf_s( error, "Could not map view of %X length %X",
                *Address, *Length );
        PrintError( error, ntStatus );
        return FALSE;                   
    }

    *Address = viewBase.LowPart;
    return TRUE;
}

static HANDLE OpenPhysicalMemory()
{
    NTSTATUS        status;
    HANDLE          physmem;
    UNICODE_STRING  physmemString;
    OBJECT_ATTRIBUTES attributes;
    WCHAR           physmemName[] = L"\\device\\physicalmemory";

    RtlInitUnicodeString( &physmemString, physmemName );    

    InitializeObjectAttributes( &attributes, &physmemString,
                                OBJ_CASE_INSENSITIVE, NULL, NULL );         
    status = NtOpenSection( &physmem, SECTION_MAP_READ, &attributes );

    if( !NT_SUCCESS( status )) {

        PrintError( "Could not open \\device\\physicalmemory", status );
        return NULL;
    }

    return physmem;
}

\device\physicalmemory является аналогом /dev/mem под Linux, где у вас также есть возможность прямого доступа к физической памяти. Кстати, насчет Windows не уверен, но под Linux доступен только 1 Мб физического адресного пространства, потому что оно может содержать некоторые служебные низкоуровневые данные, такие как таблицы BIOS. Доступ к другой физической памяти может повредить виртуальную память, управляемую ОС, поэтому он не разрешен.

ОБНОВЛЕНИЕ: Предоставленный код не работает в пользовательском режиме, начиная с Windows Vista. Вместо этого вы можете вызвать GetSystemFirmwareTable(), чтобы получить полезную информацию из 1-го МБ необработанной памяти, не ища ее.

Бонус: чтение физической памяти под Linux (Debian 9) с использованием файла с отображением памяти Boost IO, часть класса:

NativePhysicalMemory::NativePhysicalMemory(size_t base, size_t length)
    : physical_memory_map_(std::make_unique<boost::iostreams::mapped_file_source>())
{
    map_physical_memory(base, length);
}

// ...

void NativePhysicalMemory::map_physical_memory(size_t base, size_t length)
{
#ifdef _SC_PAGESIZE
    size_t mempry_page_offset = base % sysconf(_SC_PAGESIZE);
#else
    size_t mempry_page_offset = base % getpagesize();
#endif /* _SC_PAGESIZE */

    boost_io::mapped_file_params params = {};
    params.path = "/dev/mem";
    params.flags = boost_io::mapped_file::mapmode::readonly;
    params.length = length + mempry_page_offset;
    params.offset = base - mempry_page_offset;
    params.hint = nullptr;
    physical_memory_map_->open(params);
}
person Community    schedule 12.01.2017
comment
Отлично работает под правами Администратора и root соответственно - person ; 19.12.2017
comment
Да, извините, моя вина - это действительно не работает в пользовательском режиме, начиная с Windows 7 (работает на старых системах, таких как XP). Вместо этого вы можете читать таблицы SMBIOS, используя вызов WinAPI. Хотя под Linux чтение из /dev/mem все же возможно :) - person ; 21.12.2017
comment
В очередной раз не запускается с винды 7, с висты конечно (что-то с памятью, я не имею в виду ОЗУ =)) Обновил ответ. - person ; 21.12.2017

Я предполагаю, что невозможно получить доступ к физическому адресу напрямую. Даже с правами администратора.

Каждый адрес, к которому обращается приложение, является виртуальным адресом, который преобразуется в физический адрес аппаратным MMU.

Один из способов — настроить MMU для однозначного сопоставления виртуального адреса с физическим адресом. Обычно это делается во встроенных системах без ОС или перед загрузкой ОС.

С загруженными окнами. Я считаю, что ваше требование невозможно.

person M S    schedule 06.12.2011
comment
Можно как из POSIX - /dev/mem так и из Windows NtOpenSection(L\\Device\\PhysicalMemory) - person ; 12.01.2017

Краткий ответ: нет

Длинный ответ:

Стандарт C/C++ определяет машину очень просто. Нет понятия виртуальной памяти (просто память). Эти концепции больше относятся к области аппаратного обеспечения и потенциально могут быть доступны через ОС (если ОС знает о таких вещах).

Я бы повторно задал вопрос с точки зрения возможностей, предоставляемых вашей ОС/аппаратным обеспечением.

person Martin York    schedule 06.12.2011
comment
Я думаю, что вопрос уже связан с возможностями, предлагаемыми ОС, поскольку речь идет о функциях и устройствах, предоставляемых ОС. - person Rob Kennedy; 06.12.2011
comment
Я забыл указать это в описании: это для среды Win32. Я согласен с вами, что вопрос бессмысленный, если не конкретный. - person tigrou; 06.12.2011
comment
Это не группа новостей C++. Специфика ОС в полном порядке - person parapura rajkumar; 06.12.2011