问题
题目提示是:
假设一个名为Lab11-02.ini
的可疑文件与这个恶意代码一同被发现
我们这次把分析过程放在上面
我们还是一样的先做一些静态的分析
这里有一个我们以前没见过的函数叫CreateToolhelp32Snapshot
这个函数在MSDN
里面的定义是这样的
获取指定进程的快照, 以及这些进程使用的堆、模块和线程
书中对这个导入函数的解释是
搜索一个进程或者线程列表的导入函数
当然,我们还可以看见一些包括就像CopyFile
和CreateFile
函数,说明这个代码会操纵一些文件
还有三个操作注册表的函数
之后我们查看一下字符串有哪些
这里我们看到有趣的字符串有
installer
THEBAT.EXE
OUTLOOK.EXE
MSIMN.EXE
wsock32.dll
SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows
spoolvxx32.dll
AppInit_DLLs
\\spoolvxx32.dll
\\Lab11-02.ini
这些,尤其是AppInit_DLLs
需要我们注意
对于这个键值的解释有
AppInit_Dlls
键值位于注册表
HKLM\Microsoft\Windows NT\CurrentVersion\Windows
下面,相对于其他的注册表启动项来说
这个键值的特殊之处在于任何使用到User32.dll 的EXE、DLL、OCX等类型的PE文件都会读取这个地方
并且根据约定的规范将这个键值下指向的DLL文件进行加载,加载的方式是调用
LoadLibrary
众所周知,Windows服务程序的启动时机是可以非常早的,往往在用户登录之前就完成启动了
而这个时候最常见的Run键值还不一定被处理完,而且Windows服务程序拥有相当高的权限
(默认是Local System,可以对系统里面所有的资源进行操作)
因此如果一个恶意软件被加载到Windows服务里面,那么是会非常危险的
前文提到,任何进程使用了User32.DLL,都会对AppInit_Dlls键值指向的DLL进行加载,如果是一个Windows服务程序,也不例外
上面这些话的意思就是,这个Appinit_DLLs
驻留方式是在系统启动之前就会把恶意DLL
加载在Windows
服务中
而\Lab11-02.ini
表明了这个程序有可能使用我们看到的那个Lab11-02.ini
其中还有一些像OUTLOOK.EXE
和THEBAT.EXE
还有MSIMN.EXE
的字符串,书上说
这些都是邮件客户端,说明这个程序有可能操作这些客户端来发送邮件什么的
然后我们打开Lab11-02.ini
来看看是什么
这个没有意义的乱码说明这个程序很可能有加解密的功能
CHMMXaL@MV@SD@O@MXRHRCNNJBNL
字符串中还有wsock32.dll
,这个说明这个程序可能会使用网络的功能
还有那么几个RCPT
的字符串,这个查了一下
RCPT是RECIPIENT 的缩写,为SMTP协议中的一个命令
说明这个代码很有可能用了邮件客户端来发送了一个邮件之类的
然后我们开始准备运行这个DLL
这里我们运行的时候要加一个DLL
导出函数名字
这个名字就DLL
的导出函数
我们可以在这里来找
现在我们运行,运行的同时记得做好系统的监控
rundll32.exe Lab11-02.dll, installer
我们看到了一个弹窗错误(因为我没加路径)
后来再次执行之后会发现,什么也没出现,就结束了,然后我们看看我们的监控的结果
这里删除了两个,分别是
新增加的键
这里是在浏览器的位置增加的键
以改变的值里面有这么一个需要注意的
这里在这个位置上修改AppInit_DLLs
的值,修改为spoolvxx32.dll
,说明很有可能这里有个spoolvxx32.dll
被释放出来了
然后我们看看Procmon
和Procexp
的监控情况,对于不会常驻内存的进程来说,Procexp
没多大作用
我们看Procmon
的记录
我们设置过滤为Process name
为rundll32.exe
因为注册表的值我们刚刚已经比对过了,现在我们再设置一个过滤是操作CreateFile
这里要注意的就是虽然DLL
调用了CreateFile
,但是不一定都是创建文件,有可能是打开文件的操作
我们最后找会发现在
C:\WINDOWS\system32\
下面,创建了一个文件叫
spoolvxx32.dll
其实这个文件和我们的Lab11-02.dll
是一样的,最后恶意代码会尝试在C:\WINDOWS\system32\
中打开Lab11-02.ini
为了让这个恶意代码能访问这个文件,我们把这个Lab11-02.ini
放在C:\WINDOWS\system32\
下
这个恶意代码会在最后将自己加载到user32.dll
中,然后所有加载了user32.dll
的进程也会加载了它
然后我们开始用IDA
来分析它看看~~
然后我们可以看到这个导出函数的大概调用图,虽然没什么用
导出函数installer
的内部第一个函数调用是RegOpenKeyExA
这是打开键的函数,我们主要看他的键的位置
SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
如果RegOpenKeyExA
这个函数执行成功,函数返回ERROR_SUCCESS
也就是0
在test
之后,因为eax
为0
,那么ZF
=1
,jnz
不会跳转
之后函数会来到这里执行
这里的第一个函数调用是strlen
,计算字符串长度的
这个函数的返回值就是eax
,成为了下一个函数调用RegSetValueExA
的最后一个参数cbData
这里调用RegSetValueExA
来将键AppInit_DLLs
的值改为了spoolvxx32.dll
之后代码关闭了设置键的句柄
之后函数就会来到这里,这里调用的第一个函数是sub_1000105B
,我们看看这个函数是干什么的
这个函数是来查询系统的目录的,函数的返回值是目录的长度,目录的路径是保存到了Buffer
这里,调用完函数之后,代码将路径赋值给了eax
来返回
然后下面的函数调用是
这里的eax
其实就是上面那个sub_1000105B
函数调用之后查出来的系统路径,一般就是C:\WINDOWS\system32\
写成伪代码的形势就是
strncat("C:\WINDOWS\system32\", "\\spoolvxx32.dll", 104h)
这个就是最后会得到一个这样的字符串
C:\WINDOWS\system32\spoolvxx32.dll
之后
开始调用函数CopyFileA
这个从字面意思就是赋值文件的意思
这里的入参lpNewFileName
其实就是上面组装成的字符串C:\WINDOWS\system32\spoolvxx32.dll
,因为strncat
的第一个参数是指向[ebp+Dest]
的
而lpExistingFileName
的意思是我们要复制的文件名字
而这个lpExistingFileName
是个260
大小的字符数组
因为这个函数里面并没有调用ExistingFileName
这个参数,所以我们不知道这个变量的值是从哪里来的,不过我猜想就是我们现在Lab11-02.dll
这个文件的绝对路径
之后就是一个CopyFileA
之后导出函数就退出了
下面我们看看DLL
的主函数
其中这里的hinstDLL
是
DLL模块的句柄,该值是DLL的基地址。 DLL的HINSTANCE与DLL的HMODULE相同
而fdwReason
是
原因码说明了为什么调用DLL入口函数
这里将DLL
文件的基地址赋值到了dword_100035a4
中去
还比较了fdwReason
和1
的大小
其中1
代表的意思就是
由于进程启动或由于调用LoadLibrary,DLL正被加载到当前进程的虚拟地址空间中, DLL可以使用此机会初始化任何实例数据或使用TlsAlloc函数分配线程本地存储(TLS)索引
如果这个值等于1
的话,cmp
之后ZF
=1
则jz
会跳转,如果不跳转,就会退出了DLLMain
之后
我们上面说的hinstDLL
指向的是这个DLL
的基地址
所以这里的GetModuleFileNameA
其实返回的是当前这个DLL
的绝对路径
之后调用memset
分配了几个空间
所以我们这里知道了,ExistingFileName
的值其实就是这个DLL
的绝对路径
之后会调用sub_1000105B
这个函数我们上面分析过,会返回系统目录的路径
之后调用了strncat
,不过这次最后拼接出来的字符串是这样的
C:\WINDOWS\system32\Lab11-02.ini
这就印证我们在Procmon
中看到的调用C:\WINDOWS\system32\Lab11-02.ini
的操作
之后代码会调用CreateFileA
,这里的lpFileName
其实就是我们上面strncat
返回的那个最终的字符串
也就是这里会创建一个文件在
C:\WINDOWS\system32\Lab11-02.ini
然后这里开始调用ReadFile
来读这个文件
这里的[ebp+hFile]
其实在上面被eax
赋值了
之后的函数调用
这里把我们上面读进内存的数据传了进去sub_100010B3
中
这个函数我们看着像是一个解密的函数,这里我们可以硬分析这个编码,但是我们也可以通过OD
运行之后直接看结果就行了~
这里我们找到函数的地址
100016CA
这里有个神奇的地方,只是跳到这个位置的时候,OD
中已经自动标注出了这个字符串的解密
我甚至没运行DLL
呢
billy@malwareanalysisbook.com
然后下面还有一个函数调用
在这里的地方,叫sub_100014B6
,这个函数就是书上说的hook_install
函数,这个函数会在这里安装恶意代码的hook
这个函数入参了一个1
之后这里会比较入参的值是否和0
相当呢个,之后如果这个值是0
的话,cmp
之后ZF
=1
,则jz
跳转,跳转之后就直接退出了
如果不等于0
的话,像我们现在的值是1
,就不会跳转继续往下执行
之后函数会来到这里
这里出现一个[ebp+Buf1]
的地址
这里的Buf1
等于-4
我们画一下栈图就知道这个值是多少了
-------
| ecx | <--- ebp-4
-------
| oebp | <--- ebp
-------
| 1 | <--- ebp+4
-------
.
.
.
所以[ebp-4]
其实就是ecx
的地址
然后这步第一个调用的函数是sub_10001075
,这个函数会返回系统的系统路径
之后函数又会调用sub_10001104
这个函数
之后函数进入这个函数之后的第一调用是strrchr
这个函数的意思就是找到最后在字符串中最后出现某个字符的位置
这里我们可以推算得出,这个eax
或者说strrchr
的第一个入参其实就是我们的系统路径的返回值,因为外面的一个函数将ebp+Buf1
的地址赋值给了eax
,于是sub_10001104
的返回值就会直接写到ebp+Buf1
上
所以这里的Str
就是C:\WINDOWS\system32
然后要查找的值是5Ch
换算成ASCII
的话就是
\
这个会查找最后一个字符为\
出现的位置,这里注意我们的系统路径最后是没有\
也就是我们的系统路径只是
C:\WINDOWS\system32
而不是
C:\WINDOWS\system32\
因为我们前面拼接字符串的时候,后面拼接的字符串是这样的
\\Lab11-02.ini
这样的
所以前面的字符串是不会提供\
的
于是我们这里的strrchr
返回的就是
\system32
这里先将返回值eax
赋值给了[ebp+var_4]
,然后将又将[ebp+var_4]
赋值给了ecx
,然后ecx
又加1
,
这里的ecx
代表了字符串的地址,于是+1
就是往后偏移了一个位置
最后的字符串就变成了
system32
然后计算字符串的长度strlen
返回值是在eax
中,这里计算eax
的值是否为0
如果是0
的话,test
之后ZF
=1
之后jz
就会跳转,跳转之后就会看到将eax
异或置0
了
如果不跳转,也就是eax
不为0
之后就会将[ebp+var_4]
的值赋值给了eax
也就是system32
这个字符串
之后函数就退出了
从函数中出来之后,将返回值的eax
赋值给了[ebp+Buf1]
之后,和0
比较大小,如果为0
就jnz
跳转之后就结束了
然后假设我们这里没有跳转结束
之后函数就会来到这里执行
这里的第一个函数调用是sub_1000102D
这个函数
这个函数长这样的
我们可以用OD
来进行动态分析
我们让OD
在这里停住
我们可以看见,这时候我们入栈的参数是LOADDLL.EXE
这个字符串
通过动态运行我们可以看出,这个函数sub_1000102D
作用其实就是将字符串中的字母由小写变成大写的字母
然后一个栈缩小之后,将esp
指向我们变成大写的字符串
之后计算字符串THEBAT.EXT
的长度
之后又一个add esp, 4
将esp
指回我们的变成大写的字符串
然后这里通过memcmp
函数来比较我们刚刚变成大写的那个字符串和现在这个字符串THEBAT.EXE
的相等与否
比较的长度为strlen("THEBAT.EXT")
如果不想等,就会继续比较其他字符串
包括OUTLOOK.EXE
和MSIMN.EXE
如果其中一个相等,马上跳转到这里执行这些代码,如果不相等,马上跳转结束
这里首先调用的是sub_100013BD
这个函数
这个函数首先会调用GetCurrentProcessId
,这个函数是返回这个进程的PID
的
之后准备调用sub_100012FE
在函数sub_100012FE
中我们可以看到一些有意思的调用操作
第一个函数调用是sub_10001000
,这个函数的目的主要是返回第一个push
的DLL
的基地址
函数在调用LoadLibraryA
的时候,push
入栈的参数是eax
,也就是[ebp+8]
,这个地址其实是调用这个函数的第一个入参,也就是我们上面的kernel32.dll
这里恶意代码用LoadLibraryA
将这个kernel32.dll
加载到内存中
之后把这个句柄保存到hModule
中,之后函数会调用GetProcAddress
来检索kernel32.dll
上函数,我们来看这个函数名字的地址是lpProcName
,也就是ebp+0Ch
,这个地址其实指向的是我们上面的那个入参OpenThread
然后函数找到了这个函数的地址,就返回了
我们注意这里的之后函数将返回值,也就是OpenThread
函数的地址,赋值给了[ebp+var_4]
也就是[ebp-4]
之后代码会调用GetCurrentThreadId
函数,这个函数的作用是获取当前线程的标识符
之后会调用CreateToolHelp32Snapshot
来获取当前进程的
获取指定进程的快照,以及这些进程使用的堆,模块和线程
这里的dwFlags
的值是0x4
也就是代表了TH32CS_SNAPTHREAD
,意思就是
快照包括系统中的所有线程,同时会枚举线程
之后代码把返回值保存到了hSnapshot
中
之后代码会来到这里
代码会调用Thread32First
函数,来
检索有关系统快照中遇到的任何进程的第一个线程的信息
这里的[ebp+te.dwSize]
的te
是个THREADENTRY32
结构
描述当拍摄快照时从系统中执行的线程列表中的条目
调用函数Thread32First
成功之后,返回的结构就会保存到[ebp+te]
中,这个结构是这样的
typedef struct tagTHREADENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ThreadID;
DWORD th32OwnerProcessID;
LONG tpBasePri;
LONG tpDeltaPri;
DWORD dwFlags;
} THREADENTRY32, *PTHREADENTRY32;
之后函数会把结构中th32ThreadID
和[ebp+var_28]比较
,这个var_28
是函数当前线程的标识符
如果两个值相等的话,执行cmp
之后ZF
=1
,那么jz
就会跳转到最下面的loc_10001399
这个地方
这里将我们的那个结构和hSnapshot
压入了栈,然后就调用了Thread32Next
这个函数
这个函数在MSDN
中的解释如下
检索有关系统内存快照中遇到的任何进程的下一个线程的信息
然后这个函数的返回值是这样的
如果线程列表的下一个条目已被复制到缓冲区,则返回
TRUE
,否则返回FALSE
假设返回的是TRUE
,在计算机中TRUE
的值一般是非零值,而FALSE
的值一般是0
所以这里test
返回值eax
的时候,如果在内存中找不到已经复制的缓冲区,返回了FALSE
,也就是0
,那么ZF
=1
,之后就会沿着红线执行
就会结束这个小代码,如果找到了缓冲区,那么就会跳回去迭代循环比较
好了,我们退出这个函数的分析,回到主函数
我们上面是在sub_100013BD
里面分析这个函数的作用,他是一个在进程中搜索某个线程的函数
之后下面的函数会将这个一个int
类型的值和sub_1000113d
压入栈中
其中我们快速看一下sub_1000113d
这个函数的作用
这个函数的第一个call
是strstr
函数
而两个入参一个是字符串RCPT TO:
,另一个是函数sub_1000113d
的第二个入参,也就是上面的第二个char *Str
的这个
我们可以看一下剩余的函数,基本可断定,这是一个构造邮件的函数
且如果在邮件中发现了RCPT TO
的字样,这个代码会加上我们在ini
文件中发现的邮箱,加上这个邮箱,这台电脑发送的邮件都会发到这个邮箱一份,这应该是一个盗窃邮件中关键信息的病毒
我们会到外面的函数
然后还会压栈几个参数,一个是字符串send
,一个是字符串wsock32.dll
,这个wsock32.dll
函数是用来发送东西用的
之后就会调用函数sub_100012A3
这个函数,我们看看这个函数
这个函数会去查找那个wsock32.dll
函数
其中MSDN
对GetModuleHandleA
的定义是这样的
检索指定模块的模块句柄。该模块必须已由调用进程加载
这个函数其实就是找wsock32.dll
的地址的作用
之后会调用sub_10001499
这个函数
这个函数我们也是粗略的看一下
这个函数的第一个调用的是GetCurrentProcessId
,这个函数在MSDN
中的解释是
检索调用进程的进程标识符
其后就会退出这个函数了
上面分析了这么多偏的函数,我们现在总结归纳一下(因为时间过去久远)
函数进入了这个hook_install
之后
第一个调用会是sub_10001075
这个函数,这个函数的里面就是
有一个GetModuleFileNameA
,因为这个函数的hModule
参数的值被设置为了0
所以这个函数的会返回加载了这个DLL
的进程的绝对路径,之后就会把这个路径返回了
以AppInit_DLLs作为驻留机制的恶意代码常常使用GetModuleFileNameA。这个恶意DLL几乎被加载到系统中的所有启动的进程,而恶意代码作者可能只是针对某些进程,所以他们必须确定运行恶意代码进程的名称
确定了这个返回值之后,之后会剔除多余的路径名,并且进行大写变换
之后就会于进程名THEBAT.EXE
和OUTLOOK.EXE
还有MSIMN.EXE
比较,确定这个加载了恶意DLL
的进程是这三个中的一个
如果不属于他们中的一个,就会退出
然后代码确定了自己加载到了怎么三个进程中的其中一个,就会执行下面的代码
在第一个调用sub_100013BD
中,我们可以看到以下内容
这个函数里面第一个调用是GetCurrentProcessId
这个,然后就会调用sub_100012FE
这个函数,这个函数会返回当前运行进程内的所有线程标识符(TID,进程标识符是PID),之后这个sub_100012FE
就会调用CreateToolHelp32Snapshot
来遍历所有的线程
如果这个线程不是当前的线程,就会挂起这个线程,所以这个函数会挂起所有不是当前线程的所有线程
然后下一个函数sub_100012A3
这里,这个函数就是执行安装挂钩的地方
这里第一个调用是GetModuleHandleA
来获取wsock32.dll
的句柄,之后用LoadLibrary
加载这个DLL
到空间中
将指定的模块加载到调用进程的地址空间中。指定的模块可能会导致其他模块被加载。
之后函数在wsock32.dll
中查找send
函数的地址
并且把这个地址赋值到了lpAddress
中存起来了
之后就会调用sub_10001203
这里的arg_C
和arg_8
就是我们外面调用这个函数的时候那两个int
类型的入参
这里的sub_10001203
函数的入参是这样的
第一个参数是我们的send
函数的地址,第二个参数就是arg_8
,第三个是arg_C
这里会计算一个地址差
arg_4
是我们第二个参数,这个int
类型的参数其实是sub_1000113D
的地址,这个函数就是构建邮件文件的那个函数
之后我们代码开始计算两个地址之间的地址差值
之后将这个差值减去5
之后,存储在一个变量var_4
中
这里为什么要减去5
我们继续往下看就知道了
之后代码会调用函数VirtualProtect
这个函数的作用是
> 更改调用进程的虚拟地址空间中已提交页的区域的保护
然后地这个函数的lpAddress
参数的值是
一个地址, 描述要更改其访问保护属性的页区域的起始页
这个地址就是我们构造邮件发送的那个函数的地址,这里用VirtualProtect
改变了这个地址的保护属性
之后,这个函数会调用malloc
分配了一个0FFh
大小的空间
下一个调用的函数就是memecpy
这个函数
这个函数的作用是将我们上面刚刚分配好的空间,复制了send
函数的前五个字节,为了方便跳转回来之后保证send
函数代码的完整性
之后
在段函数我们应该分成两段来看
第一段是一个暂时不知道什么操作的代码,从memcpy
之后到lea
操作
第二段就是我们调用VirtualProtect
这个函数的的函数入栈操作,这个段函数会再次调用VirtualProtect
函数来对我们的地址进行保护更改
我们先看第一段
通过代码
mov edx, [ebp+var_8]
来把memcpy
函数分配的空间的地址赋值给了edx
之后从空间偏移量为0Ah
的地方开始,将值赋值成为0E9h
,这个十六进制书上已经提醒我们是jmp
的操作码,因为这里在我们从正常的send
跳到恶意函数之后,要从恶意函数调回来正常的send
函数,也会计算send
到我们分配的内存空间的地址差,之后就会利用这个地址差来跳转到我们的复制了5
字节send
函数代码的空间,之后用这个代码来接上send
函数之下的代码
这样可以保证代码的运行
之后会再次计算构造邮件那个函数的地址和memcpy
分配空间地址之间的差值
之后将这个差值减去0Ah
下面
代码将0E9h
机器码复制到send
函数的开头,这里的edx
其实就是send_address
之后代码将我们的var_4
的值复制给ecx
,var_4
中存储了send
函数和我们的构造邮件函数地址send_address
之间的地址差值,这个差值还要减去5
这里有个问题,书上说,var_4
存储的是我们想要跳转的地址,但是在这段代码中调用了var_4
一共就两次,现在我们遇到的是第二次也是最后一次
然后第一次是计算函数send
和sub_1000113d
之间的差值,并把这个值减去5
,之后保存在var_4
中,为什么这个var_4
现在成了要跳转的函数地址?
这个var_4
不是应该是函数之间地址的差值么?
这里的有一个比较难以理解的就是这个地址的差值为什么要减去5
因为这个5
,是存储0E9h
和我们要跳转地址的所需空间,也就是比如我们的send
函数和sub_1000113d
之间差值是10d
,且send
函数在sub_1000113d
之前,且send
函数的开始地址是0
,那么推理可知sub_1000113d
的地址就应该是10d
,这里用十进制说明了,方便理解
但是我们的0E9h
和地址查占了5
个字节的空间,之后就如果我们要跳转地址10d
的地方,我们就需要要写jmp 5d
,这个5d
的意思是在jmp
开始的地方开始数,往后5
个地址
这里有个概念就是,函数的跳转地址,不是直接写0x1000113d
这种,而是往后跳转多少字节这种
比如我们这里,有一个代码是这样的,这里用的是je
跳转
0x74h
是je
的机器码,然后后面的0x23h
就是我们要往后跳转多少字节
我们地址的下一个地址开始是0x1000153eh
,那么加上0x23h
之后,就是0x10001561h
,所以就会跳转到这里的call spoolvxx.100013BD
这个地方
这是汇编的跳转原理,理解这里,上面这个跳转就好理解了
函数先计算了地址差值,之后减去5
,是为我们将来要增加的机器码和跳转地址做准备,之后
我们将我们要跳转的字节写入send_address
中,这样在我们调用send
函数的时候,代码找到send
的地址,一进去第一个代码就是jmp
,这样就将我们的send
函数替换成为了gen_mail
函数,而这个函数会发送恶意代码定义的东西
这个所谓的hook_function
的工作原理就是这个
之后函数在最后一个调用sub_10001499
这里
会执行和sub_100013BD
相反的操作
之后这个函数会恢复所有的进程
1. 这个恶意DLL导出了什么?
解答: 这个恶意DLL中包含了一个教installer
的导出函数
2. 使用run32dll.exe来安装这个恶意代码之后,发生了什么?
解答: 恶意代码会将spoolvxx32.dll
复制到系统目录中C:\\WINDOWS\system32\
之后会从这个目录中打开Lab11-02.ini
3. 为了使这个恶意代码正确安装,Lab11-02.ini必须放置在何处?
解答: 放在C:\\WINDOWS\system32\
下
4. 这个安装的恶意代码如何驻留?
解答: 恶意代码会将自己安装到AppInit_DLLS
中,然后这个恶意代码就可以load
到了所有导入了User32.dll
的进程中
5. 这个恶意代码采用的用户态Rootkit技术是什么?
解答: 这个恶意代码针对wsock32.dll
中的send
函数安装了一个inline
挂钩
6. 挂钩代码做了什么?
解答: 这个挂钩会检查对外的所有邮件,之后,会增加一个RCPT TO
的邮箱
7. 哪个或者哪些进程执行了这个恶意攻击,为什么?
解答: 这个恶意代码仅针对的是MSIMN.exe
或者THEBAT.exe
或者OUTLOOK.exe
这些程序,除非这些程序运行在进程空间中,不然这个代码不会安装
8. .ini文件的意义是什么?
解答: 这个ini
文件提供了一个恶意的邮箱地址
9. 你怎样用WireShark动态抓获这个恶意代码的行为?
解答: 可以看到这个恶意代码发送的邮件信息
本文完