2010的这次比赛,我打算做 主动防御的东西,这个防御的系统能够对
1:文件操作,
2:注册表操作,
3:进程的创建和消失
等方面 进行监控。。。
在今天终于搞完了文件操作的部分功能,现在能够对 文件的读取和写入进行监控了,
今天遇到的问题在于,对于文件操作的重入,本来以为可以通过提升中断等级来避免我都程序在执行到一半的时候,
另一个读写操作马上就来到,学过操作系统都知道, windows 是一个可中断和抢占 的系统,谁的等级高,就执行谁,
ring 3 就 比不了 ring 0 ,就是这个道理。。。
今天完成了注册表中对IE的回复,得到它路径真是费了好大的功夫。。。
2010/3/27 早,找到了在MFC上与驱动交互的问题,在于参数的传递,可以将其声明成全局的变量。。。
2010/3/28早,在写MFC界面的时候,加入我们自己定义的头文件的时候,出现了:
C++6.0中错误"unexpected end of file while looking for precompiled header directive"
这样的问题,以前也出现过,不过,加入类来封装那些函数就OK 了。现在不想封装了,所以。。。
1、看看是否缺少“;”,“}”
隐藏得深的是宏、.h文件的问题就要费点心思了
2、一定是你在类的部分定义被删除了,M$在每个类中定义一些特殊的常量,是成对的,如下:
.h:
#if !defined(AFX_CHILDFRM_H__54CA89DD_BA94_11D4_94D7_0010B503C2EA__INCLUDED_)
#define AFX_CHILDFRM_H__54CA89DD_BA94_11D4_94D7_0010B503C2EA__INCLUDED_
.......
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRM_H__54CA89DB_BA94_11D4_94D7_0010B503C2EA__INCLUDED_)
你可以新建一个类,然后把这些拷贝过去或补上就可以了。
3、在头部加入 #include "stdafx.h"
4、在CPP文件第一行加上#include "stdafx.h"。
或者Rebuild All.
5、
(1). [Project] - [Settings] - [C/C++] - [Category]
(2). 选择 [Precomplied Headers]
(3). 单选 [Not Using Precomplied Headers]
(4). [OK]
解决方法:
1、如果发生错误的文件是由其他的C代码文件添加进入当前工程而引起的,则Alt+F7进入当前工程的 Settings,选择C/C++选项卡,从Category组合框中选中Precompiled Headers,选择Not Using Precompiled headers。确定。
2、在文件开头添加:
#include "stdafx.h"
对预编译头文件说明如下:
所谓头文件预编译,就是把一个工程(Project)中使用的一些MFC标准头文件(如Windows.H、Afxwin.H)预先编译,以后该工程编译时,不再编译这部分头文件,仅仅使用预编译的结果。这样可以加快编译速度,节省时间。
预编译头文件通过编译stdafx.cpp生成,以工程名命名,由于预编译的头文件的后缀是“pch”,所以编译结果文件是projectname.pch。
编译器通过一个头文件stdafx.h来使用预编译头文件。stdafx.h这个头文件名是可以在project的编译设置里指定的。编译器认为,所有在 指令#include "stdafx.h"前的代码都是预编译的,它跳过#include "stdafx.h"指令,使用projectname.pch编译这条指令之后的所有代码。
因此,所有的CPP实现文件第一条语句都是:#include "stdafx.h"。
2010/3/28 下午,上午把界面的一些下问题搞出来了,不过其他的问题又出来了,当我关闭程序或者解除
HOOK 的时候,应用程序就死掉了。。。让人好郁闷。。
还有就是,当程序执行上边的操作的时候,必须要有一次其他的注册表的操作,不然程序就 死掉了,
好像这样的问题在 对键盘的过滤也出现过,只不过上次必须是按一个键,这次也一样,不过我把 HOOK 和
关闭应用程序的操作分开处理,基本应该没什么问题了。。。
2010/3/31 晚,解决了对 IE ,注册表 的锁定的问题,IE 的锁定难点在于,注册表中,没有对应的项
需要我们自己创建,然后还需要创建一个子键 homepage , 1:代表保护,0:解除保护。。。
注册表的锁定比较容易,对自定的项修改就好了。。。
2010/4/1 下午 终于解决了数据的读取的策略问题,能够顺利的读取来自驱动层的数据,并且不会造成应用层假死,方法是
通过 应用层想驱动中传入在应用层中创建的事件,然后,在线程中等待这个事件,驱动中设置这个事件,就能够通知应用层来
取数据了。。。
2010/4/3 晚, 玩了一整天,该去做些东西了,何况还有些问题没有解决,那就是怎么样将驱动中的数据(这个数据比较大)传输到
应用层,显示给用户看呢? 为此,我搞了好久,都是蓝屏。。。汗
不过,通过今晚的检查,发现问题的原因在于我们申请的内存不一致造成的,我在应用层中定义的结构数组比较小,但是在驱动中
返回的数据量是比较大的,因此,有时候,可以成功,但是,当我改变驱动中的返回结果的大小时,只要超过了
应用层中定义的大小,那么结果就可想而知了。。。对了,还有一个问题就是,在传输到应用层的数据的类型,不要将 WCHAR 直接搞过去。否则,得不到完整的数据,只能得到开始的那个字符,因为 char 只占一个字节,wchar 是两,一不小心就错了,刚开始还纳闷
为什么,返回的数据老是一个字符,通过调试,查看内存分布,终于发现了了这个问题。。。
2010/4/10 今天,将个功能的模块组织的时候,发现了一个问题,那就是在当我操作一些选项的时候,程序就死掉了,让人
挺郁闷的,最后发现,是服务号的重复,造成了这样的原因。。。修改服务号,一些OK 。。。
2010/4/26 这几天对一些驱动中的程序的分发函数进行了检测,因为这个东西涉及到了对 PE 文件的搜索,所以
用到了硬编码,获取到了分发函数的地址,对于一些将数据的返回,出现了应用层的程序崩溃,
原因是接受的buffer 不够大,这个问题让我郁闷了好久。。。
2010/4/28 今晚,完成了对模块定位的功能,能够发现当前程序所在的模块信息了,其实就是调用 ZwQuerySystemInformation
然后得到当前的模块信息,信息当保存在一个buffer 中,遍历一下链表,判断当前地址是否在此模块,就OK了。。。
2010/5/8 今天,搞了一个下午+一个晚上,终于把进程的监控基本完成,windwos 的可抢占和中断的特性,今天让我印象特变的深刻,
临界区的使用可以在这里得到很好的运用,不过我还晚上想到用这个方法的,之前我是通过一个变量来判断的,当我用变量实现了之后,
发现,这里才是临界区的运用,对程序加载到内存的时候,程序会反复的调用 ZwCreateSection, 这里,程序会不断的为程序申请
内存资源,这里往往会出现很多系统进程,他们会把我们抢占掉,造成了BOSD ,郁闷了好久。。。
2010/5/11 上午的web 感觉没啥意思,终于逃了这门课,继续完善我的程序,做完发现,写入文件的时候一直不能成功,
按照以前的经验分析,以为是之前打开的文件没有关闭或者当前有东西在占据着它,但是,我对文件的操作的习惯一直是很好的
,打开之后,用完就 close 了,这项被我排除了,搞了好久才发现,其实程序确是是写入了文件中,只不过是,那个文件的路劲
我没有用据对路劲,造成了这样的惨剧,就我们要生成的数据库文件用据对路劲的方式给程序就解决了问题。。。
下午,叫别人测试了一下驱动,居然说不能加载驱动,于是我怀疑是驱动是debug 版本导致的,所以,我重新编译驱动
将其改为release 版本的,编译的过程中,出现了这样的错误,而在debug 中的编译是不会的
“VC 2005 & VC 2008 error C2220: warning treated as error - no object file generated ”
接在项目中的makefile文件的最后一行加入 MSC_WARNING_LEVEL=/W1 搞定了。。。
2010/5/13 今早,逃了一个上午的课,本想完成对内核的导入表的检测的功能,无奈,驱动的路径的获取在内核中,太不规则了
获取IAT 倒是不难,但是,还是挺麻烦的,驱动中的路径都是经过了转换的,不是符号链接的形式,如果做,还得改很多东西,
如果在应用层上做,同样是这个问题,后来想想,还是对当前进程的IAT 来一个解析吧。。。
2010/5/18 现在正在完善防火墙的部分,采用WDK中的passthru 的框架,在添加一些共享变量的时候,出现了编译时不能正确
识别它们的问题,现在才发现 extern 的作用,以前,由于不太关注,造成了现在的困惑,它的作用有两个,一个是声名全局变量,另一个
是 指定编译的时候,函数才去的是 extern "c" void func() 的方式,也就是如果 文件时 .cpp 的格式,可以用这样的方法来将
函数的编译方式指定为 c 的,避免一些错误,但是,我写的是驱动,文件也是按照 .c 的格式保存的, 如果要想利用共享变量来
达到数据传输的目的,那么就得用它现在某个.h 文件先声明,然后,在所有想利用这个变量的 .c 文件中定义就可以了,不然的话,
你是没法使用这些共享变量的,编译会提示你,某个符号的错误等等。。。
2010/5/19 今天,把防火墙与应用层的传输的问题也做了一下,在做的过程中,发现我从上边发送的io 不能被驱动识别,真是
郁闷啊。
这是一个例子:
#define IOCTL_NET_PASS_OR_NOT
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x8111, METHOD_BUFFERED, FILE_ANY_ACCESS)
红色部分是关键点,如果 是 FILE_ALL_ACCESS 那么可能会造成不能被驱动识别。
2010/5/24 今天,搞了好久,终于把eat 的原始地址给弄了出来,其实,之前的理解有些错误,本来以为原始地址,
经过自己解析磁盘文件后,将其映射到内存冲得到的地址就是原始地址,后来发现映射的地址始终 小于 2g ,明显这是不对的,
驱动的地址都是大于 2 g 的,后来想到了,可以通过相对地址来得到重定位后的原始地址,于是,问题解决了,
原理是,现将其映射到内存中,获取要解析模块的加载的基址,加上我们映射的到的相对地址,就可以了。。。