125096 发表于 2019-3-7 15:11:15

分享一个在最新WIN10获取KeServiceDescriptorTable的方法

原来我们64位搜索KeServiceDescriptorTable是通过msr的0xc0000082获得KiSystemCall64字段, 但是现在msr变成了KiSystemCall64Shadow函数, 而且这个函数无法直接搜索到KeServiceDescriptorTable
ULONGLONG SearchforKeServiceDescriptorTable64(ULONGLONG StartSearchAddress, ULONGLONG EndSearchAddress)
{
    UCHAR b1 = 0, b2 = 0, b3 = 0;
    ULONG templong = 0;
    ULONGLONG KeServiceDescriptorTable = 0;

    //地址效验
    if (MmIsAddressValid(StartSearchAddress) == FALSE)return NULL;
    if (MmIsAddressValid(EndSearchAddress) == FALSE)return NULL;

    for (PUCHAR i = StartSearchAddress; i < EndSearchAddress; i++)
    {
      if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2))
      {
            b1 = *i;
            b2 = *(i + 1);
            b3 = *(i + 2);
            if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15)//4c8d15
            {
                memcpy(&templong, i + 3, 4);
                KeServiceDescriptorTable = (ULONGLONG)templong + (ULONGLONG)i + 7;
                return KeServiceDescriptorTable;
                //当前地址 + 长度 + 数值
                //fffff800`03c8c772+7 + 002320c7 = FFFFF80003EBE840
                /*
                fffff800`03c8c772 4c8d15c7202300lea   r10,
                fffff800`03c8c779 4c8d1d00212300lea   r11,
                */
            }
      }
    }
    return NULL;
}

//获取SSDT KeServiceDescriptorTable
ULONGLONG GetKeServiceDescriptorTable64()
{
    PUCHAR pKiSystemCall64 = (PUCHAR)__readmsr(0xc0000082);//rdmsr c0000082   //定位KiSystemCall64
    PUCHAR EndSearchAddress = pKiSystemCall64 + 0x500;
    ULONGLONG KeServiceDescriptorTable = 0;

   
    KeServiceDescriptorTable=SearchforKeServiceDescriptorTable64(pKiSystemCall64, EndSearchAddress);
    if (KeServiceDescriptorTable)returnKeServiceDescriptorTable;

    //msr变成了KiSystemCall64Shadow函数
    //原来我们64位搜索KeServiceDescriptorTable是通过msr的0xc0000082获得KiSystemCall64字段, 但是现在msr变成了KiSystemCall64Shadow函数, 而且这个函数无法直接搜索到KeServiceDescriptorTable。
    ULONGLONG KiSystemServiceUser = 0;
    ULONGLONG templong = 0xffffffffffffffff;
    for (PUCHAR i = pKiSystemCall64; i < EndSearchAddress + 0xff; i++)
    {
      if (*(PUCHAR)i == 0xe9 && *(PUCHAR)(i + 5) == 0xc3)
      {
            //fffff803`23733383 e9631ae9ff      jmp   nt!KiSystemServiceUser(fffff803`235c4deb)
            //fffff803`23733388 c3            ret
            RtlCopyMemory(&templong, (PUCHAR)(i + 1), 4);
            KiSystemServiceUser = templong + 5 + i;//KiSystemServiceUser
            EndSearchAddress= KiSystemServiceUser +0x500;
            KeServiceDescriptorTable = SearchforKeServiceDescriptorTable64(KiSystemServiceUser, EndSearchAddress);
            return KeServiceDescriptorTable;
      }
    }
    return 0;
}

tangptr@126.com 发表于 2019-3-8 00:53:59

我差点就信了你的鬼,你这糟老头子坏得很。

85251201 发表于 2022-2-8 13:39:07

tangptr@126.com 发表于 2019-3-8 00:53
我差点就信了你的鬼,你这糟老头子坏得很。

意思是 他不是这样的?
页: [1]
查看完整版本: 分享一个在最新WIN10获取KeServiceDescriptorTable的方法