CreateFile函数执行的全过程

CreateFile函数执行全过程

CreateFile的Ring3流程

HANDLE CreateFileA(
  LPCSTR                lpFileName,
  DWORD                 dwDesiredAccess,
  DWORD                 dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD                 dwCreationDisposition,
  DWORD                 dwFlagsAndAttributes,
  HANDLE                hTemplateFile
);

CreateFile是一个非常普通常见的函数,当在VS中写下代码,或者Debug时F8了一下,没有人关心一个CreateFile到底经历了什么流程,怎样的运行机制才打开文件。今天有兴趣研究一下。研究就要研究透彻,这样以后调用每个API时都会有丝丝快感。
在这里插入图片描述
Kernel32.dll中的CreateFile。只是一句jmp,这个间接动态跳转指令。通过X64dbg可以看到是跳转到了Kernelbase32.dll中。
在这里插入图片描述
在Kernelbase32.dll中将打开的文件路径添加"/??/"符号,经过CreateFileInternal函数后执行下图的__GSHandlerCheck代码。
在这里插入图片描述
这个GSHandlerCheck代码不太明白,感觉不太重要,应该就是为进入Ring0进行一些准备性工作。有空再研究。
在这里插入图片描述
最终调用NtCreateFile函数。下步将会去ntdll.dll执行NtCreateFile。对于Ring3下的一些API,最终会对应于Ntdll.dll里一个Ntxxx的函数(也就是Native API)。例如这次的CreateFile,最终调用到Ntdll.dll里的NtCreateFile这个函数,NtCreateFile最终将系统服务号放入EAX,然后CALL系统的7FFE0300处存放的一个地址(后面细说),进入到内核当中,从Ring3->Ring0,最终在Ring0当中通过传入的EAX得到对应的同名系统服务的内核地址。
在这里插入图片描述
对于NtCreateFile而言,是和ZwCreateFile一样的,程序在ntdll这一层将进入系统调用,经入Ring0层。
上图0x55是本系统上NtCreateFile函数的SSDT调用号,本系统支持syscall指令,故不会执行旧版本的int 0x2E进入系统内核。SSDT的表就是一个存放着函数指针的表,而这些函数指针指向的就是系统重要的服务例程。这个表的重要性很高,如果说有恶意的程序对这个表进行了HOOK,修改了服务例程地址为自己提供的假服务例程,那么就可以干一些坏事了。
在这里插入图片描述
如上图所示,进入Ring0后寄存器发生不少变化,至此我们的X64dbg已经调试不了,不能继续深入。换工具Windbg,OD调试32位程序时也是一样,无法深入到syscall内核层继续追踪。

继续追踪Ring0流程

之后的流程是:KiFastSystemCall->sysenter->KiFastCallEntry->查找SSDT,call过去.有兴趣的同学可以在WRK当中搜索相关的函数去走一下流程。
欢迎来到0x80000000-0xFFFFFFFF的内核地址空间,调试器已经废了,但我们可以用BTS驱动继续捕捉执行流程跟踪下去。
Ring3上面的HOOK和对抗技术实在太多了,特别是SSDT HOOK这种最常见也最容易检测(直接拿内核中的硬编码副本和内存中的内核地址去比较)。但是一旦对抗方(假使是内核级rootkit)在机器中安装了驱动程序,CreateFile的对抗就是Ring0级别的对抗。
从Pchunter中可以看到SSDT的文件位置在ntoskr.exe中(如果你没有被HOOK的话)。还可以找到NtCreateFile的SSDT调用号。
在这里插入图片描述
在ntoskrnl.exe中找到NtCreateFile的实现,注意这个NtCreateFile已经和Ring3的NtCreateFile没有关系了,虽然它们重名,但是因为是在两个不同的世界,所以不会出错(就像你和你的反物质一样…)。函数中又调用了IopCreateFile函数,显然CreateFile的故事还很长。
在这里插入图片描述
废话不再多说,上图是剩余的全部调用流程。上图中使用IO管理器的IopCreateFile函数。Inline Hook IopCreateFile函数见 看雪论坛:Inline Hook IopCreateFile函数。驱动开发中常见的IoCreateFile的实现函数是IopCreateFile(iosubs.c)。

在此之后就是文件管理驱动程序的函数。I/O管理器担当着用户模式代码和驱动程序之间的接口。驱动程序会以一种安全稳定的方式处理或转发I/O管理器发送过来的IRP,最终与硬件抽象层hal.dll完成交互,完成并反馈CreateFile的操作请求。

总结

在这里插入图片描述
可见一个CreateFile函数的调用全过程,涉及到了太多Windows平台的知识。Win32 API接口,内核原理与结构,驱动开发等方面都有涉及得到。乍看起来感觉CreateFile打开文件流程十分复杂,而用汇编指令IN OUT直接就可以对文件设备I/O进行操作。为什么在windows上却需要如此复杂的流程?答案就是两个字——安全。可见越成熟越统一的产品为了安全两字付出的代价之大。
Rootkit病毒程序可能会在上面任何一个过程中HOOK其中一个函数,达到控制文件(设备)的读取打开。所以长期以来安全软件和病毒开发的技术对抗不会离开这条必须的战线,一直是在做HOOK与反HOOK,结束与被结束的斗争。传统的解决方案仍然停留在这种函数级别的对抗之上。
学海无涯苦作舟,对于Windows的学习与研究之路仍然任重道远。

猜你喜欢

转载自blog.csdn.net/qq_43312649/article/details/107796994