欢迎转发,转发请注脚出处:

    欢迎转发,转发请评释出处:

浅谈系统服务分发,浅谈分发

    欢迎转发,转发请注脚出处:

0x00.说在前头

  就大家所知,Windows操作系统内核的圈套处理器会分发中断、万分和连串服务调用,这里大家就其中的种类服务分发简单解析一下。

 

0x01.粗看分裂电脑进入系统调用

  (1).在PentiumII
此前的x86处理器上,Windows使用int2e指令发出叁个陷阱,导致执行线程转到内核格局,进入系统服务分发器,eax保存种类服务号,edx指向参数列表。最后经过iret指令回到用户情势;

    
  大家查阅IDT的2e分子,得知该成员保存的地址是系统调用分发器的地点,紧接着u一下KiSystem瑟维斯,会发觉在保留完寄存器等景观之后,他走到了Ki法斯特CallEntry里面!(在Win7
x86下测试)

      澳门金沙国际 1

  (2).在x86Pentium II
处理器上,Windows使用了sysenter指令,内核的种类服务分发器例程的地方保存在与该指令相关联的八个MS帕杰罗中,eax,edx保存与int2e相同的始末。最终经过sysexit指令再次回到用户形式;

     那里读取MS福睿斯的0x176处,其中富含了系统服务分发器地址,发现其实调用的就是Ki法斯特CallEntry(入口)!(在Win7
x86下测试)

      澳门金沙国际 2

  (3).在x64连串架构上,Windows使用syscall指令,将系统调用号保存在eax中,前几个参数放在寄存器(rcx/rdx/r8/r9)中,剩下的参数在栈中。

    6二位平台读取MS奥迪Q5的0xC00000082处,里面保存的是6三位的syscall,当我们u一下那么些地方,发现这些就是x64系统调用分发的入口KiSystemCall64(在Win7
x64下测试)

      澳门金沙国际 3

    Ps:通过KiSystemCall64的地方可以透过硬编码拿到SSDT、SSSDT地址

 ……

澳门金沙国际 4

 

   大家发现,33人下,系统调用分发操作都会走到Ki法斯特CallEntry里面,而62位下,系统调用分发操作会走到KiSystemCall64,然后去达成相应的系统服务调用。那么大家有个问号,系统是怎么进来到这个连串调用的呢?

 

0x02.举例查看系统调用怎么着发生

  那里以Win7 x86 平台下的
NtOpenProcess为例,切换成2个进度内(如explorer.exe),u一下NtOpenProcess,那里浮现的是ntdll里的NtOpenProcess的反汇编:

  澳门金沙国际 5

  我们有多少个得到,二个是寓目了系统服务号放在了eax里了,另八个是它呼叫了一个地方,call指令将履行由基本建立起来的系统服务分发代码,该地点保存在ntdll!_KUSER_SHARED_DATA+0x300处,大家随后进这一个地方看看:

  澳门金沙国际 6

  大家如同有了一定量眉目了,系统调用在ntdll里面发生了,相当于说,在ntdll里面达成了从ring3到ring0的切换,其中eax保存服务号,edx保存参数列表首地址,通过服务号可以在SSDT中固定目的服务例程

  三贰12人下的KeServiceDescriptorTable各个成员固然目标系列服务的断然地址,陆拾肆位下的目的连串服务实在地址是KeServiceDescriptorTable每种成员保存的偏移量(右移3人后的)+KeServiceDescriptorTable集散地址;

  一初步线程的种类服务表地址指向Ntoskrnl.exe中的SSDT表,但当调用了一个USE哈弗或GDI服务时,服务表地址被改动成指向win32k.sys中的系统服务表。 

 

0x03.从用户层到内核层完整的调用进程

  (1).
当2个Windows应用程序调用Kernel32.dll中的OpenProcess时,其导入并调用了API-MS-Win-Core-File-L1-1-0.dll(三个MinWin重定向Dll)中的NtOpenProcess函数;

  (2).
接着上述的NtOpenProcess函数又会调用KernelBase.dll中的OpenProcess函数,那里是函数的确实完成,它会对子系统有关的参数做了反省;

  (3).
