系统调用(三): 分析KiFastCallEntry(二)

SystemServiceTable 系统服务表

ServiceTable:指向函数地址表
Count:系统服务表被调用次数
ServiceLimit:函数数量
ArgmentTable:指向函数参数表

当进入0环之前,在eax中存了一个数字,称为系统调用号,以0x115举例

0000000000000000000 0 000100010101
从13到31没有使用
12位=0:Ntoskrl.exe
12位=1:Win32k.sys
0到11位用来索引地址表和参数表

分析KiFastCallEntry

.text:00407781 loc_407781:                             ; CODE XREF: _KiBBTUnexpectedRange+18↑j
.text:00407781                                         ; _KiSystemService+6E↑j
.text:00407781                 mov     edi, eax        ; edi=eax(系统调用号)
.text:00407783                 shr     edi, 8
.text:00407786                 and     edi, 30h        ; 12位为1,edi=0x10
.text:00407786                                         ; 12位为0,edi=0
.text:00407789                 mov     ecx, edi
.text:0040778B                 add     edi, [esi+0E0h] ; _KTHREAD->ServiceTable+edi(选择系统服务表)
.text:00407791                 mov     ebx, eax
.text:00407793                 and     eax, 0FFFh      ; 取索引
.text:00407798                 cmp     eax, [edi+8]    ; ServiceLimit判断是否越界
.text:0040779B                 jnb     _KiBBTUnexpectedRange
.text:004077A1                 cmp     ecx, 10h
.text:004077A4                 jnz     short loc_4077C0 ; 跳转为Ntoskrl.exe表处理
.text:004077A4                                         ; 不跳转的话Win32k.sys表处理,这里不分析了
.text:004077A6                 mov     ecx, ds:0FFDFF018h
.text:004077AC                 xor     ebx, ebx
.text:004077AE
.text:004077AE loc_4077AE:                             ; DATA XREF: _KiTrap0E+110↓o
.text:004077AE                 or      ebx, [ecx+0F70h]
.text:004077B4                 jz      short loc_4077C0 ; _KPRCB->KeSystemCalls+1系统调用次数加一
.text:004077B6                 push    edx
.text:004077B7                 push    eax
.text:004077B8                 call    ds:_KeGdiFlushUserBatch
.text:004077BE                 pop     eax
.text:004077BF                 pop     edx
.text:004077C0
.text:004077C0 loc_4077C0:                             ; CODE XREF: _KiFastCallEntry+B4↑j
.text:004077C0                                         ; _KiFastCallEntry+C4↑j
.text:004077C0                 inc     dword ptr ds:0FFDFF638h ; _KPRCB->KeSystemCalls+1系统调用次数加一
.text:004077C6                 mov     esi, edx        ; esi=edx(三环参数)
.text:004077C8                 mov     ebx, [edi+0Ch]  ; ebx指向参数表
.text:004077CB                 xor     ecx, ecx
.text:004077CD                 mov     cl, [eax+ebx]   ; cl为参数长度(byte)
.text:004077D0                 mov     edi, [edi]      ; edi指向地址表
.text:004077D2                 mov     ebx, [edi+eax*4] ; ebx为函数地址
.text:004077D5                 sub     esp, ecx        ; 分配空间
.text:004077D7                 shr     ecx, 2          ; ecx除四,得到参数个数
.text:004077DA                 mov     edi, esp        ; edi指向栈
.text:004077DC                 cmp     esi, ds:_MmUserProbeAddress ; 判断三环参数地址是否有效
.text:004077E2                 jnb     loc_407990
.text:004077E8
.text:004077E8 loc_4077E8:                             ; CODE XREF: _KiFastCallEntry+2A4↓j
.text:004077E8                                         ; DATA XREF: _KiTrap0E+106↓o
.text:004077E8                 rep movsd               ; 向栈上写参数
.text:004077EA                 call    ebx             ; 调用函数
原文地址:https://www.cnblogs.com/harmonica11/p/14197804.html