吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1395|回复: 4
收起左侧

[讨论] 驱动编程方式实现win10 64位下读写某一进程的内存数据

[复制链接]
syw6616 发表于 2024-9-17 21:19
//实现功能:为当前运行中的某一程序申请一块内存,并可进行读写。
//有什么用?如何功能扩展?请有兴趣的朋友自己探索!

#include <ntddk.h>

typedef struct _KAPC_STATE {
        LIST_ENTRY ApcListHead[MaximumMode];
        struct _KPROCESS *Process;
        union {
                UCHAR InProgressFlags;
                struct {
                        BOOLEAN KernelApcInProgress : 1;
                        BOOLEAN SpecialApcInProgress : 1;
                };
        };

        BOOLEAN KernelApcPending;
        BOOLEAN UserApcPending;
} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;

#if (NTDDI_VERSION >= NTDDI_WIN2K)
_IRQL_requires_max_(APC_LEVEL)
NTKERNELAPI
VOID
KeStackAttachProcess (
    _Inout_ PRKPROCESS PROCESS,
    _Out_ PRKAPC_STATE ApcState
    );
#endif

#if (NTDDI_VERSION >= NTDDI_WIN2K)
_IRQL_requires_max_(APC_LEVEL)
NTKERNELAPI
VOID
KeUnstackDetachProcess (
    _In_ PRKAPC_STATE ApcState
    );
#endif



NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(_In_ HANDLE ProcessId,_Outptr_ PEPROCESS *Process);


NTSTATUS
ZwAllocateVirtualMemory(
__in HANDLE  ProcessHandle,
__inout PVOID  *BaseAddress,
__in ULONG_PTR  ZeroBits,
__inout PSIZE_T  RegionSize,
__in ULONG  AllocationType,
__in ULONG  Protect
);

KIRQL Irql;
VOID WPOFF()
{
        ULONG_PTR cr0 = 0;
        Irql = KeRaiseIrqlToDpcLevel();
        cr0 = __readcr0();
        cr0 &= 0xfffffffffffeffff;
        __writecr0(cr0);
#ifdef _WIN64
        _disable();
#endif
}

VOID WPON()
{
        ULONG_PTR cr0 = __readcr0();
        cr0 |= 0x10000;
#ifdef _WIN64
        _enable();
#endif
        __writecr0(cr0);
        KeLowerIrql(Irql);
}



NTSTATUS ReadWriteProcess()
{
        NTSTATUS Status;
        HANDLE  hProcess;
        CLIENT_ID ClientId;
        PVOID AllocateAddress;
        size_t ReginSize;
        OBJECT_ATTRIBUTES ObjAttr;
        PEPROCESS Process = NULL;

        ClientId.UniqueProcess = (HANDLE)9544;      //进程句柄,可从任务管理器中取得
        ClientId.UniqueThread = 0;
        AllocateAddress = 0; //不赋值 会C000018错误
        memset(&ObjAttr, 0, sizeof(OBJECT_ATTRIBUTES));

        PsLookupProcessByProcessId((HANDLE)ClientId.UniqueProcess, &Process);


        Status = ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &ObjAttr, &ClientId);

        if (!NT_SUCCESS(Status))
        {
                DbgPrint("ZwOpenProcess Error -- %#X", Status);
                ZwClose(hProcess);
                return Status;
        }

        DbgPrint("ZwOpenProcess Success");


        ReginSize = 0xff;
        Status = ZwAllocateVirtualMemory(hProcess, &AllocateAddress, 0, &ReginSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

        if (!NT_SUCCESS(Status))
        {
                DbgPrint("ZwAllocateVirtualMemory Error -- %#X", Status);
                ZwClose(hProcess);
                return Status;
        }

       
        /*要依附所在进程,才可以更改对应内存中的值*/
        //--------------------------------------------------------
        KAPC_STATE kApc;
        KeStackAttachProcess((PRKPROCESS)Process, &kApc);
        //--------------------------------------------------------

       
        (DWORD32)(*(PVOID*)AllocateAddress) = 0xABCD;   //写入内存
       
        //---------------------       
//        (DWORD32)(*((PVOID*)AllocateAddress+4)) = 0xDCBA;   //写入内存------------------------------------
           KeUnstackDetachProcess(&kApc);
        //////////////////////////////////////////////////////////

        DbgPrint("address: %p - %p -size:- %d", &AllocateAddress, AllocateAddress, ReginSize);
       

        //        WPON();

//        DbgPrint("%p\n",*(PVOID*)AllocateAddress);

//        WPOFF();

        ZwClose(hProcess);
        return Status;
}

