Я пытаюсь просканировать системную память.

Мой план: создавать указатели, указывающие на память, и перемещать этот указатель на один байт вверх в каждом цикле.

Вот что я придумал:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

const char *MemAdressPointer(int n);

int main(void) {

    int i = 0;
    for(i = 0; i<100; i++)
    {
        const char* pAddr = MemAdressPointer(i+5000);
        printf("%c hexadecimal value of : 0x%p with i at : %i\n", *pAddr, pAddr, i);
    }
    getchar();
    return 0;
}

const char *MemAdressPointer(int n)
{
    void *p1 = (void*) n;

    const char* p2;
    p2 = p1;

    return p2;
}

Все, по крайней мере, что я знаю, работает.

Он печатает правильный адрес памяти.

Но когда я печатаю символ (% c), он просто перестает отвечать

Как ни странно, указатель, будучи персонажем,

Не должен указывать на один байт и получать двоичное значение этого байта

И получить из него соответствующий символ.

Спасибо за любую помощь, которую вы можете мне оказать.

-2
Begah 11 Ноя 2014 в 20:02
6
Итак, вы просто получаете доступ к адресам памяти с 5000 по 5000+100*sizeof(int) и ожидаете, что это будет работать без проблем? Что ж, удачи с этим. Скорее всего, вы будете выполнять незаконный доступ к памяти в какой-то момент во время выполнения вашей программы (хотя вы только читаете, а не пишете, но это все равно выглядит довольно небезопасно). В любом случае, как формальный ответ на ваш вопрос - ваш код дает неопределенное поведение (незаконный доступ к памяти - это практический ответ).
 – 
barak manos
11 Ноя 2014 в 20:09
2
Кстати, если вы работаете с адресным пространством виртуальной памяти, ваша программа будет тестировать виртуальные адреса, не физические. Другими словами, вы будете читать со смещением от базового адреса, по которому ваш процесс был загружен ОС (который может быть разным каждый раз, когда вы запускаете свою программу или даже каждый раз, когда ОС подкачивает ее в память и из нее). ).
 – 
barak manos
11 Ноя 2014 в 20:12
Сделал ошибку с 5000+100*sizeof(int) там. Должно быть просто 5099 (включительно). Остальная часть комментария поддерживает...
 – 
barak manos
11 Ноя 2014 в 20:16

2 ответа

Лучший ответ

Современные операционные системы работают не так. Вы не можете просто прочитать системную оперативную память, потому что память приложений виртуализирована, а также ОС запрещает прямой доступ из-за политик безопасности.

ОС может предлагать некоторый API для доступа к памяти других процессов (предполагается, что у вас есть на это права). В Win32Api это ReadProcessMemory.

Может быть, какой-то другой API ОС позволяет прямое чтение из адресного пространства системы. Вы можете покопаться в Как вы читаете прямо из физической памяти?

3
Community 23 Май 2017 в 15:15
Это печально, поэтому вы не можете получить доступ к ОЗУ напрямую с помощью указателей, хотя у C не было ограничений ОС :( потому что это был такой низкий уровень.
 – 
Begah
11 Ноя 2014 в 20:40
Добавил какую-то ссылку
 – 
vlad_tepesch
11 Ноя 2014 в 20:44

Разве ваш компилятор не выдал предупреждение ниже:

warning: cast to pointer from integer of different size

В функции MemAdressPointer() вы делаете:

void *p1 = (void*) n;/* which is wrong */
0
Gopi 11 Ноя 2014 в 20:35
Нет, компилятор не выдал мне никаких исключений, он просто перестал отвечать на print("%c", *pAddr); кусок кода.
 – 
Begah
11 Ноя 2014 в 20:38
Указатель на переменную? Нет, это неправильно, это должен быть адрес переменной. Даже с этим изменением у вас здесь неопределенное поведение.
 – 
Gopi
11 Ноя 2014 в 20:42