两种方法获取shadow ssdt

  1. ULONG   
  2. GetShadowSsdtCurrentAddresses(  
  3.     PSSDT_ADDRESS   AddressInfo,   
  4.     PULONG          Length  
  5.     )  
  6. {  
  7.     PSYSTEM_SERVICE_TABLE KeServiceDescriptorTableShadow = NULL;  
  8.     ULONG NumberOfService = 0;  
  9.     ULONG ServiceId = 0;  
  10.     PKAPC_STATE ApcState;  
  11.     ULONG i;  
  12.       
  13.     if (AddressInfo == NULL || Length == NULL)  
  14.     {  
  15.         KdPrint(("[GetShadowSsdtCurrentAddresses] 输入参数无效"));  
  16.         return 0;  
  17.     }  
  18.   
  19.     //KdPrint(("pid = %d", PsGetCurrentProcessId()));  
  20.     ServiceId = (ULONG)PsGetCurrentProcessId();  
  21.   
  22.     if (!g_CsrssProcess) {  
  23.         PsLookupProcessByProcessId((PVOID)ScPsGetCsrssProcessId(), &g_CsrssProcess);  
  24.     }  
  25.   
  26.     KeServiceDescriptorTableShadow = GetKeServiceDescriptorTableShadow();  
  27.   
  28.     if (KeServiceDescriptorTableShadow == NULL)    
  29.     {  
  30.         KdPrint(("[GetShadowSsdtCurrentAddresses] GetKeServiceDescriptorTableShadow failed"));  
  31.         return 0;  
  32.     }  
  33.   
  34.     NumberOfService = KeServiceDescriptorTableShadow->NumberOfService;  
  35.     if (Length[0] < NumberOfService * sizeof(SSDT_ADDRESS))  
  36.     {  
  37.         Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);  
  38.         return 0;  
  39.     }  
  40.   
  41.     ApcState = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC_STATE), MEM_TAG);  
  42.     KeStackAttachProcess((PRKPROCESS)g_CsrssProcess, ApcState);  
  43.   
  44.     for (ServiceId = 0; ServiceId < NumberOfService; ServiceId ++)  
  45.     {  
  46.         AddressInfo[ServiceId].FunAddress = (ULONG)  
  47.             KeServiceDescriptorTableShadow->ServiceTableBase[ServiceId];  
  48.         AddressInfo[ServiceId].nIndex = ServiceId;  
  49.     }  
  50.   
  51.     KeUnstackDetachProcess(ApcState);  
  52.     ExFreePool(ApcState);  
  53.   
  54.     Length[0] = NumberOfService * sizeof(SSDT_ADDRESS);  
  55.     return NumberOfService;  
  56. }  
  57.   
  58. ///////////////////////////////////////////////////////////////////////////////////  
  59. //  
  60. //  功能实现:枚举当前Shadow SSDT 表函数地址  
  61. //  输入参数:void  
  62. //  输出参数:返回Shadow ssdt table  
  63. //  
  64. ///////////////////////////////////////////////////////////////////////////////////  
  65. PSYSTEM_SERVICE_TABLE   
  66. GetKeServiceDescriptorTableShadow(VOID)  
  67. {  
  68.     PSYSTEM_SERVICE_TABLE ShadowTable = NULL;  
  69.     ULONG   ServiceTableAddress = 0;  
  70.     PUCHAR  cPtr = NULL;   
  71.   
  72.     for (cPtr = (PUCHAR)KeAddSystemServiceTable;  
  73.          cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;  
  74.          cPtr += 1 )  
  75.     {  
  76.         if (!MmIsAddressValid(cPtr))  continue;  
  77.   
  78.         ServiceTableAddress = *(PULONG)cPtr;  
  79.         if (!MmIsAddressValid((PVOID)ServiceTableAddress)) continue;  
  80.   
  81.         if (memcmp((PVOID)ServiceTableAddress, &KeServiceDescriptorTable, 16) == 0)  
  82.         {  
  83.             if ((PVOID)ServiceTableAddress == &KeServiceDescriptorTable) continue;  
  84.             ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;  
  85.             ShadowTable ++;  
  86.             return ShadowTable;  
  87.         }  
  88.     }  
  89.     return NULL;  
  90. }  
  91. //  
  92. // 方法2,通过硬编码实现,不通用  
  93. //   
  94. PSYSTEM_SERVICE_TABLE   
  95. GetKeServiceDescriptorTableShadow_2(VOID)  
  96. /*++ 
  97.     KeAddSystemServiceTable函数
  98.     805ba5a3 8d8840a65580    lea    ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax] 
  99.     805ba5a9 833900          cmp    dword ptr [ecx],0 
  100. --*/  
  101. {  
  102.     PSYSTEM_SERVICE_TABLE ShadowTable;  
  103.     ULONG   ServiceTableAddress;  
  104.     PUCHAR  cPtr, pOpcode;  
  105.     ULONG   Length = 0;  
  106.   
  107.     for (cPtr = (PUCHAR)KeAddSystemServiceTable;  
  108.          cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;  
  109.          cPtr += Length )  
  110.     {  
  111.         if (!MmIsAddressValid(cPtr))  return NULL;  
  112.   
  113.         Length = SizeOfCode(cPtr, &pOpcode);  
  114.   
  115.         if (!Length || (Length == 1 && *pOpcode == 0xC3)) return NULL;  
  116.   
  117.         if (*(PUSHORT)pOpcode == 0x888D)  
  118.         {  
  119.             ServiceTableAddress = *(PULONG)(pOpcode + 2);  
  120.             ShadowTable = (PSYSTEM_SERVICE_TABLE)ServiceTableAddress;  
  121.             ShadowTable ++;  
  122.             return ShadowTable;  
  123.         }  
  124.     }  
  125.     return NULL;  
  126. }  

原文地址:https://www.cnblogs.com/kuangke/p/5761555.html