恶意代码分析实战 Lab 10-1 习题笔记

版权声明:本文为博主辛辛苦苦码字原创文章,转载记得表明出处哦~ https://blog.csdn.net/isinstance/article/details/79064157

Lab 10-1

一些准备工作

首先就是配置内核调试的环境

我这里用的是VirtualBox而不是书上的VMware

所以这里可能会有一些的不同

书上说的是这样的

与用户态调试不同,内核调试需要一些初始化配置。首先需要配置虚拟操作系统并开启内核调试,然后配置VMware使虚拟机和宿主操作系统之间有一条虚拟化的串口,同时还应该配置宿主操作系统中的WinDbg

我们按照书上的做法开始,先配置C:\boot.ini

图

这里要把隐藏文件和隐藏系统配置文件取消勾选

然后我们打开这个boot.ini

图片

注意改之前记得备份系统,防止起不来

然后我们开始修改boot.ini文件

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operation systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin  /fastdetect
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional with Kernel Debugging" /noexecute=optin /fastdetect /debug /debugport=COM1 /baudrate=115200

注意这里的COM1这个端口,待会选的时候别选错了

图

然后这就是改变后的样子

然后下次重启虚拟机的时候,就会出现一个开启内核调试的选项给你选择

然后下面我们设置虚拟机和宿主机之间的那个虚拟连接,我这里是VritualBox,所以用VMware的同学照书做就行

选择这里

图

然后这里开启串口

图

开机的时候我们还开启不了,我们先关闭虚拟机

关了之后就可以修改了

图

然后我们这样设置,注意那个连接至不要打勾,不然启动虚拟机就会报错(如果你没报错可以点了试试哈哈哈)

图

然后进去就可以发现这个了

图片

然后发现我这没激活的系统已经进不去了(无语),我还是先激活一下这个系统算了

然后这里放一个XPOEM激活工具,省的找了,直接运行就行了

XP OEM激活下载

如果你打算使用简单一点只包括WinDbg的东西,用CSDN那个(这个好像只支持xp和win7)

如果没积分的话,可以试试龟速的百度云这个我下载好上传的连接

百度云windbg

资源中有两个文件:64位系统6.12版本和32位系统6.11版本

解压后是这样的

图

我们这是32位的系统,我们安装x86的就行

打开之后就是这样的

图

然后安装就行了

这里有个问题,笔者以前一直以为这个WinDbg是要安装在虚拟机上的,然后今天有时间好好查了一下,这个是要安装在宿主机上,也就是你运行虚拟机那个机器上(这就尴尬了)

现在我bing了一下,要安装Win10WinDbg的话,你要先安装WDK,要安装WDK的话,你要安装这个

图

你必须先安装这个stdio这个东西,慢慢装吧,继续链接在这里 安装WDK

然后我们安装这个stdio

图

我就点了一个Python的开发还有一个Linux C的开发,就两个包,已经要下8G的内容,我也是很无语,这里需要选择这个使用 C++ 的桌面开发,这个会包含这个WDK东西

图

我们慢慢装一下这个东西吧,然后我们装这个Windbg

然后这里我们选择这个

图

就行了(默认是全部都选的)

图片

然后在开始里面查找一下,出现这个就说明安装成功了

图

到这里,你已经做完了安装WinDbg的任务,现在我们开始设置VirtualBox

我这里使用的Version 5.2.6的最新版(2018-1-22),英文的

图

这里我们找到这个Serial Ports这个东西,然后Enable Serial Port这里点上勾勾,然后设置这个Port ModeHost Pipe,然后确保这个Connect to existing pipe/socket这个没有打勾,其他的都不用配置

然后我们开启虚拟机

然后我们下载Windows Symbol去,我这里下载了一份,是SO的大神告诉我哪里下载的。。。

WindowsXP Symbol

然后双击运行就行了

图片

我是安装在了C

然后我们开始调试,我们设置好Windbg之后,重启虚拟机然后等着就行了

图片

出现这个就说明脸上了,然后我们开始设置Symbol

