oxygen1a1 发表于 2022-1-23 17:51

[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);

}


nNDtsS316 发表于 2022-1-23 17:51

谢谢分享

cQHmsZNlTr 发表于 2022-1-23 17:52

可以多发一些这类内容吗?我很喜欢!!

ChfZm7 发表于 2022-1-23 17:53

看着很不错,回复一个看看

学姐95361 发表于 2022-1-23 17:54

谢谢分享

DGY24736 发表于 2022-1-23 17:54

感谢楼主

向日葵89142 发表于 2022-1-23 18:00

感谢楼主

LQpJlqFNXxE 发表于 2022-1-23 18:05

谢谢分享

VXBlSUP138 发表于 2022-1-23 18:05

帮顶一下

iytwfx01 发表于 2022-1-23 18:10

来向大佬学习
页: [1] 2 3 4 5 6 7 8 9
查看完整版本: [C/C++]利用api实现对其他进程暴力枚举内存页修改内容(