然后KernelBase!OpenProcess就会调用ntdll.dll中的NtOpenProcess函数,在那儿就会触发系统调用(ntdll!Ki法斯特SystemCall),传递NtOpenProcess的系统服务号和参数列表;

  (4).
系统服务分发器(Ntoskrnl.exe中的KiSystemService函数)就会调用真正的NtOpenProcess函数来处理该I/O请求。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0x04.内核形式下的系统分发

  在系统调用中,假如原先格局为用户形式,在给系统服务传递的参数指向了用户空间缓冲区时,内核方式代码在操作该缓冲区前会检查是或不是可以访问该缓冲区,而原先形式就是基本格局的时候,默许参数有效,则不会对参数举行检查。而既然已经在基础形式了,那就不必要int2e中断大概sysenter之类的操作了,但一旦一向像调用API一般直接调用NtOpenProcess之类的体系服务函数时,内核保存的原本格局值照旧是用户形式(进基本以前当然是用户格局咯~),但又检测到传递来的地址是八个基本方式地址(因为在当前根本情势下调用),于是会造成调用失利(STATUS_ACCESS_VIOLATION)。

  那里要介绍内核的Zw种类函数了,他们不光是Nt版本函数的别名或包装,而是对应Nt系列系统调用的翻版,使用了千篇一律的系统调用分发机制。他们会确立三个假的暂停栈(CPU在刹车后变化的栈),并向来调用KiSystemService例程,那几个历程就在模仿CPU中断,就像调用来自用户格局相似,而在检测到该调用的实际特权级后将本来格局修改为根本格局,那样也节省了参数校验,成功调用到NtOpenProcess!

  澳门金沙国际 7

 

 0x05.简单小结

   Ring3 —> Ring0 的种类调用:
Kernel32.dll(API)—>ntdll.dll(Nt/Zw)—>用户格局转内核方式—>Ntoskrnl.exe(Nt)—>完成I/O请求(原路再次回到)

   Ring0 —> Ring0
的系统调用:Ntoskrnl.exe(Zw)—>Ntoskrnl.exe(Nt)

   以上知情参考自《深切剖析Windows操作系统6》第3章,倘诺有不科学的地方还请提出,小编将谦虚求教!

欢迎转发,转发请注脚出处:
0x00.说在头里 就我们所知,Windows操作系统…

0x00 Hook技术

hook技术分为两块:

  • Ring3层的Hook,俗称应用层hook技术
  • Ring0层的Hook,俗称内核层Hook技术

Ring3层的hook又分为三种档次

  • Windows消息的hook
  • WindowsAPI的hook

一般来说图所示:

澳门金沙国际 8

hook1

澳门金沙国际 9

hook2

澳门金沙国际 10

hook1

关于Windows音信的Hook,相信广大爱人都有接触过的,因为一个SetWindowsHookEx即可以成功消息Hook,在此处大概介绍一下消息 Hook,消息 Hook
是通过SetWindowsHookEx可以完毕将自身的钩子插入到钩子链的最前端,而对于发送给被
Hook 的窗口(也有或者是全体的窗口,即全局
Hook)的音讯都会被大家的钩子处理函数所擒获到,约等于大家可以预先于窗体先捕获到这一个新闻,Windows
音讯 Hook 可以落成为经过内新闻 Hook 和大局音信 Hook,对于浅谈分发,浅谈系统服务分发。进度内音讯Hook,则可以省略的将 Hook 处理函数直接写在这一个进度内,即是本身 Hook
本人,而对此用途特别宽泛的大局消息 Hook,则须要将 Hook 处理函数写在一个DLL 中,这样才方可让您的处理函数被抱有的进度所加载(进度自动加载包括 Hook
音信处理函数的 DLL)。