我的做法是这样的,其他做法也可以,只要你可以调试就行了,我找到Windbg的文件夹,然后把这个程序创建一个桌面快捷方式,然后我们打开这个快捷方式

图片

把这里这个目标改为这个(Windbg的路径一般不需要改,只需要增加后面那些参数就行了,记得结合你的虚拟机设置来稍微改动一下)

"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -b -k com:port=\\.\pipe\com1,baud=115200,pipe -y C:\Windows\Symbols

也就是在原来的

"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe"

后面加上

-b -k com:port=\\.\pipe\com1,baud=115200,pipe -y C:\Windows\Symbols

记得这两个字符串之间要有个空格

然后我们双击之后就会自动出来那个窗口了

图片

这样就说明已经处于调试状态了

图片

我这个Windbg并不会显示多余的信息,我们可以安装下面的这个教程拷出来的图片操作,输入g就继续

图片

然后这样我们就配置好了WindowsXP Kernel调试环境

问题


1.这个程序是否直接修改了注册表(使用procmon来检查)?

解答: 现在我们调试器准备好之后,开始准备运行这个病毒,然后之前先做一下系统的备份

在运行调试器的时候,如果你不需要调试中断了,输入一个g就可以了

然后如果你突然需要终端介入了,然后点一下这里

图片

然后就会产生一个中断,系统这时候就会暂停运行了

然后我们把这两个文件拖到C:\Windows\System32下面

图片

也就是Lab10-01的两个实验样本(记得在这之前做备份)

复制完之后,我们按照书上的一些办法,执行一些基本的静态分析

图片

然后我们可以发现第一个DLL里面导入了这么几个函数

ControlService
CreateServiceA
OpenSCManagerA
OpenServiceA
StartServiceA

都是和服务控制有关的,创建一个服务,控制一个服务,启动一个服务

然后第二个DLL导入的函数是这些

图片

有点多,其中毕竟要注意的是

WriteFile

说明会有一个写入文件的操作

然后我们打开IDA来看看字符串有哪些

图片

这个程序就操作了这么几个函数就完了,没有特别复杂的逻辑

然后我们看看字符串都有些什么东西

图片

我们注意到最后那里有个C:\\Windows\\System32\\Lab10-01.sys这个路径,说明这个程序会去调用这个sys文件

然后我们研究一下这个sys文件是啥样的

这个文件只导入了这么几个函数

图片

按照书上的说法,第一个函数KeTickCount是所有驱动都会包含的一个函数,这个可以忽略

然后第二个RtlCreateRegistryKey和第三个RtlWriteRegistryValue,看到这个Registry我们就大概知道这个操作是和注册表有关的操作,然后一个是Create一个是Write,所以这个是创建和写入注册表的操作

然后打开字符串看看都有哪些字符串

然后发现有个小Error

图片

这个是缺少了一个Symbol然后看来我们还要装一个Symbol这个东西,不行,装了还是不行

图片

这里看不见书上那些字符串,过~

所以这里我们缺个symbolsys文件没法看到具体的字符串是啥样的

然后下面我们开始动态分析,还原虚拟机,去除装的那个Symbol

执行之后,用procmon检查操作,会发现这么几个操作

图片

这里有个调用恶意程序的操作,放大之后就是这样的,一个QueryOpen

图片

还有这个

图片

有个操作就是CreateFile

然后如果我们设置筛选条件为Process Name = Lab10-01.exe的话,我们就可以发现这些东西

图片

这里显示我们运行这个Lab10-01.exe之后,起了一个线程(Thread Create),然后就是加载了一下DLL,然后创建了一个文件在C:\WINDOWS\system32\Lab10-01.EXE-xxxxx.pf

图片

这里有个RegOpenKey,然后打开了这个键

图片

这个的执行结果是

图片

这里唯一改变了键的就只有这个操作

图片

这里用RegSetValue改变了一个加密用的种子值,但是这个对分析恶意代码没用

然后函数在这里调用了sys驱动文件

图片

这是我们动态分析能分析到的信息了,下面我们开始静态分析代码

图片

然后这是整个函数的大概样子,其中有两个小+号里面藏着一些隐藏的函数

