2011-09-01 243 views
16

我想知道是否可以使用C/C++访问直接内存块并获取值。例如:访问直接内存地址并获取C++中的值

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

如果我把打印的价值在这里,那会给我的变量i,后者含有值15.我只想说这打印出来0x0ff9c1在这个例子中的地址。如果我有一个单独的程序,它声明,像这样的指针...

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

是否可以打印出15放置在内存块0x0ff9c1其他应用程序?我知道我的指针声明与内存地址是不正确的,我不确定如何去做,否则。我曾尝试使用memcopy,但我还没有能够得到这个工作。我知道这是可能的,因为我有一个名为Cheat Engine的程序,它修改游戏内存地址值以获得不公平的优势。我已经成功地放置了打印的内存位置并通过作弊引擎获得了值(15)。我的目标是使用C++来做到这一点。 如果这太混乱了,基本上我想访问另一个应用程序使用其内存地址存储的变量并打印出该值。如果有问题,我正在使用Windows 7 x64和MinGW编译器。谢谢! PS:我会张贴一张关于Cheat Engine做什么的图片来提供一个更好的主意。 enter image description here

+5

+1。 – Nawaz

+3

读一本关于虚拟内存的书。作为附加说明:linux和一些新版本的Windows采用堆栈随机化,所以程序执行时局部变量的地址会有所不同。 – unkulunkulu

+0

是的,虽然我发现了实验。我正在考虑通过执行参数将地址导出到第二个程序。我会研究虚拟内存,谢谢你的提示。 – llk

回答

6

这两个进程有不同的地址空间。一个进程不能访问另一个进程内存,除非它是明确的共享内存。

+0

@Shadowalker基于Ed的回答,指针内的地址不是RAM内部的实际物理地址,它只是应用程序本地的地址(从某种意义上说是虚拟地址)。 –

+0

调试器和其他程序如Cheat Engine如何访问它们?根据我的理解,OLLYDbg和Cheat Engine不会安装内核驱动程序或任何严重的挂钩。但我可能是错的。 – llk

+1

在Windows下使用'ReadProcessMemory()'和'WriteProcessMemory()'。 – trojanfoe

1

通常,一个程序通常不可能修改另一个程序的内存。系统竭尽全力确保这一点。如果没有,程序就不安全。在我所使用的所有Unix变体中,尤其如此,尽管不是我见过的所有专有操作系统。

注意,没有这些规则适用于内核...

还有一个名为共享内存编程范式,但你必须明确地设置了。

简答:你不能这样做。我相信你提到过windows。我对Windows一无所知,所以你的里程可能会有所不同。

+0

答案的重点有点不对,严格来说不完全正确,因为OS提供了进程修改彼此内存的方法。答案应该集中在内存空间不同的事实上,因此具有相同值的指针在不同进程中引用不同的物理内存位置。 – unkulunkulu

+0

虽然可能需要,但我并不觉得完整的虚拟记忆课有保证。 –

5

你不能在C++中以平台不可知的方式做到这一点。虽然我没有专门使用这个“作弊引擎”,但它几乎可以肯定地使用调试器使用的相同的特殊API。该代码将特定于Windows,并且您将在运行过程中需要一定的特权级别。

(例如,如果你使用Visual Studio,并在调试模式,从它执行程序,Visual Studio可以看一下,并在该程序中修改值。)

我没有写在调试器一段时间,所以我不知道哪里的好地方,以获得有关调试API是开始,但你可以在网络上搜索的东西喜欢这篇文章:

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

+0

注意:正如其他人指出的那样,调试器API不是唯一的特权API,特定平台可以提供其他过程。 (事实上​​,一些嵌入式系统根本不用单独的地址空间,仍然可以编译C和C++源代码,所以你的“天真”例子实际上可能适用于那些非常基础的平台。)我只是猜测出现的可能性是调试API是它使用的 - 与SpyXX使用的钩子相反。 – HostileFork

3

如果你想改变另一个进程使用的内存,一种方法是将代码注入到另一个进程中。从这一点上,你可以做任何你想要的其他程序的内存,就好像它是你的拥有者一样。

搜索周围的remote thread creationhooking。这里有几个关于它的问题(和here,对于初学者)。