2010-03-25 2 views
4

Я пытаюсь создать программу, которая считывает значение по определенному адресу. у меня есть это:Чтение значения по адресу

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int *address; 
    address = (int*)0x00000021; 
    cout << *address; 
    return 0; 
} 

Но это дает ошибку нарушения чтения. Что я делаю не так? Thanks

+0

Почему бы вам не сделать это в мире? –

+0

Откуда вы получили адрес? Вы работаете в виртуальном режиме (я подозреваю ...)? Связана ли программа в режиме ядра (предположительно не ...)? –

+0

Потому что я хочу узнать больше о том, как работают компьютеры – jmasterx

ответ

2

Вы можете использовать указатель, который указывает на фактический объект.

Если у вас нет объекта по адресу 0x00000021, это не сработает.

Если вы хотите создать объект на свободном хранилище (кучи), вам нужно сделать это с помощью new:

int* address = new int; 
*address = 42; 
cout << *address; 
delete address; 
+0

Тогда как я могу получить значение в памяти, потому что OlyDbg может рассказать мне, что находится по этому адресу ... – jmasterx

+2

@ user146780: Отладчики обычно используют зависящие от операционной системы и зависящие от среды перехватчики для чтения данных с заданного адреса в виртуальном адресном пространстве процесса или в физической памяти. –

5

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

0

Вы не можете просто читать данные с произвольного адреса в памяти.

1

Когда ваша программа работает в операционной системе, которая предоставляет виртуальную память (Windows, * nix, OS X) Не все адреса поддерживаются памятью. Процессоры, которые поддерживают виртуальную память, используют что-то, называемое Page Tables, чтобы контролировать, какой адрес относится к памяти. Размер отдельной страницы обычно составляет 4096 байт, но это может меняться и, вероятно, будет больше в будущем.

API, который вы используете для запроса таблиц страниц, не является частью стандартной среды выполнения C/C++, поэтому вам нужно будет использовать специальные функции операционной системы, чтобы знать, какие адреса в порядке, чтобы читать и из-за которых вы будете к ошибке. В Windows вы должны использовать VirtualQuery, чтобы узнать, может ли данный адрес быть прочитанным, написанным, выполненным или любым/не указанным выше.

3

На какой-то вопрос есть вопрос, что именно показывает OlyDbg. 32-разрядная (и 64-разрядная) Windows использует виртуальную память, что означает, что адрес, который вы используете в вашей программе, - , а не так же, как адрес, фактически отправленный по шине в чипы памяти. Вместо этого Windows (и я должен добавить, что другие ОС, такие как Linux, MacOS, * bsd и т. Д., Делают примерно то же самое) настраивает некоторые таблицы, которые говорят (по сути), когда программа использует адрес в , этот диапазон, используйте , что диапазон физических адресов.

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

Windows (опять же, как и другие ОС) устанавливает таблицы для первой части адресного пространства, но НЕ связывает с ними какую-либо память. С точки зрения пользовательской программы эти адреса просто никогда не должны использоваться.

Это возвращает нас к моей неуверенности в том, что дает OlyDbg, когда вы просите его прочитать по адресу 0x21. Этот адрес просто не ссылается на какие-либо реальные данные - никогда не было и никогда не будет.

То, что другие говорят, правда, так: отладчик обычно использовать некоторые функции ОС (например, ReadProcessMemory и WriteProcessMemory, в частности под Windows), чтобы получить доступ к вещам, которые не умеют читать или писать напрямую. Они позволят вам читать и записывать память в другой процесс, который не может быть напрямую доступен обычным указателем. Ни один из них не помог бы в попытке прочитать с адреса 0x21, хотя - этот адрес не относится к какой-либо реальной памяти в любом процессе.

Смежные вопросы