• 强制读写进程的内存


    某些时候我们需要读写别的进程的内存,某些时候别的进程已经对自己的内存读写做了保护,这里说四个思路(两个R3的,两个R0的)。

     方案1(R3):直接修改别人内存

    最基本的也最简单的就是直接通过WriteProcessMemory 和 ReadProcessMemory对没有进行保护的程序的内存进行修改,一些单机游戏辅助什么的可能会有这种简单方式修改其他进程内存。

    方案2(R3): 注入

         通过注入的方式想办法进入宿主进程,然后修改他的内存。这里的话姿势就很多了,远程代码注入,APC注入,输入法注入,LSP注入等等。最常用最省事的估计就是输入法注入,最不常用,但是效果最好的我个人感觉是LSP注入,这个之前用过一段时间。甚至直接可以在R3层做网络劫持了。不过LSP坑多,用者慎重。

    方案3(R0):KeStackAttachProcess

        在驱动里,直接附加到宿主进程内存,然后进行内存修改,强杀进程的时候也经常用这个姿势Attack进去,然后 进程虚拟地址空间擦除 直接干进程。

    void KWriteProcessMemory(IN PEPROCESS Process, IN PVOID Address, IN UINT32 Length, IN PVOID Buffer)
    {
    PKAPC_STATE pKs = (PKAPC_STATE)ExAllocatePool(NonPagedPool, sizeof(PKAPC_STATE));
    KeStackAttachProcess(Process, pKs);//Attach进程虚拟空间
    if (MmIsAddressValid(Address))
    {
    RtlCopyMemory(Address, Buffer, Length);
    DbgPrint("[x64Drv] Date wrote.");
    }
    KeUnstackDetachProcess(pKs);
    }

    方案4(R0):加强版方案3(也叫CR3大法,因为是操作了CR3)

      可以理解成是反汇编了方案3的代码后,直接自己实现了方案3。不过这个设计到不同系统的结构不同问题,用的时候注意确定每个系统的相关数据结构偏移:

    以下代码是Win7 64

    #define DIRECTORY_TABLE_BASE    0x028
     
    UINT32 idTarget=0;
    PEPROCESS epTarget=NULL;
    UINT32 idGame=0;
    PEPROCESS epGame=NULL;
    UINT32 rw_len=0;
    UINT64 base_addr=0;
     
     
    ULONG64 Get64bitValue(PVOID p)
    {
    if(MmIsAddressValid(p)==FALSE) 
    return 0;
    return *(PULONG64)p;
    }
     
    ULONG32 Get32bitValue(PVOID p)
    {
    if(MmIsAddressValid(p)==FALSE) 
    return 0;
    return *(PULONG32)p;
    }
     
     
    void KReadProcessMemory(IN PEPROCESS Process, IN PVOID Address, IN UINT32 Length, OUT PVOID Buffer)
    {
    ULONG64 pDTB=0,OldCr3=0,vAddr=0;
    //Get DTB
    pDTB=Get64bitValue((UCHAR*)Process + DIRECTORY_TABLE_BASE);
    if(pDTB==0)
    {
    DbgPrint("[x64Drv] Can not get PDT");
    return;
    }
    //Record old cr3 and set new cr3
    _disable();
    OldCr3=__readcr3();
    __writecr3(pDTB);
    _enable();
    //Read process memory
    if(MmIsAddressValid(Address))
    {
    RtlCopyMemory(Buffer,Address,Length);
    DbgPrint("[x64Drv] Date read: %ld", *(PDWORD)Buffer);
    }
    //Restore old cr3
    _disable();
    __writecr3(OldCr3);
    _enable();
    }
     
    void KWriteProcessMemory(IN PEPROCESS Process, IN PVOID Address, IN UINT32 Length, IN PVOID Buffer)
    {
    ULONG64 pDTB=0,OldCr3=0,vAddr=0;
    //Get DTB
    pDTB=Get64bitValue((UCHAR*)Process + DIRECTORY_TABLE_BASE);
    if(pDTB==0)
    {
    DbgPrint("[x64Drv] Can not get PDT");
    return;
    }
    //Record old cr3 and set new cr3
    _disable();
    OldCr3=__readcr3();
    __writecr3(pDTB);
    _enable();
    //Read process memory
    if(MmIsAddressValid(Address))
    {
    RtlCopyMemory(Address,Buffer,Length);
    DbgPrint("[x64Drv] Date wrote.");
    }
    //Restore old cr3
    _disable();
    __writecr3(OldCr3);
    _enable();
    }

    面是方案4的执行结果。

     

  • 相关阅读:
    DNS原理入门
    软件架构入门
    熵:宇宙的终极规则
    新鲜事
    加密货币的本质
    汇编语言入门教程
    HTML & CSS
    [模板] 矩阵快速幂
    [模板] 三分
    [模板] 2-SAT 问题
  • 原文地址:https://www.cnblogs.com/mayingkun/p/7764389.html
Copyright © 2020-2023  润新知