逆向fuck.sys–编译通过–源码

信息来源:邪恶八进制信息安全团队(www.eviloctal.com)
文章作者:sudami

前言:
一直很向往进入Debugman论坛的RCT这个核心团队,但自己水平有限,最后没有过关.

呵呵,不过俺从中学到了很多东西,于是发此帖分享一下学习成果;也顺便请教各位大牛,希望您有时间的话,逆一份更加好的code.偶逆的这份code虽然大致实现了原来驱动的功能,但写的毕竟很粗糙,希望有逆向经验的同学能给予部分提示和指导,偶也能从中总结经验和教训,争取在短时间内提高自己,以便下次再申请加入RCT.

正文:
/*********************************************************************************************************
* AUTHOR : sudami [[email protected]]
* TIME : 2008/06/05
*
* Command:
*
* 这份code是完成XIKUG给的题目:“逆向fuck.sys,给出源码,编译成功,替换原驱动的功能”
* code已经基本实现了原驱动的功能,部分瑕疵有:
*
* 1. 驱动卸载时候会BSOD, 和加进来的DLL资源有关. 不加DLL资源,则可正常加载卸载.
* 2. 驱动中包含的DLL未用XOR加密,故释放DLL时不用解密.但解密部分的code保留
* 3. DLL加载后,偶没有调用DeleteFileW来删除这个DLL,保留这个功能; 调用LoadLirary
* 经过长久思考,换回原来的硬编码. 动态获取其地址的code保留.可运行.
*
*
* Description:
*
* —— 原驱动的功能 ——
* 1. 驱动入口; 解密出“ImagePath”;在注册表得到自身的全路径;读取自身文件;定位到SYS最后一个节的
* 结束处;获取一个DOWRD的DLL文件大小,偏移后开始解密DLL,将获取的数据存放的申请的非分页内存中;
* 写DLL到\SYSTEMROOT\SYSTEM32\winlib .dll.
* [sudami注:这里有个小技巧,为防止同名不可删除文件干扰DLL的释放,作者进行了判断,winlib0.dll ~ winlib10.dll]
*
* 2. 映射kernel32.dll到内存,搜索EAT得到个函数的地址-
* LoadLibraryA 、GetSystemDirectoryW 、lstrcatW 、DeleteFileA
*
* 3. 进入正常的驱动流程IoCreateDevice、IoCreateSymbolicLink
*
* 4. 调用IoCreateNotificationEvent创建事件对象\\BaseNamedObjects\\UID_1329147602_MIEEvent,
* 负责激活等待的系统线程; PsSetCreateProcessNotifyRoutine检测进程的创建
*
* 5. PsCreateSystemThread创建线程.它完成的功能如下:
* 遍历ActiveProcessLinks链表找到winlogon.exe,从中找一个可插APC的线程;初始化APC,插入之.
* 路径为SYSTEMROOT\SYSTEM32\winlib.dll.调用loadlibrary来加载这个DLL.,而后等待事件的触发…
* 当检测到IE启动时,设置事件对象为受信状态, 激活等待的线程,释放掉EVENT占用的内存,再释放掉MDL.
* DLL加载完成后会被删除.
* [sudami注:原作者这个的EVENT估计是和R3进行通讯用的,在这里保留其功能]
*
* —— 总结 ——
* 总的来说,驱动的主要功能便是”释放DLL,插APC加载DLL”.
* 1. 刚开始调试时不知如何下手,因为驱动加了很多花,IDA基本看不到内容,而偶第一次接触到驱动加花,一时很头大;
*
* 2. 脑子里想着如何去花,若能动态调试,先不去花也能看看驱动的基本流程了,抱着这个想法,偶拿起不熟悉的windbg
* 双机调试起来,弄了大半会儿效果不好,换用softice,无奈偶不是很熟悉,再换用syser,另偶感到郁闷的是load该驱动
* 总是失败,MS带反调试???然后暂时放弃了动态调试的方式
*
* 3. 再google一看,发现winhex或者IDC很好去掉.于是开始琢磨起来,无奈编写IDC第一次接触,无太多的时间用它来去花,
* 索性拿起不怎么熟悉的winhex,很好很强大; 于是偶拿着IDA 和winhex,开始漫长的去花过程,由于偶太菜,去花用了
* 2天时间,而且没有去全,不过此时得到的IBD已经很明晰了,偶也从中学到了不少东西;
*
* 4. 此时才开始正式的逆向还原code工作.其实有了F5,只是方便了一点儿,大部分的时间还得自己编写调试code.断断续续
* 的调试了天(期间有专业实习,实验报告,公司实习等,时间不是很充裕),遇到了一个又一个障碍. 比如:
* R0插APC加载DLL 、释放DLL到系统目录、加资源到SYS文件末尾、驱动加花、…
*
* 5. 好在问题都被一一化解,从中偶又学到了学多偶以前不熟悉的知识.感觉逆向很能锻炼一个人的耐心和解决问题的能力.
*
* —— 后记 ——
* 感谢XIKUG给俺这次机会,偶非常希望进入RCT这个核心团队; 虽然这次逆的code很粗糙,但偶相信以后会越来越熟练,写出来
* 的code也一定越来越完善.
*
* Copyright (c) 2008 sudami.
* Freely distributable in source or binary for noncommercial purposes.
* This is not a virus, So take it easy, just for fun.
*
********************************************************************************************************/

