鱼C论坛

 找回密码
 立即注册
查看: 4280|回复: 2

关于ReadProcessMemory函数的小问题

[复制链接]
发表于 2018-4-27 13:29:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
是这样的我用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);
    }
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 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我也没有太明白你的意思,我感觉楼主应该就是想要查找值的内存的最终的地址,至于如何朝找,可以参考上面的那个博客,程序运行的时后要再项目属性里更改一下多字节字符
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-4-28 02:32:46 | 显示全部楼层
无标题.png

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

  5. UINT32 ReadAddress_4Byte(HANDLE hProcess, UINT32 BaseAddress)
  6. {
  7.         UINT32 data;
  8.         SIZE_T NumberOfBytesRead;

  9.         ReadProcessMemory(hProcess, (LPCVOID)BaseAddress, &data, 4, &NumberOfBytesRead);
  10.         return data;
  11. }

  12. void WriteAddress_4Byte(HANDLE hProcess, UINT32 BaseAddress, UINT32 data)
  13. {
  14.         SIZE_T NumberOfBytesWritten;

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

  17. DWORD GetProcessIdByName(std::string ProcessName)
  18. {
  19.         DWORD dwProcessId = 0;
  20.         PROCESSENTRY32 pe32;
  21.         HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

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

  24.         do
  25.         {
  26.                 if(ProcessName == pe32.szExeFile)
  27.                 {
  28.                        
  29.                         dwProcessId = pe32.th32ProcessID;
  30.                         break;
  31.                 }
  32.         }
  33.         while(Process32Next(hProcessSnap, &pe32));

  34.         CloseHandle(hProcessSnap);
  35.         return dwProcessId;
  36. }

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

  40.         UINT32 address = base;
  41.         UINT32 offset;
  42.         address = ReadAddress_4Byte(hProcess, address);

  43.         va_start(ap, level);
  44.         for(int i = 0; i < level - 1; ++i)
  45.         {
  46.                 address = ReadAddress_4Byte(hProcess, address + va_arg(ap, UINT32));
  47.         }
  48.         offset = va_arg(ap, UINT32);
  49.         va_start(ap, level);

  50.         return address + offset;
  51. }

  52. int main()
  53. {
  54.         DWORD dwProcessId = GetProcessIdByName("PlantsVsZombies.exe");
  55.         if(dwProcessId == 0)
  56.                 return 0;

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

  59.         UINT32 address;
  60.         address = GetAddress(hProcess, 0x5aa054, 5, 0x3a4, 0x10, 0x230, 0x50, 0x80);
  61.         UINT32 data = ReadAddress_4Byte(hProcess, address);
  62.         WriteAddress_4Byte(hProcess, address, data - 100);
  63.        
  64.         CloseHandle(hProcess);
  65.         return 0;
  66. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-9 06:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表