对于 Windows 消息 Hook
呢,可以有个大致的凶悍应用,就是记录键盘按键音讯,从而落成监视用户输入的键值新闻的目标,那样,对于一些简单易行的用户通过键盘输入的密码就可以被
Hook 获取到,因为没当用户按下三个键时,Windows
都会发生一个按键音信(当然有按下,弹起等音讯的不同),然后大家可以 Hook
到那一个按键音信,那样就足以在 Hook
的音讯处理函数中拿走到用户按下的是怎么键了。

但是信息的hook不是本文的首要。

正文要讲的SSDT hook呢其实是属于内核Hook,常见于病毒以及杀软中。

下图显示了内核hook的多少个基本类型。

澳门金沙国际 11

Kernel hook

0x00.说在日前

0x00.说在前边

0x01 SSDT简介

SSDT全称System Service Descriptor
Table(系统描述符表),这几个表用于将Ring3的Win32API和水源的API联系起来。

SSDT并不仅只蕴涵一个巨大的地址索引表,它还蕴藏部分卓有功能的音信,如地址索引的基地址,服务函数的个数等。通过改动此表可以高达对一些关爱的系统动作进行过滤以及监督的目标。

在NT4.0的windows操作系统中,暗中同意存在三个系统服务描述符表,那四个描述符表对应了两类差其他系统服务,那多个表为:KeServiceDescriptorTable(SSDT)和KeServiceDescriptorTable(SSDT
Shadow)。其中SSDT负责处理来自Ring3层的Kernel32.dll的连串调用。而SSDT
Shadow则主要处理来自User32.dll和GDI32.dll的系统调用。同时SSDT在ntoskrnl.exe中是导出的,而SSDT
Shadow如其名是未被Windows所导出的,而至于SSDT的全体内容都是通KeServiceDescriptorTable来落成的。

以下截图声明,KeServiceDescriptorTable是在ntoskrnl.exe中被导出的:

澳门金沙国际 12

Export1

随即我们看看看看Windows操作系统的源码中怎么着定义KeServiceDescriptorTable的,通过观看W福睿斯K可见,

澳门金沙国际 13

KeServiceDescriptorTable in WRK

如此看照旧有点蛋疼呀。改写以下变量的称号吧。

    typedef struct _KSYSTEM_SERVICE_TABLE{
        PULONG ServiceTableBase;            //SSDT的基地址指针
        PULONG ServiceCounterTableBase; //SSDT中每个服务被调用次数表的基地址指针
        ULONG NumberOfService;              //服务函数个数,NumberOfService*4就是整个地址表的大小
        ULONG ParamTableBase;               //SSPT的基地址
    }KSYSTEM_SERVICE_TABLE,*PKSYSTEM_SERVICE_TABLE;
    typedef struct _KSERVICE_TABLE_DESCRIPTOR{
        KSYSTEM_SERVICE_TABLE ntoskrnl;     //ntoskrnl.exe的服务函数
        KSYSTEM_SERVICE_TABLE win32k;       //win32k.sys的服务函数(GDI32/User32)
        KSYSTEM_SERVICE_TABLE notUsed1;
        KSYSTEM_SERVICE_TABLE notUsed2;
    }KSERVICE_TABLE_DESCRIPTOR,*PKSERVICE_TABLE_DESCRIPTOR;
    //导出由ntoskrnl.exe所导出的SSDT
    extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;

从上述介绍可以,Ke瑟维斯DescriptorTable可以视作是三个数组,是陆个KSYSTEM_SERVICE_TABLE结构形成的数组,而各种KSYSTEM_SERVICE_TABLE对应多个PE文件导出的服务描述符表,依据这一个劳务描述符表大家可以赢得特别详实的服务音讯。在应用层ntdll.dll中的API在那些系统服务描述表中都留存五个与之相应的劳务,当大家的应用程序调用ntdll.dll里的API时最终可以调用对应的系列服务函数,文告给基础三个索引,内核通过该索引在SSDT中搜寻对应的服务,内核调用服务到位应用的API调用请求。

  就我们所知,Windows操作系统内核的圈套处理器会分发中断、非常和种类服务调用,那里我们就其中的连串服务分发不难分析一下。

  就大家所知,Windows操作系统内核的圈套处理器会分发中断、极度和体系服务调用,那里大家就其中的连串服务分发简单解析一下。

