国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

驅(qū)動開發(fā):內(nèi)核讀寫內(nèi)存多級偏移

這篇具有很好參考價值的文章主要介紹了驅(qū)動開發(fā):內(nèi)核讀寫內(nèi)存多級偏移。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

讓我們繼續(xù)在《內(nèi)核讀寫內(nèi)存浮點數(shù)》的基礎(chǔ)之上做一個簡單的延申,如何實現(xiàn)多級偏移讀寫,其實很簡單,讀寫函數(shù)無需改變,只是在讀寫之前提前做好計算工作,以此來得到一個內(nèi)存偏移值,并通過調(diào)用內(nèi)存寫入原函數(shù)實現(xiàn)寫出數(shù)據(jù)的目的。

以讀取偏移內(nèi)存為例,如下代碼同樣來源于本人的LyMemory讀寫驅(qū)動項目,其中核心函數(shù)為WIN10_ReadDeviationIntMemory()該函數(shù)的主要作用是通過用戶傳入的基地址與偏移值,動態(tài)計算出當(dāng)前的動態(tài)地址。

函數(shù)首先將基地址指向要讀取的變量,并將其轉(zhuǎn)換為LPCVOID類型的指針。然后將指向變量值的緩沖區(qū)轉(zhuǎn)換為LPVOID類型的指針。接下來,函數(shù)使用PsLookupProcessByProcessId函數(shù)查找目標(biāo)進程并返回其PEPROCESS結(jié)構(gòu)體。隨后,函數(shù)從偏移地址數(shù)組的最后一個元素開始迭代,每次循環(huán)都從目標(biāo)進程中讀取4字節(jié)整數(shù)型數(shù)據(jù),并將其存儲在Value變量中。然后,函數(shù)將基地址指向Value和偏移地址的和,以便在下一次循環(huán)中讀取更深層次的變量。最后,函數(shù)將基地址指向最終變量的地址,讀取變量的值,并返回。

如下案例所示,用戶傳入進程基址以及offset偏移值時,只需要動態(tài)計算出該偏移地址,并與基址相加即可得到動態(tài)地址。

#include <ntifs.h>
#include <ntintsafe.h>
#include <windef.h>

// 普通Ke內(nèi)存讀取
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;
	else
		return STATUS_ACCESS_DENIED;
}

// 讀取整數(shù)內(nèi)存多級偏移
/*
  Pid: 目標(biāo)進程的進程ID。
  Base: 變量的基地址。
  offset: 相對基地址的多級偏移地址,用于定位變量。
  len: 偏移地址的數(shù)量。
*/
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;
}

// 驅(qū)動卸載例程
VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("Uninstall Driver \n");
}

// 驅(qū)動入口地址
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;

	// 讀取內(nèi)存數(shù)據(jù)
	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] 讀取偏移數(shù)據(jù): %d \n", read);

	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

編譯并運行如上這段代碼,則可獲取到PID=4884PBase的動態(tài)地址中的數(shù)據(jù),如下圖所示;

驅(qū)動開發(fā):內(nèi)核讀寫內(nèi)存多級偏移

至于如何將數(shù)據(jù)寫出四級偏移的基址上面,則只需要取出pbase里面的基址,并通過原函數(shù)WIN10_WriteProcessMemory直接寫出數(shù)據(jù)即可,此出的原函數(shù)在《內(nèi)核MDL讀寫進程內(nèi)存》中已經(jīng)做了詳細(xì)介紹,實現(xiàn)寫出代碼如下所示;

#include <ntifs.h>
#include <ntintsafe.h>
#include <windef.h>

// 普通Ke內(nèi)存讀取
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;
	else
		return STATUS_ACCESS_DENIED;
}

// Win10 內(nèi)存寫入函數(shù)
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
	{
		//分配內(nèi)存
		buff1 = ExAllocatePoolWithTag((POOL_TYPE)0, BYTE_size, 1997);
		buff2 = buff1;
		*(int*)buff1 = 1;
		if (MmIsAddressValid((PVOID)VirtualAddress))
		{
			// 復(fù)制內(nèi)存
			memcpy(buff2, VirtualAddress, BYTE_size);
		}
		else
		{
			return FALSE;
		}

		// 附加到要讀寫的進程
		KeStackAttachProcess((PRKPROCESS)Process, &KAPC);
		if (MmIsAddressValid((PVOID)Address))
		{
			// 判斷地址是否可寫
			ProbeForWrite(Address, BYTE_size, 1);
			// 復(fù)制內(nèi)存
			memcpy(Address, buff2, BYTE_size);
		}
		else
		{
			return FALSE;
		}
		// 剝離附加的進程
		KeUnstackDetachProcess(&KAPC);
		ExFreePoolWithTag(buff2, 1997);
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		return FALSE;
	}
	return FALSE;
}

