驅動開發:內核讀寫內存多級偏移 世界今熱點
(資料圖)
讓我們繼續在《內核讀寫內存浮點數》的基礎之上做一個簡單的延申,如何實現多級偏移讀寫,其實很簡單,讀寫函數無需改變,只是在讀寫之前提前做好計算工作,以此來得到一個內存偏移值,并通過調用內存寫入原函數實現寫出數據的目的。
以讀取偏移內存為例,如下代碼同樣來源于本人的LyMemory讀寫驅動項目,其中核心函數為WIN10_ReadDeviationIntMemory()該函數的主要作用是通過用戶傳入的基地址與偏移值,動態計算出當前的動態地址。
函數首先將基地址指向要讀取的變量,并將其轉換為LPCVOID類型的指針。然后將指向變量值的緩沖區轉換為LPVOID類型的指針。接下來,函數使用PsLookupProcessByProcessId函數查找目標進程并返回其PEPROCESS結構體。隨后,函數從偏移地址數組的最后一個元素開始迭代,每次循環都從目標進程中讀取4字節整數型數據,并將其存儲在Value變量中。然后,函數將基地址指向Value和偏移地址的和,以便在下一次循環中讀取更深層次的變量。最后,函數將基地址指向最終變量的地址,讀取變量的值,并返回。
如下案例所示,用戶傳入進程基址以及offset偏移值時,只需要動態計算出該偏移地址,并與基址相加即可得到動態地址。
#include #include #include // 普通Ke內存讀取NTSTATUS KeReadProcessMemory(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size){PEPROCESS SourceProcess = Process;PEPROCESS TargetProcess = PsGetCurrentProcess();SIZE_T Result;if (NT_SUCCESS(MmCopyVirtualMemory(SourceProcess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, &Result)))return STATUS_SUCCESS;elsereturn STATUS_ACCESS_DENIED;}// 讀取整數內存多級偏移/* Pid: 目標進程的進程ID。 Base: 變量的基地址。 offset: 相對基地址的多級偏移地址,用于定位變量。 len: 偏移地址的數量。*/INT64 WIN10_ReadDeviationIntMemory(HANDLE Pid, LONG Base, DWORD offset[32], DWORD len){INT64 Value = 0;LPCVOID pbase = (LPCVOID)Base;LPVOID rbuffer = (LPVOID)&Value;PEPROCESS Process;PsLookupProcessByProcessId((HANDLE)Pid, &Process);for (int x = len - 1; x >= 0; x--){__try{KeReadProcessMemory(Process, pbase, rbuffer, 4);pbase = (LPCVOID)(Value + offset[x]);}__except (EXCEPTION_EXECUTE_HANDLER){return 0;}}__try{DbgPrint("讀取基址:%x \n", pbase);KeReadProcessMemory(Process, pbase, rbuffer, 4);}__except (EXCEPTION_EXECUTE_HANDLER){return 0;}return Value;}// 驅動卸載例程VOID UnDriver(PDRIVER_OBJECT driver){DbgPrint("Uninstall Driver \n");}// 驅動入口地址NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){DbgPrint("Hello LyShark \n");DWORD PID = 4884;LONG PBase = 0x6566e0;LONG Size = 4;DWORD Offset[32] = { 0 };Offset[0] = 0x18;Offset[1] = 0x0;Offset[2] = 0x14;Offset[3] = 0x0c;// 讀取內存數據INT64 read = WIN10_ReadDeviationIntMemory(PID, PBase, Offset, Size);DbgPrint("PID: %d 基址: %p 偏移長度: %d \n", PID, PBase, Size);DbgPrint("[+] 1級偏移: %x \n", Offset[0]);DbgPrint("[+] 2級偏移: %x \n", Offset[1]);DbgPrint("[+] 3級偏移: %x \n", Offset[2]);DbgPrint("[+] 4級偏移: %x \n", Offset[3]);DbgPrint("[ReadMemory] 讀取偏移數據: %d \n", read);Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;} 編譯并運行如上這段代碼,則可獲取到PID=4884的PBase的動態地址中的數據,如下圖所示;
至于如何將數據寫出四級偏移的基址上面,則只需要取出pbase里面的基址,并通過原函數WIN10_WriteProcessMemory直接寫出數據即可,此出的原函數在《內核MDL讀寫進程內存》中已經做了詳細介紹,實現寫出代碼如下所示;
#include #include #include // 普通Ke內存讀取NTSTATUS KeReadProcessMemory(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size){PEPROCESS SourceProcess = Process;PEPROCESS TargetProcess = PsGetCurrentProcess();SIZE_T Result;if (NT_SUCCESS(MmCopyVirtualMemory(SourceProcess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, &Result)))return STATUS_SUCCESS;elsereturn STATUS_ACCESS_DENIED;}// Win10 內存寫入函數BOOLEAN WIN10_WriteProcessMemory(HANDLE Pid, PVOID Address, SIZE_T BYTE_size, PVOID VirtualAddress){PVOID buff1;VOID *buff2;int MemoryNumerical = 0;KAPC_STATE KAPC = { 0 };PEPROCESS Process;PsLookupProcessByProcessId((HANDLE)Pid, &Process);__try{//分配內存buff1 = ExAllocatePoolWithTag((POOL_TYPE)0, BYTE_size, 1997);buff2 = buff1;*(int*)buff1 = 1;if (MmIsAddressValid((PVOID)VirtualAddress)){// 復制內存memcpy(buff2, VirtualAddress, BYTE_size);}else{return FALSE;}// 附加到要讀寫的進程KeStackAttachProcess((PRKPROCESS)Process, &KAPC);if (MmIsAddressValid((PVOID)Address)){// 判斷地址是否可寫ProbeForWrite(Address, BYTE_size, 1);// 復制內存memcpy(Address, buff2, BYTE_size);}else{return FALSE;}// 剝離附加的進程KeUnstackDetachProcess(&KAPC);ExFreePoolWithTag(buff2, 1997);}__except (EXCEPTION_EXECUTE_HANDLER){return FALSE;}return FALSE;}// 寫入整數內存多級偏移INT64 WIN10_WriteDeviationIntMemory(HANDLE Pid, LONG Base, DWORD offset[32], DWORD len, INT64 SetValue){INT64 Value = 0;LPCVOID pbase = (LPCVOID)Base;LPVOID rbuffer = (LPVOID)&Value;PEPROCESS Process;PsLookupProcessByProcessId((HANDLE)Pid, &Process);for (int x = len - 1; x >= 0; x--){__try{KeReadProcessMemory(Process, pbase, rbuffer, 4);pbase = (LPCVOID)(Value + offset[x]);}__except (EXCEPTION_EXECUTE_HANDLER){return 0;}}__try{KeReadProcessMemory(Process, pbase, rbuffer, 4);}__except (EXCEPTION_EXECUTE_HANDLER){return 0;}// 使用原函數寫入BOOLEAN ref = WIN10_WriteProcessMemory(Pid, (void *)pbase, 4, &SetValue);if (ref == TRUE){DbgPrint("[內核寫成功] # 寫入地址: %x \n", pbase);return 1;}return 0;}// 驅動卸載例程VOID UnDriver(PDRIVER_OBJECT driver){DbgPrint("Uninstall Driver \n");}// 驅動入口地址NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){DbgPrint("Hello LyShark \n");DWORD PID = 4884;LONG PBase = 0x6566e0;LONG Size = 4;INT64 SetValue = 100;DWORD Offset[32] = { 0 };Offset[0] = 0x18;Offset[1] = 0x0;Offset[2] = 0x14;Offset[3] = 0x0c;// 寫出內存數據INT64 write = WIN10_WriteDeviationIntMemory(PID, PBase, Offset, Size, SetValue);DbgPrint("PID: %d 基址: %p 偏移長度: %d \n", PID, PBase, Size);DbgPrint("[+] 1級偏移: %x \n", Offset[0]);DbgPrint("[+] 2級偏移: %x \n", Offset[1]);DbgPrint("[+] 3級偏移: %x \n", Offset[2]);DbgPrint("[+] 4級偏移: %x \n", Offset[3]);DbgPrint("[WriteMemory] 寫出偏移數據: %d \n", SetValue);Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;} 運行如上代碼將在0x6566e0所在的基址上,將數據替換為100,實現效果圖如下所示;
那么如何實現讀寫內存浮點數,字節集等多級偏移呢?
其實我們可以封裝一個WIN10_ReadDeviationMemory函數,讓其只計算得出偏移地址,而所需要寫出的類型則根據自己的實際需求配合不同的寫入函數完成,也就是將兩者分離開,如下則是一段實現計算偏移的代碼片段,該代碼同樣來自于本人的LyMemory驅動讀寫項目;
#include #include #include // 普通Ke內存讀取NTSTATUS KeReadProcessMemory(PEPROCESS Process, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size){PEPROCESS SourceProcess = Process;PEPROCESS TargetProcess = PsGetCurrentProcess();SIZE_T Result;if (NT_SUCCESS(MmCopyVirtualMemory(SourceProcess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, &Result)))return STATUS_SUCCESS;elsereturn STATUS_ACCESS_DENIED;}// 讀取多級偏移內存動態地址DWORD64 WIN10_ReadDeviationMemory(HANDLE Pid, LONG Base, DWORD offset[32], DWORD len){INT64 Value = 0;LPCVOID pbase = (LPCVOID)Base;LPVOID rbuffer = (LPVOID)&Value;PEPROCESS Process;PsLookupProcessByProcessId((HANDLE)Pid, &Process);for (int x = len - 1; x >= 0; x--){__try{KeReadProcessMemory(Process, pbase, rbuffer, 4);pbase = (LPCVOID)(Value + offset[x]);}__except (EXCEPTION_EXECUTE_HANDLER){return 0;}}return pbase;}// 驅動卸載例程VOID UnDriver(PDRIVER_OBJECT driver){DbgPrint("Uninstall Driver \n");}// 驅動入口地址NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath){DbgPrint("Hello LyShark \n");DWORD PID = 4884;LONG PBase = 0x6566e0;LONG Size = 4;DWORD Offset[32] = { 0 };Offset[0] = 0x18;Offset[1] = 0x0;Offset[2] = 0x14;Offset[3] = 0x0c;// 寫出內存數據DWORD64 offsets = WIN10_ReadDeviationMemory(PID, PBase, Offset, Size);DbgPrint("PID: %d 基址: %p 偏移長度: %d \n", PID, PBase, Size);DbgPrint("[+] 1級偏移: %x \n", Offset[0]);DbgPrint("[+] 2級偏移: %x \n", Offset[1]);DbgPrint("[+] 3級偏移: %x \n", Offset[2]);DbgPrint("[+] 4級偏移: %x \n", Offset[3]);DbgPrint("[CheckMemory] 計算偏移地址: %x \n", offsets);Driver->DriverUnload = UnDriver;return STATUS_SUCCESS;} 運行如上代碼將動態計算出目前偏移地址的pbase實際地址,實現效果圖如下所示;
關鍵詞:
相關文章
精彩推送
當前資訊!天天快資訊丨【當前獨家】西部行丨一半技術人員來自四川 這個新疆生產建設兵團項目里,有更多四川“聲音” 消息
四川在線記者唐澤文吳聃到達位于新疆生產建設兵團第七師胡楊河市的新疆
焦點快看:提前了解Windows 11的Windows Copilot - 微軟最廣泛的AI升級
WindowsCopilot可能會在未來幾周內開始向WindowsInsider計劃的測試人員
[路演]恒工精密:產能位居國內連續鑄造工藝競爭對手前列 曾獲“2018 年度中國鑄造行業單項冠軍產品”等多項榮譽 當前視點
恒工精密董事長、總經理魏志勇表示,在連續鑄造及機加工領域,公司擁有
