两种方法获取shadow ssdt

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;

}

 

你可能感兴趣的:(sha)