// 寫入整數(shù)內(nèi)存多級偏移
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;
	}

	// 使用原函數(shù)寫入
	BOOLEAN ref = WIN10_WriteProcessMemory(Pid, (void *)pbase, 4, &SetValue);
	if (ref == TRUE)
	{
		DbgPrint("[內(nèi)核寫成功] # 寫入地址: %x \n", pbase);
		return 1;
	}
	return 0;
}

// 驅(qū)動卸載例程
VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("Uninstall Driver \n");
}

// 驅(qū)動入口地址
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;

	// 寫出內(nèi)存數(shù)據(jù)
	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] 寫出偏移數(shù)據(jù): %d \n", SetValue);

	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

運行如上代碼將在0x6566e0所在的基址上,將數(shù)據(jù)替換為100,實現(xiàn)效果圖如下所示;

驅(qū)動開發(fā):內(nèi)核讀寫內(nèi)存多級偏移

那么如何實現(xiàn)讀寫內(nèi)存浮點數(shù),字節(jié)集等多級偏移呢?

其實我們可以封裝一個WIN10_ReadDeviationMemory函數(shù),讓其只計算得出偏移地址,而所需要寫出的類型則根據(jù)自己的實際需求配合不同的寫入函數(shù)完成,也就是將兩者分離開,如下則是一段實現(xiàn)計算偏移的代碼片段,該代碼同樣來自于本人的LyMemory驅(qū)動讀寫項目;

#include <ntifs.h>
#include <ntintsafe.h>
#include <windef.h>

// 普通Ke內(nèi)存讀取
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;
	else
		return STATUS_ACCESS_DENIED;
}

// 讀取多級偏移內(nèi)存動態(tài)地址
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;
}

// 驅(qū)動卸載例程
VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("Uninstall Driver \n");
}

// 驅(qū)動入口地址
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;

	// 寫出內(nèi)存數(shù)據(jù)
	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;
}

運行如上代碼將動態(tài)計算出目前偏移地址的pbase實際地址,實現(xiàn)效果圖如下所示;

驅(qū)動開發(fā):內(nèi)核讀寫內(nèi)存多級偏移文章來源地址http://www.zghlxwxcb.cn/news/detail-501882.html