应用层调用Win32API流程

有了上述的SSDT基础后,大家再来看看在应用层调用Win32API(首要指ntdll.dll中的API)的流程,大家重点针对ntdll.dll中的NtQuerySystemInformation那些API的调用流程来开展演说。

此地存在多个类似的API。

澳门金沙国际 14

4APIs

再提交那个API的调用流程。

澳门金沙国际 15

calling way

那边大家可以看看ntdll.dll中的nt和zw都会跻身内核层去调用ntoskrnl的zw函数,而zw最终会调用nt函数,这些函数作为内核API最终去乞求系统服务的施行。
用exescope工具得以打开ntdll.dll,看到NtQuerySystemInformation以及ZwQuerySystemInformation。

澳门金沙国际 16

ntdll1

澳门金沙国际 17

ntdll2

而实质上zw和nt都以同一函数,指向同一区域,入口地址一样。

由此Ntdll.dll中的API都以对内核API的卷入,当Kernel32.dll中的API通过Ntdll.dll去调用系统API时,会开展参数检查,并调用中断(int
2Eh或SysEnter),从而从Ring3跻身Ring0,并将所要调用的服务号,即SSDT数组的索引值,存放进寄存器EAX中,并且将参数地址放到指定的寄存器EDX中,再复制参数到根本地址空间,依照存放在EAX中的索引值来在SSDT数组中调用钦赐的劳务。

通过地点步骤大家来到Ring0层。使用exescope看看ntoskrnl.exe中的ZwQuerySystemInformation以及NtQuerySystemInformation。

澳门金沙国际 18

ntoskrnl1

澳门金沙国际 19

ntoskrnl2

再反汇编ntoskrnl那一个文件可以见见Zw函数中调用KiSystemService系统服务分发函数时往EAX中存放了索引号ADh。如图:

澳门金沙国际 20

ZwQSystemInfor

随之依照该索引值检索SSDT项,最终按照该SSDT项中所存放的序列服务地点来调用这么些系统服务。在此间就是调用KeServiceDescriptorTable[ADh]处保存的地方对应的系统服务。那就是Ring0下的NtQuerySystemInformation。

 

 

0x02 详解SSDT

这节内我们用WinDbg来调节XP系统,借此验证SSDT是个怎么样鬼。
据大家上文的布局定义可见,Ke瑟维斯DescriptorTable是3个针对性5个KSYSTEM_SERVICE_TABLE结构首地点的指针,以下图为例吧。

澳门金沙国际 21

dd KeServiceDescriptorTable

那里的0x80563520这一行就是ntoskrnl对应的劳动描述符表结构KSYSTEM_SERVICE_TABLE。那么首先个3一个人的0x804e58a0则是对应ntoskrnl对应的KSYSTEM_SERVICE_TABLE中的SSDT
Base
,即服务描述符表的首地址。通过对该首地址的dump,我们可以寓目众多以1二十六位为一组排列的劳务描述符,每一种描述符中的第贰个叁九位(0x80591bfb)对应着系统服务的进口地址。通过对该入口地址的反汇编,可以看来那是SSDT第3个系统服务NtAcceptConnectPort函数。如图:

澳门金沙国际 22

NtAcceptConnectPort

那就是说透亮了SSDT首地址,同时知道了目录,那么我们就能够经过索引来找到相应的序列服务入口地址了。通过测算“SSDT中系统服务地方所在的地址
= SSDT首地址 + 4 *
索引值”,可以推算出NtQuerySystemInformation的开头地址位0x80586ff1,对该地方举办反汇编,可得下图:

澳门金沙国际 23

NtQuerySystemInformation

因而可见,SSDT就是个保存Windows系统服务地点的数组。

0x01.粗看不相同电脑进入系统调用

0x01.粗看分裂电脑进入系统调用

0x03 SSDT hook原理

从上边的分析中大家得以看来SSDT数组中保留了系统服务的地址,如Ring0下的NtQuerySystemInformation系统服务地方,就保留在KeServiceDescriptorTable[ADh]中,既然hook就是取出那一个地方后替换上我们的hook函数,在hook函数中施行原函数即可。