HANDLE DriverAllocMem(HANDLE ProcessId, ULONG RegionSize)
{

        NTSTATUS status;
        PEPROCESS Process;
        HANDLE BaseAddr = NULL;
        KAPC_STATE ApcState;


        status = PsLookupProcessByProcessId(ProcessId, &Process);

        if (NT_SUCCESS(status))
        {

                KeStackAttachProcess((PKPROCESS)Process, &ApcState);
                _try
                {

                        ZwAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&BaseAddr, 0, (PSIZE_T)&RegionSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
                        MmProtectMdlSystemAddress(BaseAddr, PAGE_EXECUTE_READWRITE);
                        RtlZeroMemory(BaseAddr, RegionSize); //关键点
                        //这里是关键点,内存清理后,然后ring0下再调用 VirtualProtectEx() 修改内存属性,这样申请到的内存,用之前的代码,就莫名其妙的就可以访问了
                        //原因我不懂,之前因为申请到的内存,不能访问,我就用CE查看内存,然后发现用CE访问过后的内存就可以驱动读写了
                        //后来我就胡乱测试,发现这个方法可以,ring0申请内存,然后清零,然后ring3修改内存属性,就可以访问
                        KeUnstackDetachProcess(&ApcState);
                }
                __except (EXCEPTION_EXECUTE_HANDLER)
                {
                        KeUnstackDetachProcess(&ApcState);
                        return 0;
                }

        }

        return BaseAddr;
}












VOID MyUnload(PDRIVER_OBJECT pDriverObject)
{
        DbgPrint("GoodBye World!");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegisterPath)
{
        pDriverObject->DriverUnload = MyUnload;

        DbgPrint("Hello World");

        ReadWriteProcess();

        return STATUS_SUCCESS;
}


//可用CheatEngine 软件工具打开对应进程句柄号的程序,查看相应内容地址的属性和内容

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Panel 发表于 2024-9-17 21:26
你不如直接替换cr3寄存器
[C++] 纯文本查看 复制代码
#include <intrin.h>
#include <ntifs.h>

VOID  UnloadDriver(PDRIVER_OBJECT pDriver)
{}

typedef struct _PROCESS_DATA_
{
        CHAR ignore[0x28];
        ULONGLONG DirectoryTableBase;
}PROCESS_DATA,*PPROCESS_DATA;

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegpath)
{

        pDriver->DriverUnload = UnloadDriver;

        NTSTATUS status = STATUS_SUCCESS;
        PEPROCESS pEprocess = NULL;
        ULONG oldcr3;

        status = PsLookupProcessByProcessId(5420,&pEprocess);

        if (!NT_SUCCESS(status))
        {
                return STATUS_UNSUCCESSFUL;
        }

        ObDereferenceObject(pEprocess);

        PPROCESS_DATA pdata = pEprocess;

        _disable();

        oldcr3 = __readcr3();

        __writecr3(pdata->DirectoryTableBase);
        
        CHAR buffer[10] = { 0 };

        __try {

                ProbeForRead(0xf20020,10,1);

                RtlCopyMemory(buffer, 0xf20020, 10);

                for (size_t i = 0; i < 10; i++)
                {
                        DbgPrintEx(77, 0, "[db]%2x ", buffer[i]);
                }

                DbgPrintEx(77, 0, "\n");
        }
        __except(1){
                
        }


        __writecr3(oldcr3);

        _enable();


        return STATUS_SUCCESS;
}
 楼主| syw6616 发表于 2024-9-17 22:46
szluyang 发表于 2024-9-18 12:54
CGPZ 发表于 2024-9-18 18:12
那个啥,这个驱动编程写的是到底是驱动文件(配置文件inf),还是里面的驱动文件内容
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 11:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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