利用CheatEngine驱动实现内核空间任意读写

利用CheatEngine驱动实现内核空间任意读写

frok https://github.com/ioncodes/ceload

https://github.com/xjohjrdy/ceload

原理

ceload.exe调用CreateProcessW创建进程,将dwCreationFlags设置为CREATE_SUSPENDED状态,然后读写创建的进程空间,在原始OEP处注入shellcode.

shellcode的作用是加载loader.dll。

loader.dll中的主要步骤就是加载驱动(服务),然后将注入shellcode的位置进行恢复,以实现驱动中对调用者身份的检查。

驱动中身份检查、签名检查等部分基本没有变化,所以可以很容易适配CE7.6。

任意地址读写

CE驱动中有太多功能,可以用IOCTL_CE_READMEMORY、IOCTL_CE_WRITEMEMORY读写内存,但如果内存属性为只读,IOCTL_CE_WRITEMEMORY仍然无法写入,需要修改内存属性,但似乎没有修改内存属性的函数。

IOCTL_CE_READPHYSICALMEMORY、IOCTL_CE_WRITEPHYSICALMEMORY、IOCTL_CE_GETPHYSICALADDRESS这几个IoControlCode可以实现将内存地址转换成物理内存地址,并进行读写,可以忽略内存属性。

踩坑

image-20250410002507379

image-20250410002625795

image-20250410012403613

image-20250410012432088

部分API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
BOOL CreateProcessW(
LPCWSTR lpApplicationName, // 可执行文件路径(或模块名)
LPWSTR lpCommandLine, // 命令行参数
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程安全属性
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全属性
BOOL bInheritHandles, // 是否继承父进程句柄
DWORD dwCreationFlags, // 进程创建标志(如优先级、控制台等)
LPVOID lpEnvironment, // 环境变量块(NULL 表示继承父进程)
LPCWSTR lpCurrentDirectory, // 进程工作目录(NULL 表示父进程目录)
LPSTARTUPINFOW lpStartupInfo, // 启动信息(窗口状态、标准句柄等)
LPPROCESS_INFORMATION lpProcessInformation // 返回进程和线程的句柄及ID
);


BOOL ReadProcessMemory(
HANDLE hProcess, // 目标进程的句柄
LPCVOID lpBaseAddress, // 要读取的内存地址(目标进程空间)
LPVOID lpBuffer, // 接收数据的本地缓冲区
SIZE_T nSize, // 要读取的字节数
SIZE_T *lpNumberOfBytesRead // 实际读取的字节数(可选,可设为NULL)
);

BOOL WriteProcessMemory(
HANDLE hProcess, // 目标进程的句柄
LPVOID lpBaseAddress, // 要写入的内存地址(目标进程空间)
LPCVOID lpBuffer, // 要写入的数据的本地缓冲区
SIZE_T nSize, // 要写入的字节数
SIZE_T *lpNumberOfBytesWritten // 实际写入的字节数(可选,可设为NULL)
);

BOOL DeviceIoControl(
HANDLE hDevice, // 设备或驱动程序的句柄
DWORD dwIoControlCode, // 控制代码(IOCTL)
LPVOID lpInBuffer, // 输入数据缓冲区
DWORD nInBufferSize, // 输入缓冲区大小
LPVOID lpOutBuffer, // 输出数据缓冲区
DWORD nOutBufferSize, // 输出缓冲区大小
LPDWORD lpBytesReturned, // 返回的实际数据大小
LPOVERLAPPED lpOverlapped // 异步操作结构(可选)
);