2011-09-01 20 views
16

Me preguntaba si era posible acceder a un bloque directo de memoria usando C/C++ y tomar el valor. Por ejemplo:Accediendo a direcciones de memoria directa y obteniendo los valores en C++

int i = 15; 
int *p = &i; 
cout << &i; 

Si tomaba el valor impreso aquí, eso me dará la dirección de la variable i, que contiene el valor 15. Me limitaré a decir que imprime 0x0ff9c1 para este ejemplo. Si tengo un programa separado que declara un puntero al igual que ...

int *p = 0x0ff9c1; 
cout << *p; 

¿Sería posible imprimir que el 15 que la otra aplicación se coloca en el bloque de memoria 0x0ff9c1? Sé que la declaración de mi puntero con la dirección de la memoria es incorrecta, de lo contrario no estoy seguro de cómo hacerlo. He intentado usar memcopy pero tampoco he podido hacer que funcione. Sé que esto es posible de alguna manera ya que tengo un programa llamado Cheat Engine que modifica los valores de la dirección de la memoria del juego para obtener ventajas injustas. He tenido éxito en colocar la ubicación de la memoria impresa y obtener el valor (15) a través de Cheat Engine. Mi objetivo es hacer esto usando C++. Si esto es demasiado confuso, básicamente me gustaría acceder a una variable que otra aplicación almacena usando su dirección de memoria e imprimir el valor. Estoy usando Windows 7 x64 con el compilador MinGW si eso es importante. ¡Gracias!

PD: Voy a publicar una imagen de lo que hace Cheat Engine para dar una mejor idea. enter image description here

+5

+1 para tales experimentos. – Nawaz

+3

lea un libro sobre la memoria virtual. Como nota adicional: Linux y algunas versiones nuevas de Windows emplean la distribución aleatoria de la pila, por lo que las direcciones de las variables locales variarán entre las ejecuciones del programa. – unkulunkulu

+0

Sí, aunque la experimentación descubrí eso. Estaba pensando en exportar la dirección a través de un argumento de ejecución al segundo programa. Buscaré en la memoria virtual, gracias por la sugerencia. – llk

Respuesta

6

Los dos procesos tienen espacios de direcciones separados. Un proceso no puede acceder a otra memoria de procesos a menos que sea memoria compartida explícitamente.

+0

@Shadowalker Basándose en la respuesta de Ed, la dirección dentro del puntero no es la dirección física real dentro de su RAM, es solo la dirección local de la aplicación (en cierto sentido, una dirección virtual). –

+0

¿Cómo los depuran y otros programas como Cheat Engine acceden a ellos entonces? Según tengo entendido, OLLYDbg y Cheat Engine no instalan controladores kernel ni ningún gancho serio. Sin embargo, podría estar equivocado. – llk

+1

Que bajo Windows usaría 'ReadProcessMemory()' y 'WriteProcessMemory()'. – trojanfoe

1

En general, generalmente no es posible que un programa modifique la memoria de otro. El sistema hace todo lo posible para garantizar esto. Si no fuera así, ningún programa sería seguro. Esto es particularmente cierto en todas las variantes de Unix en las que he trabajado, aunque no en todos los SO patentados que he visto.

Tenga en cuenta que ninguna de estas reglas se aplican al núcleo ...

También hay un paradigma de programación llamado memoria compartida, pero hay que establecer explícitamente que hasta.

Respuesta corta: generalmente no se puede hacer eso. Creo que mencionó Windows. No sé nada sobre Windows, por lo que su kilometraje puede variar.

+0

La respuesta se enfoca de forma un tanto errónea y estrictamente no exactamente correcta, porque los sistemas operativos proporcionan los medios para que los procesos modifiquen la memoria de los demás. La respuesta debe centrarse en el hecho de que los espacios de memoria son diferentes, por lo que los punteros con valores iguales hacen referencia a diferentes ubicaciones de memoria física en diferentes procesos. – unkulunkulu

+0

No creo que se justifique una lección de memoria virtual completa, aunque tal vez sea necesaria. –

5

No se puede hacer de una manera independiente de la plataforma en C++. Si bien no he usado este "motor trampa" específicamente, es casi seguro que esté usando la misma API especial que usa un depurador. El código será específico para Windows, y requerirá un cierto nivel de privilegio en el proceso en ejecución.

(Por ejemplo, si está utilizando Visual Studio, y ejecute un programa de ella en un modo de depuración, Visual Studio puede ver y modificar los valores en ese programa.)

no he escrito en un depurador un tiempo, así que no sé donde un buen lugar para empezar a trabajar en la API de depuración es, pero se puede buscar en la web para las cosas les gusta este artículo:

http://www.woodmann.com/fravia/iceman1.htm

+0

Nota: Como otros señalan, la API del depurador no es la única API con privilegios que ciertas plataformas pueden ofrecer para explorar en otros procesos. (De hecho, algunos sistemas incorporados no se preocupan por espacios de direcciones separados y todavía le permiten compilar fuentes C y C++, por lo que su ejemplo "ingenuo" podría funcionar en esas plataformas muy básicas.) Estaba adivinando que las probabilidades eran la API Debug era lo que usaba, a diferencia de los ganchos que usa SpyXX o lo que sea. – HostileFork

3

Si desea cambiar la memoria utilizada por otro proceso, una forma sería inyectar su código en el otro proceso. Desde ese punto, puede hacer lo que quiera con la memoria del otro programa como si fuera de su propiedad.

Buscar alrededor de remote thread creation o hooking. Aquí hay más que unas pocas preguntas (y here, para empezar).

Cuestiones relacionadas