我们进入main函数看看

图片

这里唯一的一个函数调用是OpenSCManagerA,这个是

在指定的计算机上建立与服务控制管理器的连接,并打开指定的服务控制管理器数据库。

这是连接到服务管理的一个函数,然后我们继续分析

如果失败,返回的NULL,然后这里用test测试了返回值,test指令是和and类似的,如果返回的是NULLtest之后,结果为0,则ZF=1JNZ不会跳转,继续执行,走红线,然后就返回了

如果没有失败,我们继续往下走

图片

往下走就是这里,之类调用了CreateServiceA这个函数,我们对应一下入参就是如下

SC_HANDLE WINAPI CreateService(
  _In_      SC_HANDLE hSCManager = edi,
  _In_      LPCTSTR   lpServiceName = "Lab10-01",
  _In_opt_  LPCTSTR   lpDisplayName = "Lab10-01",
  _In_      DWORD     dwDesiredAccess = 0F01FFh,
  _In_      DWORD     dwServiceType = 1,
  _In_      DWORD     dwStartType = 3,
  _In_      DWORD     dwErrorControl = 1,
  _In_opt_  LPCTSTR   lpBinaryPathName = "C:\\Windows\\System32\\Lab10-01.sys",
  _In_opt_  LPCTSTR   lpLoadOrderGroup = 0,
  _Out_opt_ LPDWORD   lpdwTagId = 0,
  _In_opt_  LPCTSTR   lpDependencies = 0,
  _In_opt_  LPCTSTR   lpServiceStartName = 0,
  _In_opt_  LPCTSTR   lpPassword = 0
);

这里我们就关注这么几个点,首先是可以看出这个服务的名字就是Lab10-01,然后访问权限dwDesiredAccessSERVICE_ALL_ACCESS

图片

然后下一个是dwServiceTypeSERVICE_KERNEL_DRIVER,这意味这这个文件会加载到内核里面

图片

然后dwStartTypeSERVICE_DEMAND_START,也就是会自动启动的一个服务

图片

最后需要注意的就是lpBinaryPathName,这个的值是"C:\\Windows\\System32\\Lab10-01.sys",意味着服务起来的时候会去加载这个二进制文件

一样的,这个函数调用失败会返回NULL

图片

在这里,如果函数失败,返回NULLtest之后,ZF=1,然后JNZ不会跳转,所以函数失败之后,会继续走红线,也就这写代码

图片

这里程序会尝试打开这个服务通过OpenServiceA来实现

SC_HANDLE WINAPI OpenService(
  _In_ SC_HANDLE hSCManager = edi,
  _In_ LPCTSTR   lpServiceName = "Lab10-01",
  _In_ DWORD     dwDesiredAccess = 0F01FFh
);

如果上面这个OpenServiceA失败,然后会继续通过StartServiceA来开启这个服务

图片

如果上面的函数调用失败,还是会继续通过ControlService来将控制码发送给服务

图片

然后对应一下就是

BOOL WINAPI ControlService(
  _In_  SC_HANDLE        hService = esi,
  _In_  DWORD            dwControl = 1,
  _Out_ LPSERVICE_STATUS lpServiceStatus = eax
);

这里值得注意的是dwControl,代表的意思SERVICE_CONTROL_STOP,这个应该是停止这个服务,然后卸载这个驱动(书上的原话)

图片

所以这些操作,只要一个成功了,就会直接一个JZ跳转然后返回了,如果失败,则继续往下尝试另外的函数

图片

然后我们继续分析,这次我们分析Lab10-01.sys

我们找到驱动的入口点,然后查找

图片

前面的

mov edi, edi
push ebp
mov ebp, esp

这些操作是在调用函数之前的初始化栈空间操作,如果你好好分析就会知道,这些操作会在栈上重新分配一些空间给要调用的函数,对我们分析来说,无关紧要

然后之后就调用了sub_10920,我们进去看看

这里执行的是驱动函数的一些必要操作

图片

然后我们退出来,看看下一个函数sub_10906

图片

这个代码我们来解释一下

