Motoko 发表于 2018-4-27 13:29:07

关于ReadProcessMemory函数的小问题

是这样的我用c语言获取到了进程的内存读写权限,并且我想修改一个基地址所指向的最终的值(植物大战僵尸的阳光值基地址(0x 00199178)),这个值指向0x 20155c08,但是这个值是有一个偏移的,最后的阳光值地址是20155c08 + 5578后的值。我想请教一下如何才能得到这个最后的值,怎么通过基址找到最后的值,我以为定义一个指针将00199178赋值过去然后就可以计算呢,但是不行会报错,请了解相关只是的大佬详细给我解释一下,最好能给出范例。十分奉上!这是我的其中一段代码:
程序代码:
DWORD dwSunjizhi,dwSun1=0,dwSize=0;
    dwSunjizhi=0x00199178;

    if(NULL==ReadProcessMemory(hProcess,(LPVOID)dwSunjizhi,&dwSun1,sizeof(DWORD),&dwSize));
    {
      printf("读取内存失败!错误编号:%d\n3秒后退出...\n",GetLastError());
      Sleep(3000);
      exit(0);
    }

溯影 发表于 2018-4-27 14:41:06

请问楼主你是不是想要确定那个阳光值的实际的内存地址,然后用WriteProcessMemory来更改这个地址所对应的值
我之前有一个学习笔记,也是查找游戏某一属性的内存里的地址然后用WriteProcessMemory来更改这个的值的
http://bbs.fishc.com/thread-109532-1-1.html
其实我感觉这个找内存的实际的地址话要和书上讲的一样,要进行第一次查找后多次筛选,就是变换值之后多次筛选
来确定最后一个唯一的地址

比如程序运行:
第一个testor中运行时:
i=199,addr=012FF900       g_nNum=1002,addr=003C8548
第一次修改内存程序运行的时候:(我要查找g_nNum的内存地址)
Input val:1002
003C8548
59457D9F
5948884F
594C608C
594E0855
5AFB4E58
73EBBB57
770365B8
77047E58
77153C39
774AF617
Input val =
(发现对应的g_nNum好多的地址,所以我们要再筛选一下)
第二次的时候动testor里的值,按几下enter后让testor里的值改变
比如:
i=199,addr=012FF900       g_nNum=1002,addr=003C8548

i=200,addr=012FF900       g_nNum=1001,addr=003C8548

i=201,addr=012FF900       g_nNum=1000,addr=003C8548

i=202,addr=012FF900       g_nNum=999,addr=003C8548

i=203,addr=012FF900       g_nNum=998,addr=003C8548

i=204,addr=012FF900       g_nNum=997,addr=003C8548
这个时候g_nNum的值为997,
我们再把997填入到内存查找的框中:
Input val:1002
003C8548
59457D9F
5948884F
594C608C
594E0855
5AFB4E58
73EBBB57
770365B8
77047E58
77153C39
774AF617
Input val = 997
003C8548
New value =
(这个时候发现我们找到了g_nNum的实际的地址,我们要输入要修改的值:例如我们填入1234,就是把g_nNum从值997修改到1234

试一下:
New value = 1234
Write data successfully
请按任意键继续. . .

再看一下最后testor中的变化,
i=204,addr=012FF900       g_nNum=997,addr=003C8548

i=205,addr=012FF900       g_nNum=1233,addr=003C8548

i=206,addr=012FF900       g_nNum=1232,addr=003C8548

i=207,addr=012FF900       g_nNum=1231,addr=003C8548

i=208,addr=012FF900       g_nNum=1230,addr=003C8548

i=209,addr=012FF900       g_nNum=1229,addr=003C8548

i=210,addr=012FF900       g_nNum=1228,addr=003C8548
发现我们成功修改了g_nNum的值



不知道楼主是不是要这个,毕竟那个readProcessMemory我也没有太明白你的意思,我感觉楼主应该就是想要查找值的内存的最终的地址,至于如何朝找,可以参考上面的那个博客,程序运行的时后要再项目属性里更改一下多字节字符

人造人 发表于 2018-4-28 02:32:46



附上代码,自行研究
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <cstdarg>

UINT32 ReadAddress_4Byte(HANDLE hProcess, UINT32 BaseAddress)
{
        UINT32 data;
        SIZE_T NumberOfBytesRead;

        ReadProcessMemory(hProcess, (LPCVOID)BaseAddress, &data, 4, &NumberOfBytesRead);
        return data;
}

void WriteAddress_4Byte(HANDLE hProcess, UINT32 BaseAddress, UINT32 data)
{
        SIZE_T NumberOfBytesWritten;

        WriteProcessMemory(hProcess, (LPVOID)BaseAddress, &data, 4, &NumberOfBytesWritten);
}

DWORD GetProcessIdByName(std::string ProcessName)
{
        DWORD dwProcessId = 0;
        PROCESSENTRY32 pe32;
        HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

        pe32.dwSize = sizeof(PROCESSENTRY32);
        Process32First(hProcessSnap, &pe32);

        do
        {
                if(ProcessName == pe32.szExeFile)
                {
                       
                        dwProcessId = pe32.th32ProcessID;
                        break;
                }
        }
        while(Process32Next(hProcessSnap, &pe32));

        CloseHandle(hProcessSnap);
        return dwProcessId;
}

UINT32 GetAddress(HANDLE hProcess, UINT32 base, int level, ...)
{
        va_list ap;

        UINT32 address = base;
        UINT32 offset;
        address = ReadAddress_4Byte(hProcess, address);

        va_start(ap, level);
        for(int i = 0; i < level - 1; ++i)
        {
                address = ReadAddress_4Byte(hProcess, address + va_arg(ap, UINT32));
        }
        offset = va_arg(ap, UINT32);
        va_start(ap, level);

        return address + offset;
}

int main()
{
        DWORD dwProcessId = GetProcessIdByName("PlantsVsZombies.exe");
        if(dwProcessId == 0)
                return 0;

        HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, 0, dwProcessId);
       

        UINT32 address;
        address = GetAddress(hProcess, 0x5aa054, 5, 0x3a4, 0x10, 0x230, 0x50, 0x80);
        UINT32 data = ReadAddress_4Byte(hProcess, address);
        WriteAddress_4Byte(hProcess, address, data - 100);
       
        CloseHandle(hProcess);
        return 0;
}
页: [1]
查看完整版本: 关于ReadProcessMemory函数的小问题