[C/C++]利用api实现对其他进程暴力枚举内存页修改内容(
运行环境:windows 10
涉及工具:
vs2019
编程语言:
C
以下为主题内容:没太了解过Cheat engine,但是感觉写出来的这个估计也Ce的机理差不多
所用到的Api CreateProcess、ReadProcessMemory、WriteProcessMemory流程是先用CreateProcess()打开目标进程,以获取hProcess(进程句柄),然后ReadProcessMemory...找地址
WirteProcessMemory该地址的数据
里面还有很多细节 比如我只枚举了进程低2Gb的空间 因为高2Gb是内核。而且基质要是64kb以后,前64kb的物理页无法写入和读取。Windows系统的规定。
贴出Msdn给的这三个Api的解释,加上代码 估计能了解各个参数的含义。难懂的参数我都会注释。(其实也已经英文注释了 看不懂的可以自己去翻译)
这三个Api都是很基础的了,纯纯菜鸟做,目前刚学windows核心编程。大佬还请点击右上角
这是CreateProcess ApiCsdn的解释
BOOL CreateProcess(
LPCTSTR lpApplicationName, // name of executable module
LPTSTR lpCommandLine, // command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD 安全属性
LPSECURITY_ATTRIBUTES lpThreadAttributes,// SD 安全属性 无用 填Null
BOOL bInheritHandles, // handle inheritance option
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCTSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFO lpStartupInfo, // startup information
LPPROCESS_INFORMATION lpProcessInformation // process information);
下面是WriteProcessMemory和ReadProcessMemory;
BOOL WriteProcessMemory(HANDLE hProcess, // handle to process
LPVOID lpBaseAddress, // base of memory area
LPVOID lpBuffer, // data buffer
DWORD nSize, // number of bytes to write
LPDWORD lpNumberOfBytesWritten // number of bytes written);
BOOL ReadProcessMemory(HANDLE hProcess, // handle to the process
LPCVOID lpBaseAddress, // base of memory area
LPVOID lpBuffer, // data buffer
DWORD nSize, // number of bytes to read
LPDWORD lpNumberOfBytesRead// number of bytes read);
效果图:
输入要找的值
可以看到
有很多 那我们next search
现在只有一个值了 修改吧
因为我修改的值太大了 所以只能(32-bit) 这个值就是int的最大值 应该是有符号的最大值
代码下面 只有一个cpp 没有什么别的
/////////////////////By Oxygen1a1///////////////////////////
////////////通过暴力枚举实现修改进程内存////////////////
////////////作者邮箱304914289@qq.com 欢迎反馈///////
#include <stdio.h>
#include <Windows.h>
BOOL FindFirst(DWORD dwVaule);//对目标进程空间进行查找
BOOL FindNext(DWORD dwValue);//对目标空间以后的查找
//把查找的东西放在列表里面
DWORD g_arList;
int g_nListCnt;//有效的地址个数
HANDLE g_hProcess;//目标进程句柄
void ShowList();//用来显示查找到的地址
BOOL WriteMemory(DWORD dwAddr, DWORD dwVaule);//最后用来改东西的
int main() {
//1.首先用CreateProcess 把目标进程Testor拉起来
//获取句柄就可以了
char szFileName[] = "Target.exe";//目标程序 注意工作路径
STARTUPINFO si;
memset(&si, 0, sizeof(si));
PROCESS_INFORMATION pi;
BOOL bRet = CreateProcess(
NULL,
szFileName,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi
);
if (bRet) {
g_hProcess = pi.hProcess;//获取进程句柄
}
//2.然后 我们需要将memchange接受一个目标值 并比对
int iVal;
printf("first search:");
scanf_s("%d", &iVal);
FindFirst(iVal);
//交互显示
ShowList();
while (g_nListCnt > 1) {
printf("next search:");
scanf_s("%d", &iVal);
FindNext(iVal);
ShowList();
}
//得到唯一地址的值
printf("new vaule:");
scanf_s("%d", &iVal);
if (WriteMemory(g_arList, iVal)) {
printf("ok!!");
}
}
BOOL ComPareAPage(DWORD dwBaseAddr, DWORD dwValue) {
BYTE arBytes;//4kb
if (!ReadProcessMemory(g_hProcess, (LPVOID)dwBaseAddr, arBytes, 4096, NULL)) {
return false;
}
DWORD* pdw;
for (int i = 0; i < 4 * 1024 - 3; i++) {
pdw = (DWORD*)&arBytes;
if (*pdw == dwValue) {
if (g_nListCnt >= 1024) return false;//太多了
g_arList = dwBaseAddr + i;
}
}
return TRUE;
}
BOOL FindFirst(DWORD dwVaule) {
const DWORD dwOneGB = 1024 * 1024 * 1024;
const DWORD dwOnePage = 4 * 1024;//4kb
if (g_hProcess == nullptr) return false;
DWORD dwBase = 640 * 1024;
//BOOL bRet = FALSE;
for (; dwBase < 2 * dwOneGB; dwBase += dwOnePage) {//在低2Gb的内核态进行查找
ComPareAPage(dwBase, dwVaule);
}
return TRUE;
}
BOOL FindNext(DWORD dwVaule) {
BOOL bRet = FALSE;
//这个时候只需要在g_arList中查找即可,
int nOrgCnt = g_nListCnt;
g_nListCnt = 0;//清空上一次找到的地址 下面在慢慢加 也是节省变量
DWORD dwReadVaule;
for (int i = 0; i < nOrgCnt; i++) {
if (ReadProcessMemory(g_hProcess, (LPVOID)g_arList
, &dwReadVaule, sizeof(DWORD), NULL)) {
//读取成功后
if (dwReadVaule == dwVaule) {
//值还一样
g_arList = g_arList;
}
}
bRet = TRUE;
}
return bRet;
}
void ShowList() {
printf("全部地址:\n");
for (int i = 0; i < g_nListCnt; i++) {
printf("%p ", g_arList);
}
printf("\n");//换行 美观
}
BOOL WriteMemory(DWORD dwAddr, DWORD dwVaule) {
return WriteProcessMemory(g_hProcess, (LPVOID)dwAddr, &dwVaule
, sizeof(DWORD), NULL);
}
谢谢分享 可以多发一些这类内容吗?我很喜欢!! 看着很不错,回复一个看看 谢谢分享 感谢楼主 感谢楼主 谢谢分享 帮顶一下 来向大佬学习