自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

函數(shù)首先將基地址指向要讀取的變量,并將其轉(zhuǎn)換為LPCVOID類型的指針。然后將指向變量值的緩沖區(qū)轉(zhuǎn)換為LPVOID類型的指針。接下來,函數(shù)使用PsLookupProcessByProcessId函數(shù)查找目標進程并返回其PEPROCESS結(jié)構(gòu)體。隨后,函數(shù)從偏移地址數(shù)組的最后一個元素開始迭代,每次循環(huán)都從目標進程中讀取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: 目標進程的進程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=4884的PBase的動態(tài)地址中的數(shù)據(jù),如下圖所示;

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

那么如何實現(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;
}
責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2017-08-01 17:34:47

Linux內(nèi)核驅(qū)動文件讀寫

2010-07-19 10:05:52

ibmdwLinux

2015-08-03 10:43:58

Linux內(nèi)核驅(qū)動

2015-07-20 10:00:28

Linux內(nèi)核編碼風(fēng)格

2017-03-23 14:30:13

Linux內(nèi)核驅(qū)動編碼風(fēng)格

2022-03-28 15:40:34

harmony鴻蒙操作系統(tǒng)

2021-12-15 10:02:25

鴻蒙HarmonyOS應(yīng)用

2023-05-15 08:58:41

塊設(shè)備驅(qū)動Linux

2018-03-01 16:25:52

Linux內(nèi)核內(nèi)存管理

2023-02-23 19:28:09

ODD測試

2013-10-31 16:29:10

Linux內(nèi)核

2021-06-24 08:37:34

網(wǎng)絡(luò)安全內(nèi)核代碼

2023-05-12 07:27:24

Linux內(nèi)核網(wǎng)絡(luò)設(shè)備驅(qū)動

2025-01-06 08:00:09

2011-05-20 15:37:05

MemoryStrea

2009-08-20 10:53:23

C#操作內(nèi)存

2018-05-18 09:07:43

Linux內(nèi)核內(nèi)存

2022-10-08 11:57:30

Linux內(nèi)核架構(gòu)

2023-04-28 08:42:08

Linux內(nèi)核SPI驅(qū)動

2023-08-07 09:18:32

Golang偏移量接口
點贊
收藏

51CTO技術(shù)棧公眾號