- ULONG
- GetShadowSsdtCurrentAddresses(
- PSSDT_ADDRESS AddressInfo,
- PULONG Length
- )
- {
- PSYSTEM_SERVICE_TABLE KeServiceDescriptorTableShadow = NULL;
- ULONG NumberOfService = 0;
- ULONG ServiceId = 0;
- PKAPC_STATE ApcState;
- ULONG i;
- if (AddressInfo == NULL || Length == NULL)
- {
- KdPrint(("[GetShadowSsdtCurrentAddresses] 输入参数无效"));
- return 0;
- }
- //KdPrint(("pid = %d", PsGetCurrentProcessId()));
- ServiceId = (ULONG)PsGetCurrentProcessId();
- if (!g_CsrssProcess) {
- PsLookupProcessByProcessId((PVOID)ScPsGetCsrssProcessId(), &g_CsrssProcess);
- }
- KeServiceDescriptorTableShadow = GetKeServiceDescriptorTableShadow();
- if (KeServiceDescriptorTableShadow == NULL)
- {
- KdPrint(("[GetShadowSsdtCurrentAddresses] GetKeServiceDescriptorTableShadow failed"));
- return 0;
- }
- NumberOfService = KeServiceDescriptorTableShadow->NumberOfService;
- if (Length[0] < NumberOfService * sizeof(SSDT_ADDRESS))
- {
- Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);
- return 0;
- }
- ApcState = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC_STATE), MEM_TAG);
- KeStackAttachProcess((PRKPROCESS)g_CsrssProcess, ApcState);
- for (ServiceId = 0; ServiceId < NumberOfService; ServiceId ++)
- {
- AddressInfo[ServiceId].FunAddress = (ULONG)
- KeServiceDescriptorTableShadow->ServiceTableBase[ServiceId];
- AddressInfo[ServiceId].nIndex = ServiceId;
- }
- KeUnstackDetachProcess(ApcState);
- ExFreePool(ApcState);
- Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);
- return NumberOfService;
- }
- ///
- //
- // 功能实现:枚举当前Shadow SSDT 表函数地址
- // 输入参数:void
- // 输出参数:返回Shadow ssdt table
- //
- ///
- PSYSTEM_SERVICE_TABLE
- GetKeServiceDescriptorTableShadow(VOID)
- {
- PSYSTEM_SERVICE_TABLE ShadowTable = NULL;
- ULONG ServiceTableAddress = 0;
- PUCHAR cPtr = NULL;
- for (cPtr = (PUCHAR)KeAddSystemServiceTable;
- cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
- cPtr += 1 )
- {
- if (!MmIsAddressValid(cPtr)) continue;
- ServiceTableAddress = *(PULONG)cPtr;
- if (!MmIsAddressValid((PVOID)ServiceTableAddress)) continue;
- if (memcmp((PVOID)ServiceTableAddress, &KeServiceDescriptorTable, 16) == 0)
- {
- if ((PVOID)ServiceTableAddress == &KeServiceDescriptorTable) continue;
- ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;
- ShadowTable ++;
- return ShadowTable;
- }
- }
- return NULL;
- }
- //
- // 方法2,通过硬编码实现,不通用
- //
- PSYSTEM_SERVICE_TABLE
- GetKeServiceDescriptorTableShadow_2(VOID)
- /*++
- KeAddSystemServiceTable函数
- 805ba5a3 8d8840a65580 lea ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax]
- 805ba5a9 833900 cmp dword ptr [ecx],0
- --*/
- {
- PSYSTEM_SERVICE_TABLE ShadowTable;
- ULONG ServiceTableAddress;
- PUCHAR cPtr, pOpcode;
- ULONG Length = 0;
- for (cPtr = (PUCHAR)KeAddSystemServiceTable;
- cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
- cPtr += Length )
- {
- if (!MmIsAddressValid(cPtr)) return NULL;
- Length = SizeOfCode(cPtr, &pOpcode);
- if (!Length || (Length == 1 && *pOpcode == 0xC3)) return NULL;
- if (*(PUSHORT)pOpcode == 0x888D)
- {
- ServiceTableAddress = *(PULONG)(pOpcode + 2);
- ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;
- ShadowTable ++;
- return ShadowTable;
- }
- }
- return NULL;
- }
![](https://i-blog.csdnimg.cn/blog_migrate/12f26ce483426467f559536d2f03fea5.jpeg)
ULONG GetShadowSsdtCurrentAddresses( PSSDT_ADDRESS AddressInfo, PULONG Length ) { PSYSTEM_SERVICE_TABLE KeServiceDescriptorTableShadow = NULL; ULONG NumberOfService = 0; ULONG ServiceId = 0; PKAPC_STATE ApcState; ULONG i; if (AddressInfo == NULL || Length == NULL) { KdPrint(("[GetShadowSsdtCurrentAddresses] 输入参数无效")); return 0; } //KdPrint(("pid = %d", PsGetCurrentProcessId())); ServiceId = (ULONG)PsGetCurrentProcessId(); if (!g_CsrssProcess) { PsLookupProcessByProcessId((PVOID)ScPsGetCsrssProcessId(), &g_CsrssProcess); } KeServiceDescriptorTableShadow = GetKeServiceDescriptorTableShadow(); if (KeServiceDescriptorTableShadow == NULL) { KdPrint(("[GetShadowSsdtCurrentAddresses] GetKeServiceDescriptorTableShadow failed")); return 0; } NumberOfService = KeServiceDescriptorTableShadow->NumberOfService; if (Length[0] < NumberOfService * sizeof(SSDT_ADDRESS)) { Length[0] = NumberOfService * sizeof(SSDT_ADDRESS); return 0; } ApcState = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC_STATE), MEM_TAG); KeStackAttachProcess((PRKPROCESS)g_CsrssProcess, ApcState); for (ServiceId = 0; ServiceId < NumberOfService; ServiceId ++) { AddressInfo[ServiceId].FunAddress = (ULONG) KeServiceDescriptorTableShadow->ServiceTableBase[ServiceId]; AddressInfo[ServiceId].nIndex = ServiceId; } KeUnstackDetachProcess(ApcState); ExFreePool(ApcState); Length[0] = NumberOfService * sizeof(SSDT_ADDRESS); return NumberOfService; } /// // // 功能实现:枚举当前Shadow SSDT 表函数地址 // 输入参数:void // 输出参数:返回Shadow ssdt table // /// PSYSTEM_SERVICE_TABLE GetKeServiceDescriptorTableShadow(VOID) { PSYSTEM_SERVICE_TABLE ShadowTable = NULL; ULONG ServiceTableAddress = 0; PUCHAR cPtr = NULL; for (cPtr = (PUCHAR)KeAddSystemServiceTable; cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE; cPtr += 1 ) { if (!MmIsAddressValid(cPtr)) continue; ServiceTableAddress = *(PULONG)cPtr; if (!MmIsAddressValid((PVOID)ServiceTableAddress)) continue; if (memcmp((PVOID)ServiceTableAddress, &KeServiceDescriptorTable, 16) == 0) { if ((PVOID)ServiceTableAddress == &KeServiceDescriptorTable) continue; ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress; ShadowTable ++; return ShadowTable; } } return NULL; } // // 方法2,通过硬编码实现,不通用 // PSYSTEM_SERVICE_TABLE GetKeServiceDescriptorTableShadow_2(VOID) /*++ 805ba5a3 8d8840a65580 lea ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax] 805ba5a9 833900 cmp dword ptr [ecx],0 --*/ { PSYSTEM_SERVICE_TABLE ShadowTable; ULONG ServiceTableAddress; PUCHAR cPtr, pOpcode; ULONG Length = 0; for (cPtr = (PUCHAR)KeAddSystemServiceTable; cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE; cPtr += Length ) { if (!MmIsAddressValid(cPtr)) return NULL; Length = SizeOfCode(cPtr, &pOpcode); if (!Length || (Length == 1 && *pOpcode == 0xC3)) return NULL; if (*(PUSHORT)pOpcode == 0x888D) { ServiceTableAddress = *(PULONG)(pOpcode + 2); ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress; ShadowTable ++; return ShadowTable; } } return NULL; }