首页
社区
课程
招聘
[原创]一个简单的驱动的反编译
发表于: 2012-5-26 00:09 24076

[原创]一个简单的驱动的反编译

2012-5-26 00:09
24076

蛋疼的时候,没有比做反编译更加能打发时间的事情了。
近日初次做驱动的逆向,所以挑了一个简单的下手ikbFilter.sys。这个驱动是针对使用IKB收费系统的网吧玩山口山掉线的问题做的。当然我是在NGA上面看见的,然后开心的看着下面的回帖讨论有毒无毒的问题。不过想得到结果,光看群众讨论是不行的,永远都得要自己实践一下才行。

首先拖入IDA,由于初次做驱动的逆向,对调用的API含义完全不懂,不过好歹我还是知道驱动的入口是DriverEntry……

不懂可以看msdn,这句话说得好,还有一句更好的:“microsoft在msdn里提供了开发常规用途软件的全部可能用到的信息,以至于有时候你得花些时间才能找到你需要的部分。”

然后再msdn里面参阅api描述,参数结构类型,确定这货是一个文件过滤驱动。体积也很小,不到6KB。一共大概8个Function,其中还有2个是直接返回STATUS_SUCCESS的以及一个空函数。鉴于此,突然想干脆反编译了吧,顺便接触一下驱动编程。

然后下载DDK,结果下到了WDK,所幸都行。然后开始搜索怎么配置VC2010又花了半小时。

终于开始磕磕撞撞的敲代码,msdn这时候很不给力的开始卡了。

等敲完了代码,点了一下编译,出错就不提了,居然提示我“错误超过100条,编译终止”。再一看,全是ntifs.h里面结构重定义,百度发现需要把ntifs.h在ntddk.h之前包含就可以了,然后我并没有引用ntifs.h,把编译设置里面显示包含文件选上再编译,发现是FltKernel.h包含了ntifs.h,那这样只要把FltKernel.h丢到第一行就可以了。

再编译,这把全是自己程序里面的错误了。
for(int i=0;i<3000;i++)
就这句话居然出现了4个错误,我是百撕不得骑姐。google一下(话说现在google.com.hk挂得是越来越频繁了),原因是C语言不支持变量在非定义性操作之后再定义。那简单的这样既可:int i;for(i=0;i<3000;i++)

然后后面类型匹配之类的就不说了。

最后就是定义字符串的问题。驱动程序里面的api如果需要字符串做参数的话,一般都是UNICODE_STRING。而定义字符串一般是char a[]="abc";。
好了,问题来了,UNICODE_STRING是一个结构,不支持UNICODE_STRING a=L"abc";这样的初始化,更不支持UNICODE_STRING a[]={L"abc",L"cde"};这样的数组。
继续google,发现Undocument windows 2000里面提及一个定义宏:
#define PRESET_UNICODE_STRING(_symbol,_buffer) UNICODE_STRING _symbol = { sizeof (USTRING (_buffer)) - sizeof (USHORT), sizeof (USTRING (_buffer)), USTRING (_buffer) };
这个宏解决了UNICODE_STRING a=L"abc";样式的定义:PRESET_UNICODE_STRING(a,L"abc")
然后是数组的定义,因为这个驱动里面有一个黑名单,按它那种写法,大概是
if (stricmp(nameinfo.FinalComponent,BlackList1) ||stricmp(nameinfo.FinalComponent,BlackList2) ||...||stricmp(nameinfo.FinalComponent,BlackListN))
{mark as ACCESS_DENIED}
可是如果定义为数组,即可用一个循环实现。这样可以大幅度简化函数的流程。
在凝视此宏1分钟之后,联想到宏的处理方式,我突然想到这样:
#define NOSYMBOL_UNICODE_STRING(_buffer) { sizeof (USTRING (_buffer)) - sizeof (USHORT), sizeof (USTRING (_buffer)), USTRING (_buffer) }
对,最后没有分号,你没有看错,我也没有写错。用这个宏,数组就可以这么定义:
UNICODE_STRING a[]={NOSYMBOL_UNICODE_STRING(L"abc"),NOSYMBOL_UNICODE_STRING(L"cde")};
这时编译通过了。

然后链接的时候出现问题了,无法解析外部符号。这就无解了,我用VS编译不了,你让我用WDK的命令行我又不会。所幸的是微软终于在VS11里面集成了驱动的开发。然后又下载VS11+WDK8,然后卸载VS2010。
一夜过去之后,开始安装VS11,然后再安装中文语言包。折腾完之后,启动一看,说好的驱动模板呢?说好的模板呢?

再去msdn上面看了一下,醒目的一行字“Templates do not show up in a non-English version of Visual Studio: If you install a Visual Studio language pack or a non-English version of Visual Studio, the WDK templates will not appear in the New Project dialog box."
感情我装个中文语言包还有错了,然后又是卸载,又是下载VAX。顺便说一下,无论是VS2010和VAX的卸载都太不方便了,VAX更是连卸载的功能都没有。就因为它们没清理自己的注册表安装路径,BRD的1903补丁足足折腾了我1个小时才打上。

然后新建工程,复制粘贴,通过编译了。
然后再次拖入IDA反汇编,对比行为及操作方式基本一致。附上代码及原始文件。VS11工程,按照Windows7的Release模式编译通过。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 6
支持
分享
最新回复 (10)
雪    币: 31
活跃值: (48)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
下载留名,Mark.
2012-5-26 07:22
0
雪    币: 695
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
ikbFilter_src.rar  里面没有代码
2012-5-26 10:40
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
4
下载学习。lz强人   膜拜学习能力。
2012-5-26 10:49
0
雪    币: 1790
活跃值: (3806)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
直接将文件名更改为.cpp就可以直接编译了。
2012-5-26 11:16
0
雪    币: 622
活跃值: (294)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
6
微软的驱动程序一般是只支持C语言编译的。C++据说从WDK7开始支持,但是还是算了吧。



有啊, ikbFilter.c ikbFilter.h
2012-5-26 11:26
0
雪    币: 309
活跃值: (93)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
楼主的学习能力不是一般
2012-5-26 11:28
0
雪    币: 458
活跃值: (421)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
8
逆的有点小问题。
PreOperation 中
                                if (nameinfo)
                                {
                                        FltReleaseFileNameInformation(nameinfo);
                                }
应该放在return之前。。。

要不就内存泄漏了
2012-5-26 14:58
0
雪    币: 622
活跃值: (294)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
9
谢谢,最后分支排错了,然后代码就堆错地方了.

重新看了一下原来的文件,去掉Else分支,修改成这样就对了。
        if (nameinfo)         FltReleaseFileNameInformation(nameinfo);
}
return return_value;
2012-5-26 18:36
0
雪    币: 7395
活跃值: (4582)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
佩服,这样的学习方法的确让人耳目一新
2012-5-28 00:57
0
雪    币: 2956
活跃值: (66)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
感谢楼主分享,小菜膜拜下。
2012-5-28 22:08
0
游客
登录 | 注册 方可回帖
返回
//