参考文献:

http://www.cnblogs.com/boyxiao/archive/2011/09/03/2164574.html

  (1).在PentiumII
从前的x86处理器上,Windows使用int2e指令发出3个陷阱,导致执行线程转到内核格局,进入系统服务分发器,eax保存种类服务号,edx指向参数列表。最后经过iret指令回到用户方式;

  (1).在PentiumII
从前的x86处理器上,Windows使用int2e指令发出贰个骗局,导致执行线程转到内核方式,进入系统服务分发器,eax保存种类服务号,edx指向参数列表。最终经过iret指令回到用户格局;

    
  我们查阅IDT的2e成员,得知该成员保存的地点是系统调用分发器的地方,紧接着u一下KiSystemService,会发以往保留完寄存器等意况之后,他走到了Ki法斯特CallEntry里面!(在Win7
x86下测试)

    
  大家查阅IDT的2e成员,得知该成员保存的地方是系统调用分发器的地方,紧接着u一下KiSystemService,会发以往保存完寄存器等情景之后,他走到了Ki法斯特CallEntry里面!(在Win7
x86下测试)

      澳门金沙国际 24

      澳门金沙国际 25

  (2).在x86Pentium II
处理器上,Windows使用了sysenter指令,内核的系统服务分发器例程的地点保存在与该指令相关联的二个MS大切诺基中,eax,edx保存与int2e相同的始末。最终经过sysexit指令再次来到用户格局;

  (2).在x86Pentium II
处理器上,Windows使用了sysenter指令,内核的系统服务分发器例程的地址保存在与该指令相关联的多个MS哈弗中,eax,edx保存与int2e相同的内容。最终经过sysexit指令再次来到用户情势;

     那里读取MS奥德赛的0x176处,其中蕴藏了系统服务分发器地址,发现实际调用的就是Ki法斯特CallEntry(入口)!(在Win7
x86下测试)

     这里读取MSRAV4的0x176处,其中带有了系统服务分发器地址,发现实际调用的就是KiFastCallEntry(入口)!(在Win7
x86下测试)

      澳门金沙国际 26

      澳门金沙国际 27

  (3).在x64连串架构上,Windows使用syscall指令,将系统调用号保存在eax中,前四个参数放在寄存器(rcx/rdx/r8/r9)中,剩下的参数在栈中。

  (3).在x64连串架构上,Windows使用syscall指令,将系统调用号保存在eax中,前八个参数放在寄存器(rcx/rdx/r8/r9)中,剩下的参数在栈中。

    60人平台读取MSOdyssey的0xC0000082处,里面保存的是陆拾个人的syscall,当大家u一下以此地方,发现这几个就是x64系统调用分发的入口KiSystemCall64(在Win7
x64下测试)

    6三人平台读取MSGL450的0xC0000082处,里面保存的是6肆位的syscall,当大家u一下这些地方,发现那一个就是x64系统调用分发的入口KiSystemCall64(在Win7
x64下测试)

    
 澳门金沙国际 28

    
 澳门金沙国际 29

    Ps:通过KiSystemCall64的地址可以经过硬编码得到SSDT、SSSDT地址

    Ps:通过KiSystemCall64的地点可以经过硬编码得到SSDT、SSSDT地址

 ……

 ……

澳门金沙国际 30

澳门金沙国际 31

 

 

澳门金沙国际 ,   我们发现,3肆个人下,系统调用分发操作都会走到Ki法斯特CallEntry里面,而6二位下,系统调用分发操作会走到KiSystemCall64,然后去做到相应的系统服务调用。那么我们有个疑问,系统是怎么进来到这么些系统调用的吗?

   大家发现,33个人下,系统调用分发操作都会走到KiFastCallEntry里面,而61个人下,系统调用分发操作会走到KiSystemCall64,然后去做到相应的连串服务调用。那么大家有个难题,系统是怎么进入到这几个种类调用的吗?

 

 

0x02.举例查看系统调用怎么着发生

