2010-03-13 44 views
1

你怎么会在内存中找到一个对象,让说你有一个结构定义为:查找内存中的对象(结构) - 如何?

struct POINT { 
    int x; 
    int y; 
}; 

我怎么会扫描我的应用程序的内存区域找到这个结构的情况下,这样我也能阅读出来吗?

谢谢R.

+5

你究竟想通过这个来实现什么? – randomThought 2010-03-13 00:08:26

+1

首先,这些实例是如何迷失在内存中的?你有做新的POINT吗?新POINT;'然后尝试找到它们? – UncleBens 2010-03-13 00:09:58

回答

4

你不能没有添加类型信息的结构。在内存中,这样的结构不是别的,而是2个整数,所以你不能识别它们比识别任何其他对象更好。

+2

...即使添加了类型信息,它可能会很难(你怎么知道哪些位代表类型信息?) – UncleBens 2010-03-13 00:07:30

+0

你将不得不创建一个相当独特的字节序列来识别它(每个人都有'0xDEADBEEF'? ) – Wolph 2010-03-13 00:16:26

2

你不能。你必须知道布局以知道哪部分内存必须代表一个变量。这是一种协议,这就是为什么我们使用基于文本的语言代替原始值。

2

你不会 - 你怎么区分随机噪声的两个任意整数?

(但在源代码中给出Point p;,可以使用操作符地址获得其地址... Point* pp = &p;)。

1

无法识别该结构。您需要将结构放置在可以找到的位置,堆栈或堆上。

有时候数据结构被标记有识别信息来协助调试或内存管理。作为数据组织的一种手段,它是最糟糕的可能方法之一。

您可能需要大量的一般阅读内存管理

1

有没有这样做的标准方式。该平台可能会指定一些允许您访问堆栈和免费商店的API。此外,即使你做了,没有任何额外的信息,你如何确定你正在阅读POINT对象而不是几个int?编译器/链接器可以读取它,因为它处理(虽然是虚拟的)地址,并且比你有更多的信息(和控制)。

3

你不能。结构体不存储任何类型的信息(除非它们具有虚拟成员函数),所以你不能将它们与任何sizeof(POINT)字节的其他块区分开来。

为什么你不把你的点存储在一个向量或东西?

1

你不行。类似的东西可能在某些“标记”架构上也是可能的,它们也支持用户定义类型的标记对象。但是在传统架构中,仅仅通过查看原始内存内容来确定存储在内存中的内容是绝对不可能的。

您可以更接近于通过引入一个独特的签名改成类型实现你想要的东西,像

struct POINT { 
    char signature[8]; 
    int x; 
    int y; 
}; 

,并小心地设置一些固定的,“独特”的POINT类型的每个对象模式,并然后在记忆中寻找那种模式。如果它是您的应用程序,您可以确定可以确定每个模式实例都是您的POINT对象。但总的来说,当然,不可能保证你发现的图案属于你的物体,而不是纯粹意外地存在。

+0

您是否知道具有C++编译器并支持任何类型标记的体系结构? – 2010-03-13 00:13:05

+0

将校验和与签名一起使用可能有助于防止误报 - 其他数据有可能包含与签名相同的字节序列。 – 2010-03-13 00:14:46

+0

@Roger Pate:在现实生活中?不,我不知道。 – AnT 2010-03-13 02:32:15

2

简答:你不能。任何(适当对齐的)8个字节的序列都可能代表一个POINT。实际上,一个int数组将与POINTS数组无法区分。在某些情况下,你可以利用编译器实现的知识来做得更好。例如,如果结构体具有虚函数,则可以查找正确的vtable指针 - 但也可能存在误报。

如果你想跟踪的对象,则需要在其构造登记他们和他们的析构函数注销他们(支付的性能损失),或给他们自己的分配器。

1

其他人都说过的话是真的。在内存中,你的结构只是几个字节,没有什么特别的区别它。但是,如果您觉得自己有点黑客攻击,那么您可以查看C库的内部结构,并找出内存在堆中的存储位置以及它的显示方式。例如,this link显示了如何在一个特定的系统中分配东西。

有了这方面的知识,你可以扫描你的堆找到分配的块是sizeof(POINT),这将大大缩小搜索范围。如果您查看表格,您会注意到malloc()调用的文件名和行号正在被记录下来 - 如果您知道源代码中的分配POINT s的位置,则可以将其用作参考。

但是,如果你的结构被分配在堆栈上,那么你的运气不好。