mov edi, edi
push ebp
mov ebp, esp
/* 上面那些都是函数调用之前的初始化栈操作 */
mov eax, [ebp + arg_0] // 将入参的第一个值也就是文件名赋值给eax
mov dword ptr [eax+34h], offset sub_10486 // 然后将sub_10486的地址赋值给eax+34h
xor eax, eax
pop ebp
retn 8

这里虽然没有调用任何函数,然后出现了一个函数的赋值sub_10486,然后我们进去看看就会发现这个

图片

这个函数会调用RtlCreateRegistryKey这个内核函数来创建一个键在\Registry\Machine\SOFTWARE\Policies\Microsoft,然后设置为0

图片

然后下一个调用是

图片

然后这里创建了一个键在\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFire,然后写入的值是wall0

图片

再下面也是一样的\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFire,然后写入的信息是wall\StandarProfile0

图片

然后下一个函数是RtlWriteRegistryValue

图片

这里写入的值是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFire

入参是这么几个

图片

这个函数在MSDN中的定义是这样的

NTSTATUS RtlWriteRegistryValue(
  _In_     ULONG  RelativeTo = 0,
  _In_     PCWSTR Path = ebx,
  _In_     PCWSTR ValueName = edi,
  _In_     ULONG  ValueType = 4,
  _In_opt_ PVOID  ValueData = eax,
  _In_     ULONG  ValueLength = 4
);

这里我们查看MSDN里面RelativeTo的数据会发现

图片

这里并没有任何是值显示,我们用IDA替换一下

图片

这里我们搜索之后会发现,这里只有这个,然后我们替换成这个RTL_REGISTRY_ABSOLUTE

这个的意思在MSDN里面解释是这样

图片

意思就是

路径是一个绝对的注册表路径

然后我们看看这个Path的路径是多少,在这里的ebx显示是这样的,他被赋值为aRegistryMach_2之后就没被改变过了

图片

所以这里的Path的值就是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFire,然后值为wall\DomainProfile, 0

然后ValueName的值是edi,在IDA里查找最后改变edi的值

图片

最上面那里一个mov赋值之后就没有改变过了,然后这个ValueName的值是一个dw类型的

图片

也就是E

然后下面的ValueType的值是4,查看MSDN

图片

这里有个REG我们根据这个查查看

图片

这里有很多的待选,我们再继续查找

图片

这时候只有一个REG_DWORD_LITTLE_ENDIAN符合,这个选项的意思是

最低地址处的最低有效字节的4字节数值。与REG_DWORD相同。

所以最后,总结一下这个函数会做什么

RtlWriteRegistryValue例程将调用方提供的数据以指定的值名称写入指定的相对路径。

这里会将\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFire\wall\DomainProfile的值写入成45h


2.用户态的程序调用了ControlService函数,你是否能够使用WinDbg设置一个断点,以此来观察由于ControlService的调用导致内核执行了怎样的操作?

解答: 我们开始刚刚一开始我们配置的Windbg来就行内核调试,书上的原话我就不重复了

这里说一下,我的WindbgWinXP虚拟机的内核的时候,必须重启才可以连进去,然后现在书上的做法是虚拟机里面用Windbg来进行调试,加个断点之后,在来宿主物理机上,连Windbg,这个方法我感觉是不靠谱的,我的想法是最好还是虚拟机启动的时候就连Windbg,然后用g命令执行,再用OD来加载exe文件加断点,省的windbg界面不好调试,windbg还是用于内核调试算了

我们先在IDA里面找到这个ControlService的地址,这个是系统函数

图片

图片

然后找到地址为401080,我们在OD里面加载断点

图片

我们找到这个位置,然后加断点,然后执行到这里

命中断点之后,我们的OD显示和Windbg一样,比Windbg更具有可读性

图片

然后我们现在可以跳出虚拟机了,Windbg发送break然后暂停虚拟机的运行

然后我们继续跟着书走

图片

我们已经暂停了虚拟机的执行,Windbg在等待我们的输入

我们输入!drvobj Lab10-01, 我在Win10物理机上做是有点慢,慢慢的才会出结果来,等一下

