4.API的调用过程(系统服务表)

SystemServiceTable(系统服务表)
在这里插入图片描述

typedef struct _KSYSTEM_SERVICE_TABLE
{
	PULONG ServiceTableBase;		//这个指向系统服务函数地址表
	PULONG ServiceCounterTableBase;	//系统这个服务表调用了几次
	ULONG NumberOfService;			//服务函数的个数
	PULONG ParamTableBase;			//参数表 

}KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;

函数参数表里的是以字节为单位的,SystemServiceTable只有两张。

函数地址表里的函数都是内核导出函数,里面只是Ntoskrl.exe其中的一部分函数并不是所有函数。(3环常用的api基本都在里面了)

函数地址表与函数参数表是一一相对的,比如函数地址表第一个成员那么它的参数个数就是参数表的第一个成员。

画程序界面、gdi之类的都在Win32k.sys中。

SystemServiceTable就在_KTHREAD+0xE0处,当程序执行后CUP只要得到当前程序的线程就能找的系统访问表。

在这里插入图片描述

  • 在3环调用api进入0环需要提供一个操作码,这操作码将决定我要调用的函数在哪。
  • 这个操作码虽然它只有32位但它只使用了低13位。
  • 如果它的第13位为0那么他在Ntoskrl.exe,1在win32k.sys
  • 它的低12位就是对应的函数地址表的索引

_KiFastCallEntry 的过程

  				 mov     edi, eax        ; 取出操作码
                 shr     edi, 8          ; 操作码右移8位
                 and     edi, 30h        ; 再将它&30h 结果只有两种010h
                                         ; (也就是下标12的位置为0 或者1)
                 mov     ecx, edi
                 add     edi, [esi+0E0h] ; _KTHREAD->ServiceTable(0xE0)
                 mov     ebx, eax
                 and     eax, 0FFFh      ; 取操作码的后12(索引)
                 cmp     eax, [edi+8]    ; typedef struct _SYSTEM_SERVICE_TABLE
                                         ;   {
                                         ;   
                                         ;   PVOID ServiceTableBase; //这个指向系统服务函数地址表
                                         ;    PULONG ServiceCounterTableBase;//系统这个服务表调用了几次
                                         ;   ULONG NumberOfService; //服务函数的个数
                                         ;   ULONG ParamTableBase;//参数表
                                         ;   
                                         ;   }SYSTEM_SERVICE_TABLE,*PSYSTEM_SERVICE_TABLE;
                                         ; +8 = NumberOfService
                                         ; 这里判断要找的函数有没有超出范围
                 jnb     _KiBBTUnexpectedRange
                 cmp     ecx, 10h        ;0x10比较 如果是0x10查第二张系统服务表
                                         ; 如果为0,jnz 到 第一张系统服务表
                 jnz     short loc_4077C0 ; KPRCD->0x518 KeSystemCalls 增加1
                 mov     ecx, ds:0FFDFF018h
                 xor     ebx, ebx

 loc_4077AE:                             ; DATA XREF: _KiTrap0E+110o
                 or      ebx, [ecx+0F70h] ; 这一块只有调用第二张系统服务表才会执行
                 jz      short loc_4077C0 ; GUI之类的东西不是一次性加载的
                 push    edx             ; 要用的时候动态加载的
                 push    eax
                 call    ds:_KeGdiFlushUserBatch
                 pop     eax
                 pop     edx

 loc_4077C0:                             ; CODE XREF: _KiFastCallEntry+B4j
                                         ; _KiFastCallEntry+C4j
                 inc     dword ptr ds:0FFDFF638h ; KPRCD->0x518 KeSystemCalls 增加1
                 mov     esi, edx        ; edx存着3环传入的参数指针
                 mov     ebx, [edi+0Ch]  ; ParamTableBase;//参数表
                 xor     ecx, ecx
                 mov     cl, [eax+ebx]   ; eax=索引 +参数表= 得到的调用号得到的参数个数
                 mov     edi, [edi]      ; [ServiceTableBase]; 得到函数地址表
                 mov     ebx, [edi+eax*4] ; 0环函数的地址
                 sub     esp, ecx        ; 提升堆栈为cl
                 shr     ecx, 2          ; 右移2= 参数总长度/4 == 参数个数
                                         ; 因为rep指令一次复制4字节,所以除4
                 mov     edi, esp        ; 设置要拷贝到的地址
                 cmp     esi, ds:_MmUserProbeAddress ; 判断3环参数是否越界
                 jnb     loc_407990

 loc_4077E8:                             ; CODE XREF: _KiFastCallEntry+2A4j
                                         ; DATA XREF: _KiTrap0E+106o
                 rep movsd               ; 开始拷贝参数 ecx几就拷贝几次
                 call    ebx             ; 调用函数

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值