众所周知,我们在使用ReadProcessMemory时经常会被有保护的程序拒绝访问(甚至句柄都拿不到)。
#include <windows.h>
int main()
{
int value;
DWORD pid = 18016; // 需要读取内存的进程ID
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); // 获取进程句柄
if (ReadProcessMemory(hProcess, (LPCVOID)0x140000000, &value, sizeof(value), NULL))
{
// 读取成功
printf("Read value: %d\n", value);
}
else
{
// 读取失败
printf("Read failed\n");
}
CloseHandle(hProcess); // 关闭进程句柄
return 0;
}
所以这里提供了一种内核层最基本的读写方法,可以称为:附加读写或者内核API读写(没有任何含金量)
代码如下:
#include<ntifs.h>
NTSTATUS ReadProcessMemoryByMmCopy(SIZE_T pid, SIZE_T readAddress, _Out_ PVOID pOutBuffer, SIZE_T bufferSize)
{
NTSTATUS st;
/* 判断地址是否有效 */
if ((readAddress + bufferSize) < readAddress) return STATUS_INVALID_PARAMETER_2;
if (readAddress >= MmUserProbeAddress) return STATUS_INVALID_PARAMETER_2;
if ((readAddress + bufferSize) >= MmUserProbeAddress) return STATUS_INVALID_PARAMETER_2;
if (pOutBuffer == NULL) return STATUS_INVALID_PARAMETER_3;
/* 打开目标进程 */
PEPROCESS pTargProcess;
st = PsLookupProcessByProcessId((HANDLE)pid, &pTargProcess);
if (!NT_SUCCESS(st)) return STATUS_INVALID_PARAMETER_1;
/* 判断进程状态*/
if (PsGetProcessExitStatus(pTargProcess) != STATUS_PENDING) return STATUS_INVALID_PARAMETER_1;
/* 获取自身进程 */
PEPROCESS pCurrProcess;
pCurrProcess = PsGetCurrentProcess();
if (pCurrProcess == NULL) return STATUS_UNSUCCESSFUL;
/* 读取指定内存 */
SIZE_T ulSize;
st = MmCopyVirtualMemory(pTargProcess, readAddress, pCurrProcess, pOutBuffer, bufferSize, KernelMode, &ulSize);
return st;
}
CV之后我们发现MmCopyVirtualMemory 并没有被识别
因为MmCopyVirtualMemory 函数是内核中的一个导出未文档化函数,当然我们有WRK(Windows Research Kernel,。它给出了Windows这个成功的商业操作系统的内核部分代码),CV 一份他的结构过来,声明一下
EXTERN_C NTSTATUS MmCopyVirtualMemory(
IN PEPROCESS FromProcess,
IN CONST VOID* FromAddress,
IN PEPROCESS ToProcess,
OUT PVOID ToAddress,
IN SIZE_T BufferSize,
IN KPROCESSOR_MODE PreviousMode,
OUT PSIZE_T NumberOfBytesCopied
);
搞定,下播。
以游戏来举例,虽然这种读写方式已经烂大街,但是依然能读到大多数保护的游戏(当然封不封号不一定喽,基本所有主流反作弊系统都会检测附加,甚至不让你附加(满血EAC ))。
这里我们对某款满血ACE保护的游戏进行测试发现是可以读到的。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2024-1-1 00:47
被#Unknow编辑
,原因: 补充