图片

这里显示的和书上的不一样,因为我们输入的是大写的Lab10-01,然后我们试试小写的lab10-01

图片

还是一样的无法得出和书中结果相似的结果,书中的结果如下

图片

然后我们看这个WinDbgERROR,说的是symbols could not be loaded for Lab10-01这个东西,我以前装的symbolsWinXP SP3的…

现在我换个Symbols看看,换的是Windows 10 1701的,试试看

图片

现在我们更换这个Symbols为安装在D盘的Windows 10的,但是这里显示是找不到这个Symbols文件,这里保证路径没有打错哈哈哈

图片

看来我们只能用WindowsXP SP3那个版本的Symbol

所以这里不知道什么Symbol的原因,无法显示和书中相似的结果,我们继续下面的操作

然后我们查找这个驱动对象的地址,在书本上是这里

图片

然后我们查看我们出来的结果

图片

这里我们试了大写和小写的,出来的驱动对象地址都是一样的896fa5f0,不过我们先试试82636b418这个地址

图片

这里显示什么也没有,我们再试试我们得出的结果的那个地址896fa5f0

图片

这里就和书上结论类似了,我们查看在0x034偏移DriverUnload(驱动程序卸载)的这个地方的值,这里有个DriverUnload的函数,这个偏移的地址是0xf7ab9486

下面我们在这个地址这里设置一个断点,来查看这里发生了什么(这个断点用物理机上的WinDbg设置)

bp 0xf7ab9486

图片

注:每次运行地址都会不同

然后我们恢复虚拟机的运行,回到OD中用ODF9运行代码

图片
注:这里是我第二次运行虚拟机,上面那个是昨天写的,今天重连pipe所以重启了一下虚拟机,所以这个地址和前面的有不同,说明一下

这里我们的断点已经被命中,然后我们继续,这时候虚拟机也已经暂停了运行,下面我们执行单步调试,WinDbg的单步调试对话框输入p就可以了

图片

这里显示了三行汇编代码,从这个结构和处理来说,我们刚刚WinDbg的断点应该是断在了一个函数的入口第一行汇编代码的地方

mov  edi, edi
push ebp
mov  ebp, esp

这三段代码都是调用函数之后的栈预处理,然后接下来的代码整理之后就是如下的

push ecx
push ebx
push esi
move esi, dword ptr [Lab10_01+0x780 f(7a54780)]
push edi
xor  edi, edi
push offset Lab10_01+0x6bc(f7a546bc)
push edi
mov  dword ptr [ebp-4], edi
call esi

执行到这里的时候我们想知道这个调用esi是什么函数,可以执行

u esi

然后就会显示了

图片

这是一个nt!RtlCreateRegistryKey调用,而这个函数的定义是如下

NTSTATUS RtlCreateRegistryKey(
  _In_ ULONG RelativeTo,
  _In_ PWSTR Path
);

有两个入参,第一个入参是edi,即RelativeTo=edi,第二个是offset Lab10_01+0x6bc(f7a546bc),即Path=offset Lab10_01+0x6bc(f7a546bc)

图片

这里的RelativeTo的值为0,接下来我们看看Path的值,这里我们先用da命令

图片

在地址f7a546bc处的值的ASCII\,当然,这样对查看单个地址上的数据比较有用,如果数据很多,要查看的话,我们用dc命令

dc f7a546bc

图片

这里的Path的值就是\Registry\Machine\SOFTWARE\Policies\Microsoft,然后后面就是全0的截断符了

然后下面又是一个相同的调用nt!RtlCreateRegistryKeyedi的值没有改变还是0,我们看看f7a54640的值

push offset Lab10_01+0x640(f7a54640)
push edi
call esi

图片

注意这里下面被圈黄的截断符(web渗透里面叫截断符’\00’,计算机里面叫文件结束符),这里我们得出的Path\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall

从字面意思应该可以大概知道这个注册表是关于防火墙的

继续下面的汇编代码

push offset Lab10_01+0x6a8(f7a545a8)
push edi
call esi

