首页
社区
课程
招聘
Windows10 x64 ShadowSSDT遍历函数名
发表于: 2022-5-28 15:54 9003

Windows10 x64 ShadowSSDT遍历函数名

2022-5-28 15:54
9003

测试系统:windows10 21H2 19044
主要是通过WIN32K.sys导出的__win32kstub_Ntxxx函数来获取ShadowSSDT序号,W32pServiceTable也是直接通过导出表获取的

测试效果

用了些硬编码,请自行修改。。。
代码写的很乱,勿喷

#include <ntifs.h>
#include <ntimage.h>
 
EXTERN_C PVOID NTAPI RtlFindExportedRoutineByName(  _In_ PVOID ImageBase, _In_ PCCH RoutineName);
 
PULONG W32pServiceTable = NULL;
 
typedef struct _LDR_DATA_TABLE_ENTRY {
    LIST_ENTRY InLoadOrderModuleList;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    LIST_ENTRY HashLinks;
    PVOID SectionPointer;
    ULONG CheckSum;
    ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
 
PVOID GetSystemRoutineAddress(PCWSTR routine_name) {
    UNICODE_STRING name;
    RtlInitUnicodeString(&name, routine_name);
    return MmGetSystemRoutineAddress(&name);
}
 
PVOID GetSystemModuleBase(LPCWSTR module_name) {
    PLIST_ENTRY module_list = reinterpret_cast<PLIST_ENTRY>(GetSystemRoutineAddress(L"PsLoadedModuleList"));
    if (!module_list) {
        return NULL;
    }
    for (PLIST_ENTRY link = module_list; link != module_list->Blink; link = link->Flink) {
        LDR_DATA_TABLE_ENTRY* entry = CONTAINING_RECORD(link, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
        UNICODE_STRING name;
        RtlInitUnicodeString(&name, module_name);
        if (RtlEqualUnicodeString(&entry->BaseDllName, &name, TRUE)) {
            return entry->DllBase;
        }
    }
    return NULL;
}
 
ULONG64 GetShadowSSDTFuncCurAddr(ULONG id) {
    LONG dwtmp = 0;
    PULONG ServiceTableBase = NULL;
    ServiceTableBase = W32pServiceTable;
    dwtmp = ServiceTableBase[id];
    dwtmp = dwtmp >> 4;
    return (LONGLONG)dwtmp + (ULONGLONG)ServiceTableBase;
}
 
NTSTATUS GetPEPPocess(const char* process_name, PEPROCESS* process) {
    PEPROCESS sys_process = PsInitialSystemProcess;
    PEPROCESS curr_entry = sys_process;
    char image_name[15];
    do {
        RtlCopyMemory((PVOID)(&image_name), (PVOID)((uintptr_t)curr_entry + 0x5a8), sizeof(image_name));
        if (strstr(image_name, process_name)) {
            ULONG active_threads;
            RtlCopyMemory((PVOID)&active_threads, (PVOID)((uintptr_t)curr_entry + 0x5F0), sizeof(active_threads));
            if (active_threads) {
                *process = curr_entry;
                return STATUS_SUCCESS;
            }
        }
        PLIST_ENTRY list = (PLIST_ENTRY)((uintptr_t)(curr_entry)+0x448);
        curr_entry = (PEPROCESS)((uintptr_t)list->Flink - 0x448);
    } while (curr_entry != sys_process);
    return STATUS_NOT_FOUND;
}
 
VOID EnumShadowSSDT() {
 
    PEPROCESS winlogon = NULL;
    KAPC_STATE apc_state;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    status = GetPEPPocess(("winlogon.exe"), &winlogon);
 
    KeStackAttachProcess(winlogon, &apc_state);
 
    PVOID Win32KBase = GetSystemModuleBase(L"win32k.sys");
 
    W32pServiceTable =  (PULONG)RtlFindExportedRoutineByName(Win32KBase,"W32pServiceTable");
 
    DbgPrintEx(77, 0, "[%s] Win32k.sys = 0x%llx\n", __FUNCTION__, Win32KBase);
 
 
    DbgPrintEx(77, 0, "[%s] W32pServiceTable = 0x%llx\n", __FUNCTION__, W32pServiceTable);
 
 
    PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)Win32KBase;
 
    PIMAGE_NT_HEADERS64 lpNtHeader = (PIMAGE_NT_HEADERS64)((ULONG64)Win32KBase + lpDosHeader->e_lfanew);
 
    if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) {
        return;
    }
 
    if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) {
        return;
    }
 
    PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)((ULONG64)Win32KBase + (ULONG64)lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
 
    PULONG lpdwFunName = (PULONG)((ULONG64)Win32KBase + (ULONG64)lpExports->AddressOfNames);
 
    PUSHORT lpword = (PUSHORT)((ULONG64)Win32KBase + (ULONG64)lpExports->AddressOfNameOrdinals);
 
    PULONG lpdwFunAddr = (PULONG)((ULONG64)Win32KBase + (ULONG64)lpExports->AddressOfFunctions);
 
    for (ULONG i = 0; i <= lpExports->NumberOfNames - 1; i++) {
        char* pFunName = (char*)(lpdwFunName[i] + (ULONG64)Win32KBase);
        if(strstr(pFunName,"__win32kstub_"))
        {
            PVOID _FunctionAddress = (PVOID)(lpdwFunAddr[lpword[i]] + (ULONG64)Win32KBase);
            char* FunctionName = strstr(pFunName, "Nt");
            ULONG lFunctionIndex = *(ULONG*)((PUCHAR)_FunctionAddress + 1);
            ULONG64 FunctionAddress = GetShadowSSDTFuncCurAddr(lFunctionIndex);
            DbgPrintEx(77, 0, "[%s] \nIndex: %d \nAddress: 0x%llx \n", FunctionName, lFunctionIndex, FunctionAddress);
        }
    }
 
    KeUnstackDetachProcess(&apc_state);
}
 
 
 