0x02.举例查看系统调用怎么样发生

  那里以Win7 x86 平台下的
NtOpenProcess为例,切换成三个历程内(如explorer.exe),u一下NtOpenProcess,那里显得的是ntdll里的NtOpenProcess的反汇编:

  那里以Win7 x86 平台下的
NtOpenProcess为例,切换来一个经过内(如explorer.exe),u一下NtOpenProcess,这里突显的是ntdll里的NtOpenProcess的反汇编:

  澳门金沙国际 32

  澳门金沙国际 33

  大家有四个得到,3个是看到了系统服务号放在了eax里了,另3个是它呼叫了1个地方,call指令将推行由基础建立起来的系统服务分发代码,该地点保存在ntdll!_KUSER_SHARED_DATA+0x300处,我们随后进那一个位置看看:

  大家有三个拿到,一个是来看了系统服务号放在了eax里了,另2个是它呼叫了3个地点,call指令将执行由基础建立起来的系统服务分发代码,该地点保存在ntdll!_KUSER_SHARED_DATA+0x300处,大家随后进那个地方看看:

  澳门金沙国际 34

  澳门金沙国际 35

  大家如同有了点滴眉目了,系统调用在ntdll里面发生了,也等于说,在ntdll里面完成了从ring3到ring0的切换,其中eax保存服务号,edx保存参数列表首地址,通过服务号可以在SSDT中稳定目的服务例程

  大家就像有了零星眉目了,系统调用在ntdll里面发生了,相当于说,在ntdll里面完结了从ring3到ring0的切换,其中eax保存服务号,edx保存参数列表首地址,通过服务号可以在SSDT中稳定目标服务例程

  30位下的KeServiceDescriptorTable各种成员即便目的系列服务的相对地址,6肆人下的靶子种类服务真正地址是KeServiceDescriptorTable每种成员保存的偏移量(右移2人后的)+Ke瑟维斯DescriptorTable基地址;

  三十几位下的KeServiceDescriptorTable各个成员就是目的连串服务的相对地址,6四人下的靶子系列服务真正地址是KeServiceDescriptorTable各种成员保存的偏移量(右移几位后的)+KeServiceDescriptorTable集散地址;

  一起首线程的系统服务表地址指向Ntoskrnl.exe中的SSDT表,但当调用了3个USECRUISER或GDI服务时,服务表地址被涂改成指向win32k.sys中的系统服务表。 

  一开头线程的种类服务表地址指向Ntoskrnl.exe中的SSDT表,但当调用了2个USE奥迪Q7或GDI服务时,服务表地址被改动成指向win32k.sys中的系统服务表。 

 

 

0x03.从用户层到内核层完整的调用进程

0x03.从用户层到内核层完整的调用进程

  (1).
当一个Windows应用程序调用Kernel32.dll中的OpenProcess时,其导入并调用了API-MS-Win-Core-File-L1-1-0.dll(3个MinWin重定向Dll)中的NtOpenProcess函数;

  (1).
当四个Windows应用程序调用Kernel32.dll中的OpenProcess时,其导入并调用了API-MS-Win-Core-File-L1-1-0.dll(一个MinWin重定向Dll)中的NtOpenProcess函数;

  (2).
接着上述的NtOpenProcess函数又会调用KernelBase.dll中的OpenProcess函数,那里是函数的真正兑现,它会对子系统有关的参数做了反省;

  (2).
接着上述的NtOpenProcess函数又会调用KernelBase.dll中的OpenProcess函数,那里是函数的真的落实,它会对子系统相关的参数做了检讨;

  (3).
然后KernelBase!OpenProcess就会调用ntdll.dll中的NtOpenProcess函数,在那时候就会接触系统调用(ntdll!Ki法斯特SystemCall),传递NtOpenProcess的系统服务号和参数列表;

  (3).
然后KernelBase!OpenProcess就会调用ntdll.dll中的NtOpenProcess函数,在此刻就会接触系统调用(ntdll!Ki法斯特SystemCall),传递NtOpenProcess的体系服务号和参数列表;

  (4).
