2009-05-06 90 views
2

我正在处理一个未公开的API,我正在尝试做一些逆向工程 - 不要担心这不是恶意的,只是试图以创造性的方式实现用例。如何在不知道名称的情况下访问C结构的成员?

我有一个指向C结构的指针。有没有办法让我通过检查记忆来确定这个结构有多少个成员?他们的价值?

我怀疑实际的成员名称不可用,但也许他们是?

回答

3

根据内存布局,您可能能够确定结构在哪里结束,并且通过了解结构在较高级别上做了什么可以猜测成员(小心对齐)。但是,除非代码带有调试符号,否则没有关于知道名称的运气。在这种情况下,这很容易。打破使用结构的地方,并在调试器中检查它。

编辑:
假设你没发现什么成员结构包含的,你也知道,你的编译器使用相同的定位,那么你可以在你的代码中定义结构的传真和使用的一个指针结构指向真实结构的地址。然后,您可以在代码中轻松访问所有元素。

+0

所以我可以这样假设: struct Foo {int_lod; }; Foo f; Foo * pf =&f; int * pFirstMember = &f[1]; // ?? – Marplesoft 2009-05-06 14:55:28

+0

@Marplesoft,看看数据结构对齐,你可以在SO或WP上找到关于它的信息。基本上保证结构的第一个元素与结构本身具有相同的地址,即pFirstMember =(int *)&f应该工作,当然只有当它真的是一个int。 – quinmars 2009-05-06 16:02:19

4

不,不可能仅从内存中确定成员的“结构”。

1

不幸的是,您没有C或C++中的类型信息。在C++中提供了一些RTTI,它允许dynamic_cast检查向下转换的有效性。但它没有提供关于成员(姓名或类型)的信息。

+0

你需要完整的源代码才能工作。如果链接器看不到引用,则链接器可能会很好地去除所有RTTI信息。 – MSalters 2009-05-06 15:51:20

0

在C中,我通常会创建一个包含所有成员名称,偏移量和大小的元结构。它看起来像这样:

#define MEMBER(name,str) { #name, offsetof(struct str, name), sizeof(*(&((struct str *)(0))->name) } 
struct A { char *name, int offset; int size; } = { 
MEMBER(name,A), 
MEMBER(offset,A), 
MEMBER(size,A) 
}; 

然后,如果需要创意铸塑,您可以列出结构的所有成员。

5

你不能。你所能做的就是检查记忆,并尝试猜测。

例如,指针值有时可以很容易找到,因为它们通常在相同的“常规区域”。如果您有一个结构地址,请以数字方式查找“关闭”的值(平台的指针大小,通常为32或64位)。

在您的平台上查找某些“常见”浮点数的位模式并查找这些数值也许值得研究。在这里,当然知道应用程序和/或领域的帮助,或许有一些“应该”存在的价值,那么这些价值就是寻找的自然事物。

如果您有权访问接受和/或返回结构的API中的任何函数,那么您可能需要尝试调用它们并检查差异,这可以为正在发生的事情提供线索。

在该说明中,您当然也可以遍历首先分配/创建结构的代码,以查看它在哪里执行的操作。

1

我会说,无论你想要做什么,有一个更好的方法。

相关问题