ReadProcessMemory读取进程内存中的所有0
ReadProcessMemory reads all 0s in a process memory
我正在尝试编写一个进程内存扫描程序,用于扫描内存中的非零值:
MEMORY_BASIC_INFORMATION mbi;
char* addr = 0;
dtype readVal = 0;
while (VirtualQueryEx(hProc, addr, &mbi, sizeof(mbi))) { // HANDLE hProc is defined earlier
if (mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS) {
for (int i = 0; i < mbi.RegionSize; i += sizeof(readVal)) {
BOOL ret = ReadProcessMemory(hProc, (char*) mbi.BaseAddress + i, &readVal, sizeof(readVal), 0);
printf("ReadProcessMemory returns %dn", ret); // returns 5 (ERROR_ACCESS_DENIED)
if (readVal != 0) {
printf("Found a good value!");
system("pause");
}
}
}
addr += mbi.RegionSize;
}
我在chrome.exe
上尝试了一下,扫描仪发现了大量的非零值。但是,当我在一个带有防热功能的游戏进程中尝试它时,它失败了,ReadProcessMemory
在每次调用ReadProcessMemory
时都会返回ERROR_ACCESS_DENIED
。手柄hProc
连接到游戏进程没有问题,并且找到了正确的PID。为什么会这样,我们如何才能增加我们的特权来绕过反高温?
根据这个线程,你需要枚举一个进程的所有模块,以获得你感兴趣的模块的有效句柄。然后你可以像这样使用ReadProcessMemory
作为管理员运行来读取多级指针:
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>
using namespace std;
DWORD_PTR dwGetModuleBaseAddress(DWORD dwProcID, TCHAR *szModuleName);
int main()
{
HWND hwnd = FindWindowA(NULL, "Game");
if (hwnd == NULL)
{
cout << "Cannot find window." << endl;
Sleep(3000);
exit(-1);
}
else
{
DWORD procID;
GetWindowThreadProcessId(hwnd, &procID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
DWORD_PTR ModuleBaseAddress = 0;
ModuleBaseAddress = dwGetModuleBaseAddress(procID, _T("Game.exe"));
if (procID == NULL)
{
cout << "Cannot find process.";
Sleep(3000);
exit(-1);
}
else {
while (true)
{
DWORD temp;
ReadProcessMemory(handle, (LPCVOID)(ModuleBaseAddress + 0x43021C), &temp, sizeof(temp), NULL);
ReadProcessMemory(handle, (LPCVOID)(temp + 0xAC), &temp, sizeof(temp), NULL);
int curhp;
ReadProcessMemory(handle, (LPCVOID)(temp + 0x4C), &curhp, sizeof(curhp), NULL);
cout << "Current HP: " << curhp << endl;
Sleep(100);
system("CLS");
}
}
}
system("PAUSE");
}
DWORD_PTR dwGetModuleBaseAddress(DWORD dwProcID, TCHAR *szModuleName)
{
DWORD_PTR dwModuleBaseAddress = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcID);
if (hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &ModuleEntry32))
{
do
{
if (_tcsicmp(ModuleEntry32.szModule, szModuleName) == 0)
{
dwModuleBaseAddress = (DWORD_PTR)ModuleEntry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &ModuleEntry32));
}
CloseHandle(hSnapshot);
}
return dwModuleBaseAddress;
}
有关更多详细信息,您可以从互联网上进行研究。
代码的精简版本大致如下:
dtype readVal;
if (readVal != 0) {
printf("Found a good value!");
system("pause");
}
有一个(可能(未初始化的值(readVal
(,一些代码的代码路径不会改变值,然后是读取访问。这样做没有指定的行为。因此,它的行为被暗示为未定义的。
要修复您的代码,您需要进行两项更改:
readVal
需要初始化,并在最内部的循环中重置。虽然不知道readVal
是什么数据类型,但不可能知道它是初始化还是未初始化。这只是一个练习- ReadProcessMemory可能会失败。它通过返回
FALSE
来报告失败。您需要检查故障,如果需要扩展的错误信息,可以选择调用GetLastError
为什么会这样,我们如何绕过防热?
我们不知道,因为您决定将重要信息保密(例如目标的具体名称和版本(。绕过软件保护是很困难的。花十年的时间进行二进制开发,你可能会准备想出一种方法。Stack Overflow无法帮助您。
相关文章:
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 如何读取特定地址的进程内存?
- 如何使用带有矢量的 winapi 读取进程内存从另一个进程读取缓冲区?
- 先进先出:一个进程永远不会从管道读取
- 读取进程内存多级指针(DLL 注入)
- 读取进程内存作弊引擎值
- 从stdin读取时子进程挂起(fork/dup2竞争条件)
- c++ 读取进程内存基址 + 偏移量不起作用
- 使用管道从 STDIN 读取分叉进程时出现问题
- Boost.Process - 从具有休眠循环的进程读取
- 内核模式驱动程序可以在任何进程上执行读取进程内存吗?
- 如何确保我们从 boost::child 进程中读取所有行
- C++ 读取 Java 进程输出
- 在子进程处于活动状态时读取子进程的输出
- 无法读取继承进程中的文件
- 我们可以从父进程读取子进程的环境变量吗
- 子进程被满管道阻塞,无法读取父进程
- 读取分离进程的控制台输出
- 如何在过滤器驱动程序中读取当前进程的PE头
- 更好的设计模式用于读取其他进程内存