登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 9|回复: 0

驱动开发与系统原理-动态获取索引号

[复制链接]

78

主题

-6

回帖

71

积分

网站编辑

积分
71
发表于 前天 23:17 | 显示全部楼层 |阅读模式

动态获取主要操作就是把ntdll.dll加载到驱动中,去函数地址读取汇编中的索引号

代码:

        #include<ntifs.h>
        #include<ntimage.h>
        PULONG g_PageMapMenmory = NULL;

        typedef struct _SSDTService
        {
            PULONG ServiceTableBase;      // SSDT基址
            PVOID ServiceCounterTableBase;// SSDT中服务被调用次数计数器,一般由sysenter 更新
            ULONG NumberOfService;        // 索引总数
            PVOID ParamTableBase;         // 系统服务参数表基址-系统服务参数表SSPT
        }SYSTEM_SERVICE_TABLE, * PSYSTEM_SERVICE_TABLE;

        typedef struct _SSDTable
        {
            SYSTEM_SERVICE_TABLE KernelApi;
            SYSTEM_SERVICE_TABLE GuiApi;
        }SYSTEM_DESCRIPTOR_TABLE, * PSYSTEM_DESCRIPTOR_TABLE;

        EXTERN_C PSYSTEM_DESCRIPTOR_TABLE KeServiceDescriptorTable;

        typedef NTSTATUS(NTAPI* WbOpenProcess)(//类型定义
            PHANDLE            ProcessHandle,
            ACCESS_MASK        DesiredAccess,
            POBJECT_ATTRIBUTES ObjectAttributes,
            PCLIENT_ID         ClientId
            );

        WbOpenProcess  NtOpenProcessOldFunAddress = NULL;//用来保存原来的函数

        NTSTATUS NtOpenProcess(//hook的函数
            PHANDLE            ProcessHandle,
            ACCESS_MASK        DesiredAccess,
            POBJECT_ATTRIBUTES ObjectAttributes,
            PCLIENT_ID         ClientId
        ) {
            DbgPrint("此函数已被Hook!");
            return NtOpenProcessOldFunAddress(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
        }


        ULONG GetSSDTIndex(UNICODE_STRING usDLLFileName, PCHAR pFunctionName) {//获取SSDT中的Index
            NTSTATUS ntStatus = STATUS_SUCCESS;
            //打开dll的句柄
            HANDLE hFile = NULL;
            //节句柄
            HANDLE hSection = NULL;
            //对象属性
            OBJECT_ATTRIBUTES objectAttributes = { 0 };
            //状态块
            IO_STATUS_BLOCK ioStatus = { 0 };
            //在映射后的dll基址
            PVOID pBaseAddress = NULL;
            ULONG viewSize = 0;
            //用来保存索引
            ULONG ulFunctionIndex = 0;
            //初始化对象
            InitializeObjectAttributes(&objectAttributes, &usDLLFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
            ntStatus = ZwOpenFile(&hFile, GENERIC_READ, &objectAttributes, &ioStatus, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
            if (!NT_SUCCESS(ntStatus))
            {
                DbgPrint("ZwOpenFile Error!");
                return 0;
            }
            //初始化节对象
            ntStatus = ZwCreateSection(&hSection, SECTION_MAP_READ | SECTION_MAP_WRITE, NULL, 0, PAGE_READWRITE, 0x1000000, hFile);
            if (!NT_SUCCESS(ntStatus))
            {  
                ZwClose(hFile);
                DbgPrint("ZwCreateSection Error!");
                return 0;
            }
            //创建一个节对象, 以 PE 结构中的 SectionALignment 大小对齐映射文件
            ntStatus = ZwMapViewOfSection(hSection, NtCurrentProcess(), &pBaseAddress, 0, 1024, 0, &viewSize, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE);
            if (!NT_SUCCESS(ntStatus))
            {
                 ZwClose(hFile);
                 ZwClose(hSection);
                DbgPrint("ZwCreateSection Error!");
                return 0;
            }    
              // Dos Header
            PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;       
              // NT Header
            PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)pDosHeader + pDosHeader->e_lfanew);
            //导出表地址
            PIMAGE_EXPORT_DIRECTORY pExportable = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)pDosHeader + pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress);
            //获得有名字的函数的个数
            ULONG nlNumberForNames = pExportable->NumberOfNames;
            //获得函数地址表的地址
            PULONG lpNameAddress = (PULONG)((PUCHAR)pDosHeader + pExportable->AddressOfNames);
            PCHAR lpFuncName = NULL;
            for (ULONG i = 0; i < nlNumberForNames; i++)
            {
                lpFuncName = (PCHAR)((PUCHAR)pDosHeader + lpNameAddress[i]);
                // 判断是否查找的函数
                if (0 == _strnicmp(pFunctionName, lpFuncName, strlen(pFunctionName)))
                {
                    // 获取导出函数地址
                    USHORT uHint = *(USHORT*)((PUCHAR)pDosHeader + pExportable->AddressOfNameOrdinals + 2 * i);
                    ULONG ulFuncAddr = *(PULONG)((PUCHAR)pDosHeader + pExportable->AddressOfFunctions + 4 * uHint);
                    PVOID lpFuncAddr = (PVOID)((PUCHAR)pDosHeader + ulFuncAddr);
                    // 获取 SSDT 函数 Index
                    ulFunctionIndex = *(ULONG*)((PUCHAR)lpFuncAddr + 1);
                    break;
                }
            }
            ZwClose(hSection);
            ZwClose(hFile);
            return ulFunctionIndex;
        }

        NTSTATUS SetHook(ULONG ulFunAddr, PCHAR pFunctionName) {
            ULONG ulFunctionIndex = 0;
            NTSTATUS status = STATUS_SUCCESS;
            UNICODE_STRING usDllFileName;
            RtlInitUnicodeString(&usDllFileName, L"\\??\\C:\\Windows\\System32\\ntdll.dll");
            //获得ssdt中的index
            ulFunctionIndex = GetSSDTIndex(usDllFileName, pFunctionName);
            if (ulFunctionIndex == 0)
            {
                DbgPrint("GetSSDTIndex Error!");
                return status;
            }
            //打印出index
            DbgPrint("0x%X", ulFunctionIndex);
            //内存映射文件-SSDT表
            PHYSICAL_ADDRESS pHyAddress = MmGetPhysicalAddress(KeServiceDescriptorTable->KernelApi.ServiceTableBase);
            g_PageMapMenmory = MmMapIoSpace(pHyAddress, PAGE_SIZE, MmCached);
            //保存原来的函数地址
            NtOpenProcessOldFunAddress = g_PageMapMenmory[ulFunctionIndex];
            //将索引的地址改为我们HOOK的函数
            g_PageMapMenmory[ulFunctionIndex] = ulFunAddr;
            return status;
        }

        NTSTATUS UnHook(ULONG ulFunAddr, PCHAR pFunctionName) {
            ULONG ulFunctionIndex = 0;
            NTSTATUS status = STATUS_SUCCESS;
            UNICODE_STRING usDllFileName;
            RtlInitUnicodeString(&usDllFileName, L"\\??\\C:\\Windows\\System32\\ntdll.dll");
            ////获得ssdt中的index
            ulFunctionIndex = GetSSDTIndex(usDllFileName, pFunctionName);
            if (ulFunctionIndex == 0)
            {
                DbgPrint("GetSSDTIndex Error!");
                return status;
            }
            DbgPrint("0x%X", ulFunctionIndex);
            //内存映射文件-SSDT表
            PHYSICAL_ADDRESS pHyAddress = MmGetPhysicalAddress(KeServiceDescriptorTable->KernelApi.ServiceTableBase);
            g_PageMapMenmory = MmMapIoSpace(pHyAddress, PAGE_SIZE, MmCached);
            //将索引的地址改为我们保存的地址
            g_PageMapMenmory[ulFunctionIndex] = ulFunAddr;
            return status;
        }
        VOID DriverUnload(PDRIVER_OBJECT pDriverObject) {
            //解除hook   
            UnHook((ULONG)NtOpenProcessOldFunAddress, "NtOpenProcess");
            MmUnmapIoSpace(g_PageMapMenmory, PAGE_SIZE);
            DbgPrint("Driver UnLoad Success!");
        }
        NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) {
            DbgPrint("Driver Load Success!");
            //进行hook
            SetHook((ULONG)NtOpenProcess, "NtOpenProcess");
            //卸载函数
            pDriverObject->DriverUnload = DriverUnload;
            return STATUS_SUCCESS;
        }

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-4-5 04:13 , Processed in 0.164456 second(s), 25 queries , Yac On.

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表