• 我们在哪一颗星上见过 ,以至如此相互思念 ;我们在哪一颗星上相互思念过,以至如此相互深爱
  • 我们在哪一颗星上分别 ,以至如此相互辉映 ;我们在哪一颗星上入睡 ,以至如此唤醒黎明
  • 认识世界 克服困难 洞悉所有 贴近生活 寻找珍爱 感受彼此

恶意代码技术理论:RTTI(运行时类型信息)

恶意代码技术理论 云涯 2年前 (2023-05-12) 1153次浏览

RTTI概述

运行时类型信息(RTTI,Run-time Type Information)是一种在C++中用于在运行时获取和使用类型信息的机制。C++引入这个机制是为了让程序在运行时能根据基类的指针或引用来获得该指针或引用所指的对象的实际类型。但是现在RTTI的类型识别已经不限于此了,它还能通过typeid操作符识别出所有的基本类型(int,指针等)的变量对应的类型。RTTI允许程序在运行时检测和处理对象的类型。

通俗来说:当我们在编程时,有时候我们需要在程序运行时去查看或检查一个变量或对象的类型。在C++中,就是通过RTTI来实现这个功能的。你可以把RTTI看作是C++的一种工具,它能够帮助我们在程序运行的过程中去识别和处理对象的类型。

例如,我们有一种动物的基类(Animal),然后有很多派生类,比如狗(Dog)、猫(Cat)等。现在我们有一个Animal类型的指针,它实际上指向的是一个Dog对象。然而,由于指针是Animal类型的,编译器并不知道这个事实。这时,我们就可以使用RTTI的dynamic_cast来检查这个指针是否真的指向一个Dog对象。

再比如,我们想在运行时获取一个对象的类型信息,我们可以使用RTTI的typeid操作符。这个操作符能返回一个表示类型信息的对象,我们可以从这个对象中获取类型的名字,或者比较两个对象是否是同一种类型。

RTTI主要包括以下两个主要的元素:

  1. 动态类型识别(dynamic_cast):dynamic_cast操作符可以在运行时检查某个对象是否属于某种类型。如果该对象是指定类型(或是从指定类型派生的类型)的一个实例,dynamic_cast将成功;否则,它将失败(通常会返回一个空指针)。这种类型检查是在运行时进行的,因此,它可以应对程序在编译时无法知道的类型问题。
  1. 类型信息(typeid):typeid操作符可以在运行时获取一个对象的类型信息。这个操作符返回一个std::type_info对象,该对象包含了关于类型的信息,如类型的名字等。你可以比较两个std::type_info对象来确定两个对象是否属于同一种类型,或者检查一个对象是否属于特定类型。

RTTI通常在处理复杂的类层次结构时最有用,例如在需要处理基类指针或引用,但又需要知道它们是否指向派生类对象的情况下。然而,RTTI也有一些性能和内存的开销,因此在不需要的情况下应避免使用。

在一些编程语言(如Java或C#)中,类似的运行时类型信息功能是内置的,并且被广泛使用。然而,在C++中,RTTI常常被视为一种应在必要时才使用的高级特性。

名称修饰概述

在C++中,由于存在函数重载、命名空间、类等特性,一个函数或者变量的全名不仅包括它的名字,还可能包括它的参数类型、所属类名、命名空间等信息。编译器在编译的时候,会把这些信息都编码到名字中,以确保每个函数或变量的名字在整个程序中是唯一的。这个过程就叫名字混淆或修饰。这是在C++编译阶段生成的,用于在链接阶段保持函数和类名称的唯一性。

.?AVCHTTP_Protocol@@就是一个混淆后的名字。在这个名字中,.?AV是编译器添加的特殊前缀,表示这是一个类的名字;CHTTP_Protocol是类名;@@是编译器添加的结束标记。所以,.?AVCHTTP_Protocol@@代表的是一个名为CHTTP_Protocol的类。

关联分析

名称修饰后的类名可能在RTTI系统中被用于获取和使用类型信息,可以在在 RTTI 系统中起到关键作用。

名称修饰(Name Mangling)和运行时类型信息(RTTI)在某些方面是相关的,尤其在C++编程中。

名称修饰是编译器用来处理C++中允许的函数重载的方法。因为C++允许你定义多个同名但参数列表不同的函数(也就是函数重载),所以编译器需要一种方法来区分这些函数,以便在链接时能找到正确的函数。这就是名称修饰的作用。名称修饰后的字符串(也就是你看到的那种带有@@符号的字符串)包含了函数名、参数类型和数量等信息,这样链接器就可以找到正确的函数。

而运行时类型信息(RTTI)则是在运行时确定对象的类型的机制。在C++中,如果你有一个指向基类的指针,但是实际上它指向的是一个派生类对象,你可以使用RTTI来确定这个对象的实际类型。这是通过查询类型信息对象(type_info)来实现的,这个对象包含了类型的名称等信息。

这两者之间的联系在于,都涉及到类型信息的处理。名称修饰中编码的类型信息是编译时确定的,主要用于链接;而RTTI处理的类型信息则是运行时确定的,主要用于动态类型识别和转换。

同时,名称修饰后的类名或函数名在一些情况下也可能被包含在RTTI的类型信息中。因此,在进行二进制代码分析或反向工程时,我们可能会看到这两种情况下生成的名称修饰后的字符串,这也是为什么有些工具或报告会将它们称为“RTTI工件”。

我们先来看一个关联的例子:

此次分析的DLL和已知BlindingCan恶意软件都包含相同的RTTI工件,这些工件实际上是经过名称修饰的类名(如.?AVCHTTP_Protocol@@.?AVtype_info@@等)。这些名称修饰后的类名可以反映程序内部的类和对象结构,并可能被用作RTTI的一部分,用于在运行时获取对象的类型信息。当两个样本包含相同的RTTI工件时,这意味着它们可能具有相似的内部结构和功能,因此,这是一个强烈的关联证据。

 

 

 


云涯历险记 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:恶意代码技术理论:RTTI(运行时类型信息)
喜欢 (0)