阅读:8963回复:19
MiniFilter研究贴:问swapbuffers中,在哪里加解密阿,新加了自己的代码,在下面的回复里面
我这几天在看minifilter中的swapbuffers例子。发现里面没有讲具体的交换,我也不知道在哪里做。
例如读文件,不知道在哪里得到从原文件读到的字节,也不知道把这些读到的字节处理后怎么放到新缓冲给上层的应用。 本人刚学驱动开发,菜鸟一个,希望各位大大讲的详细点。谢谢。 |
|
沙发#
发布于:2008-07-07 08:36
自己顶一下
|
|
板凳#
发布于:2008-07-07 09:33
这个版上已经有了,你可以往后找一下帖吧
|
|
|
地板#
发布于:2008-07-08 16:25
老大,可以告诉下那个帖子的标题吗?或者关键字,谢谢
|
|
地下室#
发布于:2008-07-09 09:29
|
|
5楼#
发布于:2008-07-09 16:30
为了研究MiniFilter中的读的过程,我加了些调试信息。我用notepad.exe打开了一个ddd.txt文件,然后什么都不做就关闭。
文件内容为AAAAA sdfd sfdsfsfghfdh,想把它改成Hello World!显示。在SwapPostReadBuffersWhenSafe中,代码为: RtlInitUnicodeString( &otxt, L"Hello World!" ); //初始化一个UNICODE_STRING LOG_PRINT( LOGFL_READ, ("[%d]SwapBuffers!SwapPostReadBuffersWhenSafe:before modify: otxt=%wZ otxtBuf=%s origBuf=%s mynewB=%s \n",LogingLineNo++, &otxt,otxt.Buffer, origBuf, p2pCtx->SwappedBuffer) ); RtlCopyMemory(p2pCtx->SwappedBuffer,otxt.Buffer,otxt.Length);// 拷贝到交换缓冲。 RtlCopyMemory( origBuf, p2pCtx->SwappedBuffer, Data->IoStatus.Information ); // 拷贝到原来的缓冲。 LOG_PRINT( LOGFL_READ, ("[%d]SwapBuffers!SwapPostReadBuffersWhenSafe:Content2: copylen=%d origBuf=%s mynewB=%s \n",LogingLineNo++, Data->IoStatus.Information, origBuf, p2pCtx->SwappedBuffer) ); 使用FltGetFileNameInformation函数获取文件信息,如果不能获取就直接leave.然后比较文件名,如果是ddd.txt就往下处理,不是就leave。 环境Winxp sp2,ddk是6001.18001,使用checked build编译,编译没有加任何参数。使用WinDbg+vmware调试 下面的是我在WinDbg中看到的信息: 调用SwapPreReadBuffers: [544]SwapBuffers!SwapPreReadBuffers: Extension=txt FinalComponent=ddd.txt FileName=\Device\HarddiskVolume1\Documents and Settings\VManOne\My Documents\ddd.txt Volume=\Device\HarddiskVolume1 ParentDir=\Documents and Settings\VManOne\My Documents\ [545]SwapBuffers!SwapPreReadBuffers: C: newB=81726BB0 newMdl=815B1430 oldB=011FDE40 oldMdl=00000000 len=24 [546]SwapBuffers!SwapPreReadBuffers:Content1: C: newB= oldB=揶揶揶揶揶揶揶揶揶揶揶揶]? 调用SwapPreReadBuffers: [547]SwapBuffers!SwapPreReadBuffers: Can't get file name info 不是ddd.txt文件,直接leave; 调用SwapPreReadBuffers: [548]SwapBuffers!SwapPreReadBuffers: Can't get file name info 不是ddd.txt文件,直接leave; 调用SwapPostReadBuffers: [549]SwapBuffers!SwapPostReadBuffers:They don't have a MDL and this is not a system buffer or a fastio 调用SwapPostReadBuffersWhenSafe: [550]SwapBuffers!SwapPostReadBuffersWhenSafe:before modify: otxt=Hello World! otxtBuf=H origBuf=揶揶揶揶揶揶揶揶揶揶揶揶]? mynewB=AAAAA sdfd sfdsfsfghfdh [551]SwapBuffers!SwapPostReadBuffersWhenSafe:Content2: copylen=24 origBuf=H mynewB=H 调用SwapPreReadBuffers: [552]SwapBuffers!SwapPreReadBuffers: Extension=txt FinalComponent=ddd.txt FileName=\Device\HarddiskVolume1\Documents and Settings\VManOne\My Documents\ddd.txt Volume=\Device\HarddiskVolume1 ParentDir=\Documents and Settings\VManOne\My Documents\ [553]SwapBuffers!SwapPreReadBuffers: C: newB=81726BB0 newMdl=81555498 oldB=011FDB78 oldMdl=00000000 len=24 [554]SwapBuffers!SwapPreReadBuffers:Content1: C: newB= oldB=揶揶揶揶揶揶揶揶揶揶揶揶]? 调用SwapPostReadBuffers: [555]SwapBuffers!SwapPostReadBuffers:They don't have a MDL and this is not a system buffer or a fastio 调用SwapPostReadBuffersWhenSafe: [556]SwapBuffers!SwapPostReadBuffersWhenSafe:before modify: otxt=Hello World! otxtBuf=H origBuf=揶揶揶揶揶揶揶揶揶揶揶揶]? mynewB=AAAAA sdfd sfdsfsfghfdh [557]SwapBuffers!SwapPostReadBuffersWhenSafe:Content2: copylen=24 origBuf=H mynewB=H 调用SwapPreReadBuffers: [558]SwapBuffers!SwapPreReadBuffers: Can't get file name info 调用SwapPreReadBuffers: [559]SwapBuffers!SwapPreReadBuffers: Extension=txt FinalComponent=ddd.txt FileName=\Device\HarddiskVolume1\Documents and Settings\VManOne\My Documents\ddd.txt Volume=\Device\HarddiskVolume1 ParentDir=\Documents and Settings\VManOne\My Documents\ [560]SwapBuffers!SwapPreReadBuffers: C: newB=815B78F8 newMdl=8133C660 oldB=011FE668 oldMdl=00000000 len=24 调用SwapPreReadBuffers: [561]SwapBuffers!SwapPreReadBuffers: Can't get file name info 调用SwapPreReadBuffers: [562]SwapBuffers!SwapPreReadBuffers:Content1: C: newB= oldB=揶揶揶揶揶揶揶揶揶揶揶揶]? 调用SwapPostReadBuffers: [563]SwapBuffers!SwapPostReadBuffers:They don't have a MDL and this is not a system buffer or a fastio [564]SwapBuffers!SwapPostReadBuffersWhenSafe:before modify: otxt=Hello World! otxtBuf=H origBuf=揶揶揶揶揶揶揶揶揶揶揶揶]? mynewB=AAAAA sdfd sfdsfsfghfdh [565]SwapBuffers!SwapPreReadBuffers: Extension=exe FinalComponent=notepad.exe FileName=\Device\HarddiskVolume1\WINDOWS\system32\notepad.exe Volume=\Device\HarddiskVolume1 ParentDir=\WINDOWS\system32\ [566]SwapBuffers!SwapPreReadBuffers: Can't get file name info [567]SwapBuffers!SwapPostReadBuffersWhenSafe:Content2: copylen=24 origBuf=H mynewB=H [568]SwapBuffers!SwapPreReadBuffers: Extension=txt FinalComponent=ddd.txt FileName=\Device\HarddiskVolume1\Documents and Settings\VManOne\My Documents\ddd.txt Volume=\Device\HarddiskVolume1 ParentDir=\Documents and Settings\VManOne\My Documents\ [569]SwapBuffers!SwapPreReadBuffers: C: newB=815B78F8 newMdl=81554958 oldB=011FE3A0 oldMdl=00000000 len=24 [570]SwapBuffers!SwapPreReadBuffers:Content1: C: newB= oldB=揶揶揶揶揶揶揶揶揶揶揶揶]? [571]SwapBuffers!SwapPreReadBuffers: Can't get file name info [572]SwapBuffers!SwapPreReadBuffers: Extension=exe FinalComponent=notepad.exe FileName=\Device\HarddiskVolume1\WINDOWS\system32\notepad.exe Volume=\Device\HarddiskVolume1 ParentDir=\WINDOWS\system32\ [573]SwapBuffers!SwapPreReadBuffers: Extension=exe FinalComponent=notepad.exe FileName=\Device\HarddiskVolume1\WINDOWS\system32\notepad.exe Volume=\Device\HarddiskVolume1 ParentDir=\WINDOWS\system32\ [574]SwapBuffers!SwapPreReadBuffers: Extension=exe FinalComponent=notepad.exe FileName=\Device\HarddiskVolume1\WINDOWS\system32\notepad.exe Volume=\Device\HarddiskVolume1 ParentDir=\WINDOWS\system32\ [575]SwapBuffers!SwapPostReadBuffers:They don't have a MDL and this is not a system buffer or a fastio [576]SwapBuffers!SwapPostReadBuffersWhenSafe:before modify: otxt=Hello World! otxtBuf=H origBuf=揶揶揶揶揶揶揶揶揶揶揶揶]? mynewB=AAAAA sdfd sfdsfsfghfdh [577]SwapBuffers!SwapPostReadBuffersWhenSafe:Content2: copylen=24 origBuf=H mynewB=H 问题是: 1、怎么会调用SwapPreReadBuffers那么多次?是否有好几个进程在读,都被swapbuffers捕获,所以在WinDbg看到的顺序是乱的? 2、swapbuffers中的leave是什么?宏?关键字?好像文档里面没有啊。 3、为什么读出的内容没有成Hello World!?还是原来的文字?如果用了maping file,我该怎么办? 谢谢每个进来看的人,特别是回帖关注的人,当然最感谢提出自己看法的人! |
|
6楼#
发布于:2008-07-09 17:54
又有了新的发现:
其实只要ddd.txt文件得到一次焦点,SwapPreReadBuffers就调用4次,不知道这4次都是谁在调用?关闭文件的时候并不调用。上次理解错了。 |
|
7楼#
发布于:2008-07-15 14:24
终于明白NOTEpad使用了mapingfile,不过还是不知道怎么清除缓冲。
|
|
8楼#
发布于:2008-07-16 09:37
终于解决了内存映射问题。可以安全的捕获NOTEpad的读了,应该说解密基本可以了,特此报告下。
经验: 好好去看ctx和swapbuffers例子,多用本论坛的搜索功能。最重要还是要靠自己。 |
|
9楼#
发布于:2008-07-21 16:40
作者: zhs_100
标题: 你好,请教关于swapbuffers的问题 时间: 2008-07-20 17:09 内容: 我今天看了一下swapbuffers的代码,在其中发现它在preRead和postRead中都把buffer换成我们新分配的newbuf了,但是我在不改它的源代码直接编译运行的情况下,发现那个sys没有任何作用。但是我们新分配的newbuf不是没有任何信息吗?此时用户读文件为什么不是读到一个空文件? 我在这里一直弄不明白,所以也不知道加解密操作应该在哪个地方进行,还请指教 ======================================= 那个swapbuffers例子是对交换缓冲不做任何处理的,当然就没有任何作用了 我是在内存拷贝前,对newbuf进行解密加密的。 RtlCopyMemory( origBuf, p2pCtx->SwappedBuffer, Data->IoStatus.Information ); 目前我只研究了如何解密,也就读的情况。在postread中处理。 谢谢你的关注,希望可以交流。 |
|
10楼#
发布于:2008-07-22 12:00
谢谢你的回复,我去尝试写一下。
|
|
11楼#
发布于:2008-07-22 13:26
再次请教楼主,请问你对付notepad之类的用内存映射来读的程序,是怎样解决FastIO的问题的?是用
http://bbs.driverdevelop.com/htm_data/39/0701/97907.html 这里的方法吗? 希望了楼主能给个思路。 |
|
12楼#
发布于:2008-07-23 09:29
差不多,我是用这个帖子的内容:
http://bbs.driverdevelop.com/htm_data/39/0703/100266.html |
|
13楼#
发布于:2008-07-25 16:18
汇报下,终于搞定了加密算法为取反的加解密,可以对txt,word,excel,ppt进行。其中比较变态的是Excel的文件保存,竟然是存个没有扩展名的临时文件,然后再改名成你要保存的文件。我是通过扩展名来过滤的,没有扩展名就晕了。后来只有获取进程应用程序名称才解决。
不过还有问题: 1、通过扩展名来过滤好不好啊?我自己觉得不是很好。如果用加密标示,是不是创建文件的时候就要询问是否加密啊,要不怎么知道这个新文件是否改加密呢。 2、我得到的是进程名称,没有去得到进程全路径,如果进程名称改变,我就又没法过滤Excel了。据说有人可以得到进程的特征码,例如找到进程的应用程序文件用hash算法比较,或者判断其加载的模块,我也觉得这样比较保险,但是还不知道怎么搞。 3、复杂的加密算法还么有试过,例如分组啊,变长啊,如果分组加密,每次读的如果不是一个完整的组该怎么办?是否是把完整的组解密,然后不完整的保存下来完整了再解密,不过万一读文件的时候不是顺序的读,而是随机的读该怎么办 希望路过的人对我这几个问题都发表下看法。 |
|
14楼#
发布于:2008-07-25 17:16
Re:MiniFilter研究贴:问swapbuffers中,在哪里加解密阿,新加了自己的
1 自包含最好,本身的数据中包含元字符,那么只要认识该标志的驱动都可以处理了。但是还是有困难。2 hash应该是可以。他利用的是加密算法里面的摘要特性。但是前提是你的摘要要保证和锁使用的进程是完全一致的,否则就不会成功。理想的方式是进程提供自己的证书方式来确认身份一致性。赫赫,有难度。 3 分组加密有困难,特别是选择CBC方式,几乎很难处理了。个人感觉还是对单个字节加密最省事了,赫赫 |
|
|
15楼#
发布于:2008-07-28 10:37
引用第13楼stpaladin于2008-07-25 16:18发表的 : 1、鉴于临时文件比较不好处理,我觉得用基于目录的过滤比较好 3、看了一些文章,都建议用不变长的加解密方法,否则比较难处理。 另,请问楼主跟踪文件名是用StreamContext、StreamHandleContext还是VolumeContext? 我的框架是基于SwapBuffers的。 先在PostCreat中判断是否目标文件,是的话就清缓存,再用StreamHandleContext把“是目标文件”这个BOOLEAN值传给PreRead,再用VolumeContext传newBuf等东西给PostRead同时还传一个和前面类似的BOOLEAN值,最后在PostRead中解密。但是我这样做系统有时候可以解密(记事本也没问题),有时候会死机重启。即使我禁用了清缓存命令,用写字板(不是记事本)也会用非法错误,请问是不是我这样用Context有问题? 盼指教。谢谢。 |
|
16楼#
发布于:2008-07-29 10:25
首先谢谢15楼的关注和回复。
我用的StreamContext。里面的过程和你的一样。先在PostCreat中判断是否目标文件,是的话就清缓存。 附我的结构: typedef struct _CTX_STREAM_CONTEXT { // // Name of the file associated with this context. // UNICODE_STRING FileName; UNICODE_STRING FileExtName; UNICODE_STRING FinalComponent; ULONG CallSign; BOOLEAN JM_Flag; BOOLEAN ReadFlag; BOOLEAN WriteFlag; // // Number of times we saw a create on this stream // ULONG CreateCount; // // Number of times we saw a cleanup on this stream // ULONG CleanupCount; // // Number of times we saw a close on this stream // ULONG CloseCount; // // Lock used to protect this context. // PERESOURCE Resource; } CTX_STREAM_CONTEXT, *PCTX_STREAM_CONTEXT; 至于你的死机或者重启问题,我怀疑是指针或者资源的释放问题。因为得到的Context都要释放的,还有文件名的指针。 我也有个问题,我现在改用RC4加密了,发现用记事本可以,但是office里面的程序都不行了。我的RC4源码如下: typedef struct rc4_key { unsigned char state[256]; unsigned char x; unsigned char y; } rc4_key; #define swap_byte(x,y) t = *(x); *(x) = *(y); *(y) = t void prepare_key(unsigned char *key_data_ptr, int key_data_len, rc4_key *key); void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key); #define RC4KEY "1234567890" #define RC4KEYLEN 10 void prepare_key(unsigned char *key_data_ptr, int key_data_len, rc4_key *key) { int i; unsigned char t; unsigned char swapByte; unsigned char index1; unsigned char index2; unsigned char* state; short counter; state = &key->state[0]; for(counter = 0; counter < 256; counter++) state[counter] = counter; key->x = 0; key->y = 0; index1 = 0; index2 = 0; for(counter = 0; counter < 256; counter++) { index2 = (key_data_ptr[index1] + state[counter] + index2) % 256; swap_byte(&state[counter], &state[index2]); index1 = (index1 + 1) % key_data_len; } } void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key) { unsigned char t; unsigned char x; unsigned char y; unsigned char* state; unsigned char xorIndex; short counter; x = key->x; y = key->y; state = &key->state[0]; for(counter = 0; counter < buffer_len; counter++) { x = (x + 1) % 256; y = (state[x] + y) % 256; swap_byte(&state[x], &state[y]); xorIndex = (state[x] + state[y]) % 256; buffer_ptr[counter] ^= state[xorIndex]; } key->x = x; key->y = y; } 在prewrite中的加密代码: ... rc4_key key; prepare_key(RC4KEY,RC4KEYLEN,&key); rc4((PUCHAR)newBuf,writeLen,&key); .................... 我怀疑是由于每次读写文件位置不同,也就是解密的密文不同了,导致无法解密。至于记事本,应该是由于记事本的txt文件比较小,每次都是一次性读写完,这样密文都不变。该怎么办呢 |
|
17楼#
发布于:2008-07-29 10:42
谢谢楼上的回复。
我的帖子说的重启、死机等问题,我现在解决了,就是在CleanUp中还要再次释放一次StreamHandleContext。 关于RC4的加解密,我用ProcessMon跟踪了一下,发现对于大于64KB的文件,写的时候通常是一次性写入,读的时候一般是分块读入,这对于RC4这种用伪随机数序列来加解密的有状态的算法,就会因为分块的不同而导致读的时候解密错误。所以,我觉得应该把块的大小设为通常程序的最大公约数,貌似是512bytes。这样子我用记事本已经可以读任何大小的文件并解密了,但是对于word文件、MP3文件和JPG文件还是不行。究其原因,我发现有些程序的读是貌似是多线程同时进行的,所以我用StreamHandleContext貌似是不正确的,可能应该用StreamContext。 望楼上可以加我QQ共同商讨,QQ号码上次已经发给你了。谢谢。 |
|
18楼#
发布于:2008-07-31 17:52
发现一个问题,可以通过共享目录将文件明文拷贝出去。过程很出乎意料。在另外一台机器上看装有过滤驱动的机器的共享目录里面的加密文件,可以看到明文,如果拷贝到本机,就彻底变成明文的文件了。这就是说查看另外一台机器的共享目录会调用远程机器的过滤驱动,这个应该要屏蔽掉。但是还不知道怎么做
|
|
19楼#
发布于:2012-03-19 17:04
|
|