我有一个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中的那些子例程吗?是什么意思?

评论

该插件可能对您有帮助。 github.com/zyantific/REtypedef

#1 楼

尽管此函数名称确实很长,但是一旦获得了不错的C ++开发经验(尤其是使用std),就没有简单的方法可以简化它,也很难理解。 TLDR的答案是这是std::string对象的构造函数(特别是看起来像substring(3)构造函数,但我不是100%确信)。

如果访问std::string参考页,您将看到std::string的定义:

typedef std::basic_string<char> string; 


std::string类是使用std::basic_string类模板定义的,该模板具有三个模板参数:


用于字符串对象的字符类型。
用于控制某些字符串特征的对象。
用于为该类实际分配字符串缓冲区的分配器。

但是,在std::string情况下,仅提供第一个模板参数-其他两个是基于第一个模板参数(char)定义的默认参数,尽管可以用其他或更复杂的特征替换或分配器,对于std::string类不是这种情况。

尽管由于未指定默认模板参数,所以typedef字符串非常简单明了,但在编译对象并由编译器实际定义对象时,会使用完整定义,从而增加了许多样板定义。

如果将其拆分成几个部分,我们会看到正在使用std::basic_string并指定了三个模板参数。如对std::string所述,第二个(std::char_traits<char>)和第三个(std::allocator<char>)是由第一个派生的,它们本身都是模板,接收相同的模板参数std::basic_string得到(char)。

定义,两个冒号表示类名称空间下对象的定义:

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


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

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

,则需要保留所有std模板类的默认模板参数,并去除那些被识别为默认模板的参数。尽管这不是一项艰巨的任务,但对我来说似乎有点多余。显然,我们鼓励您自己开发这样的插件,或者向IDA开发团队提出功能改进建议。

评论


@Biswapriyo最后一段讨论了实际上简化这些名称的任务,但是正如我提到的那样,我个人认为它是多余的。

– NirIzr
18年6月5日在21:50

@Nirlzr:可能是一个值得尝试的工作,它解析类型容器(标准容器的专业化)中的typedef事件,并使用IDAPython脚本或插件使名称更具可读性。但是,是的,这看起来像是一个繁琐的任务。首先,它可能需要一些适当的C ++解析器,如libclang。

– 0xC0000022L♦
18年6月5日在21:53

@ 0xC0000022L不确定c ++解析,因为这些函数名称并不是真正的自由字符串,而是编译器混合的名称。编译器之间略有不同(显然IDA已支持),但基本上我认为它的结构足以让您不需要实际的C ++解析,至少在插件方面。我相信您也可以在不进行任何C ++解析的情况下,抓取一些数据库或网站来获取默认值。 YMMV和我没有详细介绍,因为我认为没有人会为此浪费时间,TBH。

– NirIzr
18年6月5日在21:58

@Biswapriyo我在这里还为不熟悉std且难以读取函数名称的任何人提供了详细信息。目标不是要说明您提供的一个名称,而是要显示std / template名称的构建方式以及不熟悉的读者应如何解释它们。

– NirIzr
18年6月5日在21:59

@NirIzr:我指的是在STL标头中进行筛选的部分,寻找与typedef basic_string wstring类似的typedef实例,用于任意数量的容器类。因为那是短名称的来源(std :: string,std :: wstring等)以及默认值已知的地方(假设您可以解析C ++)。使用libclang确实比以前要容易得多(例如,尝试解析GCC的XML AST输出)。

– 0xC0000022L♦
18年6月5日在22:01