1. 程式人生 > >強制讀寫進程的內存

強制讀寫進程的內存

效果 簡單 date stat alt 附加 內存 ble color

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

技術分享

強制讀寫進程的內存