到了這里,關(guān)于驅(qū)動開發(fā):內(nèi)核讀寫內(nèi)存多級偏移的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 驅(qū)動開發(fā):內(nèi)核解析內(nèi)存四級頁表

    驅(qū)動開發(fā):內(nèi)核解析內(nèi)存四級頁表

    當(dāng)今操作系統(tǒng)普遍采用64位架構(gòu),CPU最大尋址能力雖然達到了64位,但其實僅僅只是用到了48位進行尋址,其內(nèi)存管理采用了 9-9-9-9-12 的分頁模式, 9-9-9-9-12 分頁表示物理地址擁有四級頁表,微軟將這四級依次命名為PXE、PPE、PDE、PTE這四項。 關(guān)于內(nèi)存管理和分頁模式,不同的操

    2024年02月06日
    瀏覽(24)
  • 字符設(shè)備驅(qū)動(內(nèi)核態(tài)用戶態(tài)內(nèi)存交互)

    字符設(shè)備驅(qū)動(內(nèi)核態(tài)用戶態(tài)內(nèi)存交互)

    內(nèi)核驅(qū)動:運行在內(nèi)核態(tài)的動態(tài)模塊,遵循內(nèi)核模塊框架接口,更傾向于插件。 應(yīng)用程序:運行在用戶態(tài)的進程。 應(yīng)用程序與內(nèi)核驅(qū)動交互通過既定接口,內(nèi)核態(tài)和用戶態(tài)訪問依然遵循內(nèi)核既定接口。 系統(tǒng):openEuler-20.03-LTS-SP3 char_module.c Makefile 驅(qū)動構(gòu)建 驅(qū)動信息確認(rèn) 應(yīng)用程

    2024年02月11日
    瀏覽(26)
  • 【嵌入式環(huán)境下linux內(nèi)核及驅(qū)動學(xué)習(xí)筆記-(10-內(nèi)核內(nèi)存管理)】

    【嵌入式環(huán)境下linux內(nèi)核及驅(qū)動學(xué)習(xí)筆記-(10-內(nèi)核內(nèi)存管理)】

    對于包含MMU(內(nèi)存管理單元)的處理器而言,linux系統(tǒng)以虛擬內(nèi)存的方式為每個進程分配最大4GB的內(nèi)存。這真的4GB的內(nèi)存空間被分為兩個部分–用戶空間 與 內(nèi)核空間。用戶空間地地址分布為0~3GB,剩下的3 ~ 4GB 為內(nèi)核空間。如下圖。 用戶進程通常只能訪問用戶空間的虛擬地址

    2024年02月11日
    瀏覽(23)
  • linux驅(qū)動開發(fā)--day1(驅(qū)動、內(nèi)核模塊及相關(guān)命令、內(nèi)核模塊傳參)
  • Linux驅(qū)動開發(fā)——內(nèi)核模塊

    Linux驅(qū)動開發(fā)——內(nèi)核模塊

    目錄 內(nèi)核模塊的由來 第一個內(nèi)核模塊程序? 內(nèi)核模塊工具? 將多個源文件編譯生成一個內(nèi)核模塊? 內(nèi)核模塊參數(shù) 內(nèi)核模塊依賴 關(guān)于內(nèi)核模塊的進一步討論? 習(xí)題 最近一直在玩那些其它的技術(shù),眼看快暑假了,我決定夯實一下我的驅(qū)動方面的技能,迎接我的實習(xí),找了一本

    2024年02月04日
    瀏覽(100)
  • Linux內(nèi)核驅(qū)動開發(fā)(一)

    Linux內(nèi)核驅(qū)動開發(fā)(一)

    linux操作系統(tǒng)歷史 開發(fā)模式 git 分布式管理 git clone 獲取 git push 提交 git pull 更新 郵件組 mailing list patch 內(nèi)核代碼組成 Makfile arch 體系系統(tǒng)架構(gòu)相關(guān) block 塊設(shè)備 crypto 加密算法 drivers 驅(qū)動(85%) atm 通信 bluetooth 藍牙 firmware:外設(shè) fs 文件系統(tǒng) include 頭文件 init 啟動代碼 ipc 進程通

    2023年04月11日
    瀏覽(23)
  • linux內(nèi)核網(wǎng)絡(luò)驅(qū)動框架(linux驅(qū)動開發(fā)篇)

    linux內(nèi)核網(wǎng)絡(luò)驅(qū)動框架(linux驅(qū)動開發(fā)篇)

    網(wǎng)絡(luò)驅(qū)動的核心: 1、就是初始化 net_device 結(jié)構(gòu)體中的各個成員變量, 2、然后將初始化完成以后的 net_device 注冊到 Linux 內(nèi)核中 1、網(wǎng)絡(luò)設(shè)備(用net_device結(jié)構(gòu)體) 2、網(wǎng)絡(luò)設(shè)備的操作集( net_device_ops結(jié)構(gòu)體 ) 3、sk_buff結(jié)構(gòu)體 網(wǎng)絡(luò)是分層的,對于應(yīng)用層而言不用關(guān)系具體的底層是

    2023年04月08日
    瀏覽(27)
  • 驅(qū)動開發(fā):內(nèi)核遍歷文件或目錄

    驅(qū)動開發(fā):內(nèi)核遍歷文件或目錄

    在筆者前一篇文章 《驅(qū)動開發(fā):內(nèi)核文件讀寫系列函數(shù)》 簡單的介紹了內(nèi)核中如何對文件進行基本的讀寫操作,本章我們將實現(xiàn)內(nèi)核下遍歷文件或目錄這一功能,該功能的實現(xiàn)需要依賴于 ZwQueryDirectoryFile 這個內(nèi)核API函數(shù)來實現(xiàn),該函數(shù)可返回給定文件句柄指定的目錄中文件

    2024年02月08日
    瀏覽(29)
  • 驅(qū)動開發(fā):內(nèi)核ShellCode線程注入

    驅(qū)動開發(fā):內(nèi)核ShellCode線程注入

    還記得 《驅(qū)動開發(fā):內(nèi)核LoadLibrary實現(xiàn)DLL注入》 中所使用的注入技術(shù)嗎,我們通過 RtlCreateUserThread 函數(shù)調(diào)用實現(xiàn)了注入DLL到應(yīng)用層并執(zhí)行,本章將繼續(xù)探索一個簡單的問題,如何注入 ShellCode 代碼實現(xiàn)反彈Shell,這里需要注意一般情況下 RtlCreateUserThread 需要傳入兩個最重要的

    2024年02月08日
    瀏覽(35)
  • 驅(qū)動開發(fā):摘除InlineHook內(nèi)核鉤子

    驅(qū)動開發(fā):摘除InlineHook內(nèi)核鉤子

    在筆者上一篇文章 《驅(qū)動開發(fā):內(nèi)核層InlineHook掛鉤函數(shù)》 中介紹了通過替換 函數(shù) 頭部代碼的方式實現(xiàn) Hook 掛鉤,對于ARK工具來說實現(xiàn)掃描與摘除 InlineHook 鉤子也是最基本的功能,此類功能的實現(xiàn)一般可在應(yīng)用層進行,而驅(qū)動層只需要保留一個 讀寫字節(jié) 的函數(shù)即可,將復(fù)雜

    2024年02月10日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包