系统服务分发器(Ntoskrnl.exe中的KiSystemService函数)就会调用真正的NtOpenProcess函数来处理该I/O请求。

  (4).
系统服务分发器(Ntoskrnl.exe中的KiSystemService函数)就会调用真正的NtOpenProcess函数来拍卖该I/O请求。

 澳门金沙国际 36

 澳门金沙国际 37

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0x04.水源格局下的种类分发

0x04.根本形式下的体系分发

  在系统调用中,假设原本情势为用户格局,在给系统服务传递的参数指向了用户空间缓冲区时,内核方式代码在操作该缓冲区前会检查是还是不是可以访问该缓冲区,而原先方式就是根本情势的时候,暗许参数有效,则不会对参数进行检查。而既然已经在基本情势了,那就不须求int2e中断恐怕sysenter之类的操作了,但借使直接像调用API一般直接调用NtOpenProcess之类的连串服务函数时,内核保存的原本形式值仍旧是用户方式(进基本以前当然是用户格局咯~),但又检测到传递来的地方是叁个基石格局地址(因为在当前基本形式下调用),于是会造成调用败北(STATUS_ACCESS_VIOLATION)。

  在系统调用中,假诺原先格局为用户情势,在给系统服务传递的参数指向了用户空间缓冲区时,内核形式代码在操作该缓冲区前会检查是不是足以访问该缓冲区,而本来方式就是内核形式的时候,默许参数有效,则不会对参数举行反省。而既然已经在基础方式了,那就不必要int2e中断或然sysenter之类的操作了,但如果一向像调用API一般间接调用NtOpenProcess之类的系统服务函数时,内核保存的本原情势值还是是用户情势(进基本从前当然是用户形式咯~),但又检测到传递来的地点是八个基础格局地址(因为在现阶段根本形式下调用),于是会导致调用战败(STATUS_ACCESS_VIOLATION)。

  那里要介绍内核的Zw种类函数了,他们不不过Nt版本函数的别名或卷入,而是对应Nt连串系统调用的翻版,使用了相同的种类调用分发机制。他们会确立2个假的刹车栈(CPU在刹车后变卦的栈),并从来调用KiSystemService例程,这么些进度就在模仿CPU中断,似乎调用来自用户形式相似,而在检测到该调用的实际特权级后将原来形式修改为基石情势,那样也节约了参数校验,成功调用到NtOpenProcess!

  那里要介绍内核的Zw种类函数了,他们不光是Nt版本函数的别名或包装,而是对应Nt序列系统调用的翻版,使用了相同的系统调用分发机制。他们会确立三个假的中止栈(CPU在刹车后变更的栈),并一向调用KiSystemService例程,这么些进度就在模仿CPU中断,就像是调用来自用户情势相似,而在检测到该调用的骨子Ritter权级后将本来方式修改为基石方式,这样也省去了参数校验,成功调用到NtOpenProcess!

  澳门金沙国际 38

  澳门金沙国际 39

 

 

 0x05.不难小结

 0x05.不难小结

   Ring3 —> Ring0 的系统调用:
Kernel32.dll(API)—>ntdll.dll(Nt/Zw)—>用户情势转内核形式—>Ntoskrnl.exe(Nt)—>完结I/O请求(原路重临)

   Ring3 —> Ring0 的系统调用:
Kernel32.dll(API)—>ntdll.dll(Nt/Zw)—>用户情势转内核格局—>Ntoskrnl.exe(Nt)—>达成I/O请求(原路重临)

   Ring0 —> Ring0
的系统调用:Ntoskrnl.exe(Zw)—>Ntoskrnl.exe(Nt)

   Ring0 —> Ring0
的系统调用:Ntoskrnl.exe(Zw)—>Ntoskrnl.exe(Nt)

   以上知情参考自《深远剖析Windows操作系统6》第1章,即使有不得法的地点还请指出,小编将谦虚求教!

   以上知情参考自《深远剖析Windows操作系统6》第一章,如果有不得法的地点还请指出,作者将谦虚求教!

相关文章