还是一个nt!RtlCreateRegistryKey调用,和上面两个片段类似

edi至今未变,我们看看Path的值

图片

这里还未出现文件结束符,说明这里还有数据没有显示出来,我们跳到最后显示这个地址继续显示

图片

图上圈黄的是文件结束符的位置,然后我们可以得出这次调用的Path的值是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile

然后继续往下看代码

mov  ebx, offset Lab10_01+0x50c(f7a5450c)
push ebx
push edi
call esi

这里的esi还是未变,我们看看Path的值

图片

这里依旧是一次未能显示全,我们往下跳

图片

可得出Path的值就是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile

所以应该是调用了四次nt!RtlCreateRegistryKey(书中有误),然后依次创建的键路径在如下所示

\Registry\Machine\SOFTWARE\Policies\Microsoft
\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall
\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile
\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile

然后我们继续往下分析,下面的代码如下

mov  esi, dword ptr [Lab10_01+0x788(f7a54788)]
push 4
lea  eax,[ebp-4]
push eax
push 4
mov  edi,offset Lab10_01+0x4ee(f7a544ee)
push edi
push offset Lab10_01+0x5a8(f7a545a8)
push 0
call esi

遇到一个call函数了,这里的第一句已经改变了esi,再也不是那个nt!RtlCreateRegistryKey

我们看看这个函数是什么

图片

nt!RtlWriteRegistryValue,向注册表里面写入值的内核函数,这个函数定义如下

NTSTATUS RtlWriteRegistryValue(
  _In_     ULONG  RelativeTo,
  _In_     PCWSTR Path,
  _In_     PCWSTR ValueName,
  _In_     ULONG  ValueType,
  _In_opt_ PVOID  ValueData,
  _In_     ULONG  ValueLength
);

对应上面的汇编代码,我们可以得出下面对照

NTSTATUS RtlWriteRegistryValue(
  _In_     ULONG  RelativeTo = 0,
  _In_     PCWSTR Path = offset Lab10_01+0x5a8(f7a545a8),
  _In_     PCWSTR ValueName = offset Lab10_01+0x4ee(f7a544ee),
  _In_     ULONG  ValueType = 4,
  _In_opt_ PVOID  ValueData = eax,
  _In_     ULONG  ValueLength = 4
);

这里对我们来说有意义的参数,一个是Path,这个Path的值我们查查应该是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile
,然后ValueName的值是EnableFirewall

图片

然后下一个是ValueData的值是,这里的eax的值是[ebp-4]的值,所以我们找ebp-4的值

图片

图片

所以这个eax的值是0,这里的意思就是将EnableFirewall这个的值设置为了0,意义就是从内核禁止了Windows的防火墙功能,然后我们继续往下分析看看

push 4
lea  eax,[ebp-4]
push eax
push 4
push edi
push ebx
push 0
call esi

对照结构体,我们可以得出一下结论

NTSTATUS RtlWriteRegistryValue(
  _In_     ULONG  RelativeTo = 0,
  _In_     PCWSTR Path = ebx,
  _In_     PCWSTR ValueName = edi,
  _In_     ULONG  ValueType = 4,
  _In_opt_ PVOID  ValueData = eax,
  _In_     ULONG  ValueLength = 4
);

我们看看Path的值应该是\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile

图片

然后ValueName的值是EnableFirewall

图片

最后是ValueData的值是0

图片

所以这里还是通过内核改变注册表\Registry\Machine\SOFTWARE\Policies\Microsoft\WindowsFirewall\StandardProfile的键EnableFireawll0来关闭防火墙

然后下面的代码就是退出和一些清理函数了

pop edi
pop esi
pop ebx
leave

然后书中还讲了如何计算偏移地址的方法,如何在静态分析中找到驱动卸载程序的地址等等,就不一一概述了


3.这个程序做了什么?

解答: 这个程序通过我们上面的分析可以知道,程序运行之后会启动一个服务,然后通过运行一个驱动创建修改注册表的值,来关闭防火墙


本文完

猜你喜欢

转载自blog.csdn.net/isinstance/article/details/79064157