1.在%systemroot%\system32文件夹下生成一个随机六位小写字母为名称的.exe文件,将自身内存0x838C偏移处开始的0x32E4字节内容拷贝进这个文件并保存,并CreateProcessA运行此文件。
2.为自身进程提SE_DEBUG权限。
3.比较自身文件路径是否是在开始菜单的启动文件夹中(这句应该是作者写错了,路径有问题),或者是否是system32\ctfmon.exe或system32\conime.exe
这部分判断其实没有用,因为无论结果是还是不是,都照样执行下面的流程。怀疑这是作者把别人代码直接copy过来,但是又没有加入相关的功能。
4.使用toolhelp32 API得到系统进程快照,遍历进程检查其中是否有以下进程名的进程:
GuardField.exe
ctfmon.exe
conime.exe
wuauclt.exe
如有,得到其PID,OpenProcess后TerminateProcess结束之。
这一步重复3次。
5.调用SFC.DLL序号为5的API函数,去除system32\ctfmon.exe、system32\conime.exe、system32\wuauclt.exe、system32\spoolsv.exe的windows系统文件保护。
6.修改对ctfmon.exe、conime.exe、wuauclt.exe的访问权限(以前的类似病毒一般用calcs.exe来修改,现在则直接调用AllocateAndInitializeSid等几个与之相关的API来设置),之后依次删除这三个文件。
7.ZwOpenDirectoryObject,ZwQueryDirectoryObject遍历驱动路径,这个不太明白它在干嘛,不过在下面刚好没有用到
8.停止beep.sys的服务,调用SFC.DLL序号为5的API函数,去除对beep.sys的系统文件保护,然后删除beep.sys,以自身内存0x4000开始的0x3F80字节的内容创建并写入beep.sys,再启动其服务,从而实现以替换beep.sys的方式启动自身驱动。
这里又有一个比较奇怪的地方,0x3F80字节这个长度不对,(之前变种中相应的0x3E80字节则是对的。而这个变种的驱动改了,这里正确的应为0x4380),所以释放出来的驱动没有办法运行,额……
9.在当前用户Temp文件夹下创建"_temp.dat"文件,将以自身内存0x4000开始的0x4380字节的内容写入其中,并注册为驱动,驱动项名为随机5位小写字母,然后启动这个驱动服务。
这次的0x4380字节长度就是正确的了,真不明白作者怎么回事,我看是改了这里忘了改那里吧……
10.驱动应该是使用了第二代机器狗虚拟磁盘的技术,这个我不在行,具体分析可参考
http://www.debugman.com/read.php?tid=1292。
另外驱动还有一个巧妙的地方,由于驱动创建的设备名是驱动加载时随机生成的,其中包含任意小写字母以及数字,因此驱动必须把设备名通知给Ring3部分程序,Ring3部分才能访问它的设备与之交互,因此它采取了这样的办法:
驱动SSDT HOOK了NtTerminateProcess
Ring3部分调用TerminateProcess,传递的PID为-3,而exitcode参数则是一个缓冲区指针
这时候,驱动在自身的NtTerminateProcess例程中拦载到这个调用(由PID是否为-3来判断,不为-3则调用原始函数),就把自身设备名中的“随机生成字符”部分转换成ANSI形式,写到exitcode参数指向的缓冲区里了。
这样当这个调用返回之后,Ring3部分就可以得到驱动的设备名中的“随机”内容,从而可以通过CreateFile及DeviceIoControl与之通信。
11.最后应该就是凭借着驱动虚拟磁盘的功能,穿还原写ctfmon.exe、conime.exe、wuauclt.exe了。写入内容同样是自身内存0x838C偏移处开始的0x32E4字节