从R3 ,到磁盘
1:kernel32 WriteFile
1)
挺惊讶的,符号好使了,
前面大概4条判断,根据句柄判断要写到什么地方,一共有4个地方可能要去,
stdin stdout stderr 还有最后一个 控制台
2)然后就是一个异步的判断
如果是异步,那么整理信息,然后调用NtWriteFile,根据返回值判断情况成功了,返回1
否则返回0
这里不考虑,主要考虑同步的情况
3)同步的位置
倒是不拖拉,直接就走Nt函数准备进内核了
2:
1)内核里面,一个深情的问候,先获取有用的信息,ETHREAD,和FILE_OBJECT,还有设备对象
2)打了招呼,开始干活
Zw函数的标准玩法,先判断处于用户模式还是内核模式,其实我就很搞不懂,
驱动里面,Zw函数和Nt函数就那么点区别,一个判断内核模式,一个不判断内核模式,
判断了之后,简单地说,就是修改模式之后,Zw调用Nt,然后再走原有流程,
这里直接判断了,应该是优化了吧。
3)做完环境判断之后,
开始准备可能用到的结构了,
4)准备结构之后,还有一个步骤,
1.就是判断是否为同步操作,
如果是同步操作的话,那么后面直接走
2.并行的步骤还有个判断异步的
这里顺带判断了,如果传入字符个数是0个,并且又是非管道或者邮槽操作,
(这里要说一下,其实,管道等的操作,写入地址是NULL,写入字符个数0个,实际上是个常规操作,不算是违规操作)
5)这里先看同步操作吧
1。首先,设置当前状态,给文件系统,告诉它我现在在忙,我有同步的事情正在做
如果以前有人设置了,那么v17 = 0,否则减个引用计数,然后v17 = 1。
2。如果之前有人设置过了,那么这里自己获取一个文件对象锁
这里有个细节,其实挺奇怪的,这里加了锁,但是后面没有地方Release这个锁,所以是不是可以考虑,这个锁根本就不会加,
也就是说不会走到这里,也就是说当前文件不会有其他人在用,但是这不科学,这个理论说不通。
其实后面有地方SetEvnet了。是不是就为了这个锁而存在的。
3。
如果要写入的字符个数为0个,并且v35,没有修正,或者值有异常,
那么就把它修正为当前文件的偏移位置。
4。又是一个分水岭,这里,如果这个成员有值,则继续走内部流程,否则就走到外面去了,外面就是和异步流程相同的其它流程了
其实,这个成员是干嘛的,我就没搞清楚
An opaque member, set only by file systems, that points to handle-specific information and that is used for Cache Manager interaction.
MSDN上,只有这么一段话,说一个不透明的成员,只有文件系统可以操作它,类似于句柄,是和CM交互用的。
我是不是可以猜测成,这个东西的存在,就是说CM中,我要改写的这个文件已经进入缓存了,我直接修改缓存就可以了,所以才出现这个判断。
没有缓存的话,那就自然不是简单操作就能完成任务的。
5。这个判断,真的搞得我好郁闷,
首先判断 v35 的高位 < 0 ,就是说,它必须是 0xFFFF,
然后并且,v35 的值不为 -1 ,就是说,v35的值必须是 0xFFFF0000 ~ 0xFFFFFFFE
这是要判断什么呢,根据前面的经验,实际上这里出现这种值得可能性几乎没有,因为在前面已经通过各种设置,
设置了v35的值,不会变成这个样子,除非是文件位置的有意为之。
v35实际上是文件指针当前偏移,
6。终于到了同步最后一个位置了
这里的操作比较好理解,首先
1 typedef 2 BOOLEAN 3 FAST_IO_WRITE ( 4 __in struct _FILE_OBJECT *FileObject, 5 __in PLARGE_INTEGER FileOffset, 6 __in ULONG Length, 7 __in BOOLEAN Wait, 8 __in ULONG LockKey, 9 __in PVOID Buffer, 10 __out PIO_STATUS_BLOCK IoStatus, 11 __in struct _DEVICE_OBJECT *DeviceObject 12 );