C++強制讀寫進程內存 R0與R3法


某些時候我們需要讀寫別的進程的內存,某些時候別的進程已經對自己的內存讀寫做了保護,這里說四個思路(兩個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();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM