windows | ce查基址+代码修改内存

查基址这个东西就是找一个偏移嘛。

这次用的程序是1.0原版的植物大战僵尸。

找了个简单点的数据就是阳光,直接搜2次就能找到这个int变量。

然后查对于这个地址的内存访问。

找到的里面有个偏移,再对之前计算的那个进行查找,然后查看内存访问,最后结果如下:

阳光 = [[基地址+0x768] + 5560]

基地址0x6a9ec0

然后就是写代码修改阳光的问题了,主要就是先获取进程pid然后OpenProcess,然后对内存进行读写。

贴代码:

#include<stdio.h>
#include<Windows.h>
#include<TlHelp32.h>
#define NAME "mspaint.exx"  //要修改的进程名
 
DWORD GetPid(char* szName){
    HANDLE hprocessSnap = NULL;
    PROCESSENTRY32 pe32 = {0};
    hprocessSnap = CreateToolhelp32Snapshot(
        TH32CS_SNAPPROCESS,
        0);//捕捉所有进程的快照
    if (hprocessSnap == INVALID_HANDLE_VALUE){
        //快照失败
        return 0;
    }
    //初始化pe32结构体
    pe32.dwSize = sizeof(PROCESSENTRY32);
    if (Process32First(hprocessSnap, &pe32)){
        do{
            if (!strcmp(szName, pe32.szExeFile)){
                printf("Process Found, PID: %d \n", (int)pe32.th32ProcessID);
                return (int)pe32.th32ProcessID;
            }
            //遍历查找进程名
        }while (Process32Next(hprocessSnap, &pe32));
    }else{
        CloseHandle(hprocessSnap);
    }
    return 0;
}


void main()
{
	DWORD pid = GetPid("popcapgame1.exe");      // 获取进程pid

	//获取进程句柄
	HANDLE hProcess;
	hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
	printf("%x \n", hProcess);
	if (hProcess == NULL)
	{
		printf("fail to open process \n");
		CloseHandle(hProcess);
		return;
	}
	//CloseHandle(hProcess);
	
	// 获取模块地址
	DWORD modaddr = NULL;
	MODULEENTRY32 modentry;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
	modentry.dwSize = sizeof(MODULEENTRY32); // 初始化一下
	Module32First(hSnapshot, &modentry);
	do{
		if (!strcmp(modentry.szModule, "popcapgame1.exe")){
			modaddr = (DWORD)(modentry.hModule);
			printf("Module Found, addr: %x \n", modaddr);
			CloseHandle(hSnapshot);
			break;
		}
		//遍历查找进程名
    }while (Module32Next(hSnapshot, &modentry));

	// 读阳光数据
	/*
	183fc4f8 + 5560
	[[基地址+0x768] + 5560] 
	基地址0x6a9ec0
	*/
	DWORD pObj = modaddr;            // 有的时候偏移要用,但是这次直接是固定基地址所以不用管
	pObj = NULL;
	printf("pobj: %x \n", pObj);
	int a = ReadProcessMemory(hProcess, (LPCVOID)(pObj+0x6a9ec0), &pObj, 4, 0);
	printf("pobj: %x \n", pObj);
	ReadProcessMemory(hProcess, (LPCVOID)(pObj+0x768), &pObj, 4, 0);
	printf("pobj: %x \n", pObj);
	DWORD pSun = pObj+0x5560;

	int sun = 0;
	int max_sun = 9999;
	ReadProcessMemory(hProcess, (LPCVOID)(pSun), &sun, 4, 0);
	printf("sun: %d \n", sun);

	
	while(1)
	{
		Sleep(1000);
		ReadProcessMemory(hProcess, (LPCVOID)(pSun), &sun, 4, 0);
		WriteProcessMemory(hProcess, (LPVOID)(pSun), &max_sun, 4, 0);   // 阳光拉满
		printf("sun: %d \n", sun);
	}

	CloseHandle(hProcess);


	return;
}

P.S.中间查模块的代码其实用不到,因为基址是写死的,不是相对于模块的偏移。

posted @ 2021-08-17 20:20  Mz1  阅读(747)  评论(0编辑  收藏  举报