【问题标题】:How do I see inside opaque data types?如何查看不透明数据类型的内部?
【发布时间】:2019-03-13 19:33:09
【问题描述】:

我知道这种做法违背了不透明数据类型的全部观点,但出于逆向工程的目的,人们如何着手研究不透明数据类型?

【问题讨论】:

  • C 没有任何自省——一旦代码被编译,之后你所能做的就是非常痛苦的逆向工程。编译前比较容易:在相关源码中找到定义。
  • 您可以在系统上的标头中查看是否可以找到fpos_t 的定义。如果做不到这一点,你必须希望你在一个开源系统上,并查看你平台上 C 库的开源代码。没有简单、可靠的方法可以从目标代码中查看真正不透明类型的定义。 (不过,有些不透明类型并不像其他类型那样不透明。您可能会发现更多关于 FILE 的信息,而不是您对不透明类型的预期。)
  • @JonathanLeffler 不过,我并不完全理解;要使fpos_t 工作,完整的定义必须在某个地方,否则它只是一个无用的绰号,程序将无法运行。老实说,我有点讨厌人们这样做。我了解隐藏不必要的细节或限制访问以防止人们搞砸任何事情的用途,但我觉得我们正朝着迫使人们只在高水平上操作的方向前进。
  • fpos_t的具体情况下,使用它的函数是fgetpos()fsetpos()。由于接口,定义不能完全不透明;调用代码必须能够编写fpos_t pos; 并将&pos 传递给函数。因此,该类型不是不透明的,即使它没有记录它是什么。这意味着你可以在系统头文件中找到它——这些信息必须以某种方式提供给编译器(但它可能很神奇)。
  • 参见File Streams 上的 POSIX。它说: 每个面向宽的流都有一个关联的mbstate_t 对象,该对象存储流的当前解析状态。对fgetpos() 的成功调用应将这个mbstate_t 对象的值的表示存储为fpos_t 对象的值的一部分。稍后使用相同存储的fpos_t 值成功调用fsetpos() 将恢复关联的mbstate_t 对象的值以及受控流中的位置。

标签: c reverse-engineering information-hiding opaque-pointers


【解决方案1】:

除非您已经拥有源代码,否则在不了解特定系统的底层表示的情况下,没有可行的方法可以“破解”不透明类型。破解它需要在运行时跟踪对不透明指针的每次访问并查看它的去向,然后从那里开始猜测。

相反,您可以谷歌例如 Github 上的 glibc 源代码。在 stdio.h 中有一个条件 typedef 指向内部标头中的 __fpos_t__fpos64_t

__fpos_t.h

typedef struct _G_fpos_t
{
  __off_t __pos;
  __mbstate_t __state;
} __fpos_t;

__fpos64_t.h

typedef struct _G_fpos64_t
{
  __off64_t __pos;
  __mbstate_t __state;
} __fpos64_t;

不是很令人兴奋,但你可以从那里继续在 Github 上追踪这些不同的类型,看看它们最终归结为什么。很可能是整数和枚举。

【讨论】:

    【解决方案2】:

    在 VC++ 中定义为

     typedef __int64 fpos_t;
    

    这又是

    typedef long long fpos_t;
    

    如果您想知道它在汇编代码中的样子,那么只需编写一个示例程序,在调试模式下运行它,然后在调试时打开Disassembly Window 以查看后面的代码。

    【讨论】:

    • 就这样?这有点令人沮丧。试图隐藏别名有什么意义?
    猜你喜欢
    • 1970-01-01
    • 2013-07-12
    • 2021-12-09
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    相关资源
    最近更新 更多