如何简化 IDA 中的 C++ 标准模板库?

逆向工程 艾达 拆卸 C++
2021-06-17 22:53:32

我有一个 X64 DLL 文件,它大量使用 C++ 标准库。我已经在 IDA 中加载了 PDB 符号文件,并且所有子例程名称都sub_xxyz更改为std::xyz,正如预期的那样。但是有很多子程序,例如一个名字就像std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string<char,std::char_traits<char>,std::allocator<char>>(void *Dst, _BYTE *a2, __int64 a3). 太长了,不是吗;)

引擎盖下,所有这些子程序主要是做一些存储器操作malloc()memcpy()memmove()等等。因此我的问题,我可以以任何方式简化了IDA的子程序?

1个回答

虽然这个函数名确实很长,但是没有什么简单的方法可以简化它,一旦你获得了不错的C++开发经验,尤其是使用std,也不会太难理解。TLDR 的答案是,这是一个std::string对象的构造函数(具体来说,它看起来像substring(3) 构造函数,但我不是 100% 确定)。

如果您访问std::string参考页面,您会看到以下定义std::string

typedef std::basic_string<char> string; 

所述std::string类被使用定义的std::basic_string类模板,它具有三个模板参数:

  1. 用于字符串对象的字符类型。
  2. 一个对象来控制一些字符串特征。
  3. 分配器用于为类实际分配字符串缓冲区。

std::string然而,在这种情况下,只提供了第一个模板参数——另外两个是基于第一个模板参数 (char) 定义的默认参数,尽管它们可以用不同或更复杂的特征或分配器替换,但这不是std::string的情况

尽管由于未指定默认模板参数,typedef 字符串非常简单明了,但是当对象构建并由编译器实际定义时,将使用完整定义,这增加了许多样板定义。

如果我们将其拆分为各个部分,我们将看到std::basic_string正在使用并指定了三个模板参数。正如前面提到的std::string,第二个 ( std::char_traits<char>) 和第三个 ( std::allocator<char>) 是由第一个派生出来的,它们都是自己的模板,接收相同的模板参数std::basic_stringgot ( char)。

在类定义之后,两个冒号表示类命名空间下的对象定义:

::basic_string<char,std::char_traits<char>,std::allocator<char>>(void *Dst, _BYTE *a2, __int64 a3)

我们可以很容易地看到这是一个与类本身同名的函数,这是定义构造函数的已知方法。

最后,与每个函数一样,我们在括号中包含该函数接受的参数:

void *Dst, _BYTE *a2, __int64 a3

为了将完整定义简化回std::basic_string<char>,需要保留所有 std 模板类的默认模板参数,并去除被识别为默认参数的参数。虽然这不是一个非常困难的任务,但对我来说似乎有点多余。显然鼓励您自己开发这样的插件或向 IDA 开发团队建议功能改进。