总结几点:
1. 驱动去花
偶碰到的这个驱动,加花代码如下:

jz @F
jnz @F
db 0E8h

@@:

在IDA的图片如下:


故若用winhex,可先在IDA中定位到这段花,复制其2进制文件,再到winhex查找替换为nop即可。不过这种方式实在是体力活,有去花经验的同学可以编写IDC脚本进行去除操作。基本思路如下:

#include <idc.idc>

static main()
{
auto i,j,from,size;
from=0x401000; //起始地址,你指定一下
size=0x100;//扫描数据块大小
for ( i=0; i < size;i++ ) {
//查找 0F 82 07 ?? ?? ??,替换90
if ((Byte(from)==0x0f)&&(Byte(from+1)==0x82)&&(Byte(from+2)==0x07))
{
for(j=0;j<5;j++)
{
PatchByte(from,0x90);
from++;
}
continue;
}
//查找 0F 83 01 ?? ?? ??,替换90
if ((Byte(from)==0x0f)&&(Byte(from+1)==0x83)&&(Byte(from+2)==0x01))
{
for(j=0;j<5;j++)
{
PatchByte(from,0x90);
from++;
}
continue;
}
from++;
}
Message("\n" + "OK\n");
}

——————————————————————–
2. 驱动加载DLL资源
和EXE类似,因为驱动加载后要释放出资源,所以偶这里有2种选择:
A.为SYS增加一个新节,在新节中添入DLL资源文件.重新计算校验和
B.在SYS最后一个节的结束处,即文件末尾添加资源文件.重新计算校验和


偶选择的是第2种.插入DLL资源前,驱动自由10.KB,加入后就变大了些:

当然,你也可以用PE-DIY等工具来为SYS增加新节,注意得按文件对齐来分配大小SYS加载时,读取自身文件,定位到资源处,解密后写入新文件即可.

3. 插APC加载DLL
其实和运行EXE差不多的原理,只不过把winexec换成了LoadLiraryA(W),最好不要用引编码,因为不干净的机器上可能会被安全软件修改.驱动中获得的函数地址,要放到事情的MDL中,因为APC执行时已经到了用户空间,不可能访问驱动中的全局变量..

逆向完后,编译运行,得到SYS,以下是运行效果:


附件
逆向fuck.sys专题.rar (599.12 KB)

相关日志

抢楼还有机会... 抢座Rss 2.0或者 Trackback

发表评论