VOID DriverUnload(PDRIVER_OBJECT drv_obj [[maybe_unused]] ) {
 
}
 
EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT drv_obj [[maybe_unused]], PUNICODE_STRING reg_path [[maybe_unused]] ) {
    EnumShadowSSDT();
    drv_obj->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}
#include <ntifs.h>
#include <ntimage.h>
 
EXTERN_C PVOID NTAPI RtlFindExportedRoutineByName(  _In_ PVOID ImageBase, _In_ PCCH RoutineName);
 
PULONG W32pServiceTable = NULL;
 
typedef struct _LDR_DATA_TABLE_ENTRY {
    LIST_ENTRY InLoadOrderModuleList;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    LIST_ENTRY HashLinks;
    PVOID SectionPointer;
    ULONG CheckSum;
    ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
 
PVOID GetSystemRoutineAddress(PCWSTR routine_name) {
    UNICODE_STRING name;
    RtlInitUnicodeString(&name, routine_name);
    return MmGetSystemRoutineAddress(&name);
}
 
PVOID GetSystemModuleBase(LPCWSTR module_name) {
    PLIST_ENTRY module_list = reinterpret_cast<PLIST_ENTRY>(GetSystemRoutineAddress(L"PsLoadedModuleList"));
    if (!module_list) {
        return NULL;
    }
    for (PLIST_ENTRY link = module_list; link != module_list->Blink; link = link->Flink) {
        LDR_DATA_TABLE_ENTRY* entry = CONTAINING_RECORD(link, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
        UNICODE_STRING name;
        RtlInitUnicodeString(&name, module_name);
        if (RtlEqualUnicodeString(&entry->BaseDllName, &name, TRUE)) {
            return entry->DllBase;
        }
    }
    return NULL;
}
 
ULONG64 GetShadowSSDTFuncCurAddr(ULONG id) {
    LONG dwtmp = 0;
    PULONG ServiceTableBase = NULL;
    ServiceTableBase = W32pServiceTable;
    dwtmp = ServiceTableBase[id];
    dwtmp = dwtmp >> 4;
    return (LONGLONG)dwtmp + (ULONGLONG)ServiceTableBase;
}
 
NTSTATUS GetPEPPocess(const char* process_name, PEPROCESS* process) {
    PEPROCESS sys_process = PsInitialSystemProcess;
    PEPROCESS curr_entry = sys_process;
    char image_name[15];
    do {
        RtlCopyMemory((PVOID)(&image_name), (PVOID)((uintptr_t)curr_entry + 0x5a8), sizeof(image_name));
        if (strstr(image_name, process_name)) {
            ULONG active_threads;
            RtlCopyMemory((PVOID)&active_threads, (PVOID)((uintptr_t)curr_entry + 0x5F0), sizeof(active_threads));
            if (active_threads) {
                *process = curr_entry;
                return STATUS_SUCCESS;
            }
        }

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 4
支持
分享
最新回复 (2)
雪    币: 42
活跃值: (208)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
Interupt是个好人,这种方式应该可以直接兼容WIN11
2022-8-25 14:14
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
有点吊啊很牛
2024-10-25 08:53
0
游客
登录 | 注册 方可回帖
返回
//