病毒名称:DLL.dll
MD5 值 :9810a578f60f8ff2e376769adac9ef38
SHA1 :c605455357fe22654a7b974a2a7d301a1b0d064e
SHA256 :57e486fe50782e9fdfe73974baa88b553ba58eb5f99ef7386817a3d2e27430f5
在分析的过程中,发现代码中使用了大量的 ECX 寄存器(thiscall调用约定使用ECX寄存器传递this指针),并且在给ECX寄存器赋值之后马上调用了函数,所以我断定这应该是一个使用C++编写的样本。下面我将开始正式的分析
我们查看其导出表,发现只导出了一个函数Run911(),所以,我们从这个函数入手分析这个样本
当有程序加载这个动态库时,首先会给将DLL模块句柄保存到全局变量中。
Run911()函数,首先创建了一个线程
1、线程中初始化一个与通信有关的类CCommunicate,
2、调用CCommunicate类的成员函数ConnectServer连接到服务器
3、如果连接成功,创建了一个与通信有关的线程
(1)该线程使用选择模型与服务器进程通信
(2)如果接收到的数据长度小于等于0,则销毁当前类,
(3)否则调用CCommunicate类的DealPacket函数对接收到的数据包处理
(4)DealPacket函数对收到的数据进行存储、解码、存储解码后的数据,解析获得真正的数据,存储要传送的真正的数据
(5)在完成对数据包的解析后调用CCommunicate类中的成员变量this[33],该变量是个函数指针,但是该指针在类的构造函数中并没有初始化,该成员变量的初始化是在CManager类中进行初始化的,将CManager类this指针传递给CCommunicate类中this[33]进行保存。
4、如果与服务器连接成功则发送本机的信息到服务器,
5、构造了一个CManager类的派生类CKernelManager类,在虚基类CManager中会保存当前通信类的this指针,将CKernelManager类的this指针保存至通信类的成员变量this[33]中,而CKernelManager类的this指针保存的是CKernelManager的虚表地址,所以每当通信类收到数据时,就会调用虚表在中的函数。
CKernelManager的虚表中的函数AnalyseReceiveData_KernelManager()实现的功能是根据接收到的数据的第一个字节的不同而选择不同的功能
Case 0:CMD管理,创建一个线程执行CMD管理功能
Case 10:进程管理,创建一个线程执行进程管理功能
Case 30:窗口管理,创建一个线程执行窗口管理功能
Case 50:文件管理,创建一个线程执行文件管理功能
Case 51:通知管理,创建一个线程执行通知管理功能
Case 80:桌面管理,创建一个线程执行桌面管理功能
Case 204:回传204
6、循坏等待退出信号
对上面的6个不同的功能线程进行分析。
1、Case 0:Cmd管理:
创建一个新的通信类对象,用来接收服务器发送的有关CMD管理的数据
连接至服务器,
创建CManager的派生类CCmdManager的对象
(1) 初始化成员变量,CCmdManager的成员变量如下,
(2) 创建了两条管道,分别用于向CMD输入数据和从CMD中读出数据
(3) 获得cmd.exe的完整路径
(4) 以隐藏的方式启动cmd.exe进程,并且设置标准输入输出为管道
(5) 向服务器发送数据1;
(6) 启动一个CmdManagerWorkThread线程对管道中的数据进行处理,管道中的数据并且将管道中的数据发送到服务器
等待退出信号
CCmdManager的虚表中的函数AnalyseReceiveData_CmdManager()实现的功能:如果接收到的数据第一个字节为2,设置this[2]的Event为授信,否则,将收到的数据写入到CMD管道中
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)