我们知道数据都是写在内存中的,通过一些API我们可以访问并修改内存中的数据,达到修改游戏数据的功能。

通过一个小项目,了解windos读写内存API,以及进程id获取相关API。

大体思路如下:

(1)先找到进程:(API:CreateToolhelp32Snapshot、Process32First、Process32Next)

void ShowProcessList() //功能1显示进程
{PROCESSENTRY32 pc;//定义一个32接收变量pc.dwSize = sizeof(pc);int count = 0;  //进程计数HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//进程状态“快照”BOOL bMore = Process32First(hProcessSnap, &pc);                //“快照”中获取第一个进程while (bMore){cout << "\n---------------------------------------\n";cout << "id: " << pc.th32ProcessID << endl;               //.th32ProcessID获取进程idwprintf(L"name:%s\n", pc.szExeFile);          bMore = Process32Next(hProcessSnap, &pc);                 //转向下一进程count++;}CloseHandle(hProcessSnap);cout << "目前进程数:" << count << endl;}

涉及API:

CreateToolhelp32Snapshot

Process32First

Process32Next

(2)编辑进程   (设计两轮查找,API: OpenProcess、WriteProcessMemory)

void EditProcessData() //功能2 编辑进程
{DWORD dwId = 0;DWORD dwSearchValue = 0;DWORD dwAddrList[4 * KONEK] = { 0 };DWORD dwAddrCount = 0;BOOL bRet = false;scanf_s("%d", &dwId);       //输入需要编辑的进程idHANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwId);//获取进程句柄(打开进程)system("pause");printf("Please input the value which you want search first round:");scanf_s("%u", &dwSearchValue);//输入修改的进程内数据的当前值//首轮查找   待修改进程  查找目标值    存放数组    找到目标计数      空间FirstRound(hProcess, dwSearchValue, dwAddrList, &dwAddrCount, 4 * KONEK);ShowAddrList(dwAddrList, dwAddrCount);//显示搜索结果(目标数为):if (dwAddrCount == 0)      //无目标:返回{return;}else if (dwAddrCount == 1) //一个目标:直接修改{DWORD value;printf("input the value which you want to set");scanf_s("%u", &value);                       //修改唯一值//改写内存数据bRet = WriteProcessMemory(hProcess, (LPVOID)dwAddrList[0], (LPVOID)&value, sizeof(DWORD), NULL);}else                       //多个目标:二轮查找{DWORD dwSecondRoundSearchValue = 0;DWORD dwTargetList[KONEK] = { 0 };DWORD dwTargetCounter = 0;scanf_s("%u", &dwSecondRoundSearchValue);   //二次查找(需对数据进行修改)//二轮查找   进程      二轮查找目标值          原(1轮)地址     原(1轮)目标计数     新目标地址       新目标计数   SecondRound(hProcess, dwSecondRoundSearchValue, dwAddrList, dwAddrCount, dwTargetList, &dwTargetCounter);ShowAddrList(dwTargetList, dwTargetCounter);DWORD value;scanf_s("%u", &value);    //想要改成的数值for (DWORD i = 0; i < dwTargetCounter; i++)//对二轮查找的所有值进行修改{bRet = WriteProcessMemory(hProcess, (LPVOID)dwTargetList[i], (LPCVOID)&value, sizeof(DWORD), NULL);}}}CloseHandle(hProcess);
}

涉及API:

OpenProcess

WriteProcessMemory

(3)结束进程  (API:OpenProcess、TerminateProcess)

void KillProcess() //功能3 结束进程
{BOOL bRet = FALSE;             //进程结束是否成功标志DWORD dwId = 0;                //需结束的进程IDcout << "Please input process id which you want to kill...\n";while (!scanf_s("%d", &dwId)){/*fflush(stdin);*/rewind(stdin);cout << "Please input process id which you want to kill";}HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwId); //打开进程if (hProcess != NULL){bRet = TerminateProcess(hProcess, 0);      //结束进程}CloseHandle(hProcess);if (bRet){cout << "kill process success\n";}else{cout << "kill process filed\n";}return;
}

涉及的API:

OpenProcess

TerminateProcess

ReadProcessMemory:读取进程内存

WriteProcessMemory:写入进程内存

void FirstRound(HANDLE hProcess, DWORD dwValue, DWORD *pAddrList, DWORD *pAddrListCounter, const DWORD addrListMax) //首轮内存查找
{DWORD dwBaseAddr = 64 * KONEK;  //查找首地址DWORD dwPageCount = (2 * KONEG - 64 * KONEK * 2) / KPAGE; //查找计数 用以确定合法范围  |          |    。。。   |       |                        |//  |前64k     |用户程序区   |64k禁区 |       2G内核区           |//  |NULL指针区 |            |       |                       |printf("%u pages\n", dwPageCount);    printf("Start searching...\n");DWORD dwBeginAddr = dwBaseAddr;for (; dwBaseAddr< 2 * KONEG - 64 * KONEK; dwBaseAddr += KPAGE){if (!CompareOnePage(hProcess, dwBaseAddr, dwValue, pAddrList, pAddrListCounter, addrListMax)){return;}//计算进度百分比DWORD page = (dwBaseAddr - dwBeginAddr) / KPAGE + 1;printf("current is %u page\n", page);double temp = ((double)page / dwPageCount) * 100;printf("-----------%%%f---------\n", temp);}printf("\nSearch finished...\n");system("pause");
}
bool CompareOnePage(HANDLE hProcess, DWORD dwBaseAddr, DWORD dwValue, DWORD *pAddrList, DWORD *pAddrListCounter, const DWORD addrListMax) //对单页内数据进行遍历 比对
{BYTE byPage[KPAGE] = { 0 };if (!ReadProcessMemory(hProcess, (LPCVOID)dwBaseAddr, (LPVOID)byPage, KPAGE, NULL)){printf("Read Memory error!!!\n");return true;}DWORD *pdwPointer = NULL;pdwPointer = (DWORD*)byPage;for (DWORD i = 0; i < KONEK; i++){if (*pAddrListCounter >= addrListMax){printf("Too many data, can not save...\n");return false;}if (pdwPointer[i] == dwValue){pAddrList[*pAddrListCounter] = dwBaseAddr + i*sizeof(DWORD);(*pAddrListCounter)++;}}return true;
}void ShowAddrList(DWORD *pDwAddrList, DWORD dwAddrListCount)
{printf("\n--------------Address list begin---------------\n");for (DWORD i = 0; i < dwAddrListCount; i++){printf("%X\n", pDwAddrList[i]);}printf("\n--------------Address list end---------------\n");
}void SecondRound(HANDLE hProcess, DWORD dwValue, DWORD *pAddrList, DWORD dwAddrListCounter, DWORD *pTargetList, DWORD *pTargetCounter)
{DWORD dwTemp = 0;for (DWORD i = 0; i < dwAddrListCounter; i++){if (ReadProcessMemory(hProcess, (LPVOID)pAddrList[i], &dwTemp, sizeof(dwTemp), NULL)){if (dwTemp == dwValue){pTargetList[*pTargetCounter] = pAddrList[i];(*pTargetCounter)++;}}}
}

完整代码:

https://github.com/zjq4688/Myproject.git

Windows开发——内存读写API相关推荐

  1. Linux 字符设备驱动开发--内存读写操作

    学习Linux的累计时间已经有两年多了,工作关系,学习的过程总是断断续续的,现在整理一下,下面要分享的是一个简单的linux驱动程序,将内存当作一个虚拟的设备去读写,没有什么实际的用处,像hello ...

  2. 【笔记】Windows Phone 8开发笔记之API

    Windows Phone 8 API一览 Windows Phone 7平台不支持Native语言的开发,这困扰了许多游戏和底层应用的开发者.Windows Phone 8 SDK的推出,改善了这个 ...

  3. Android开发笔记(二十八)利用Application实现内存读写

    全局变量 C/C++有所谓的全局变量,因为全局变量保存在内存中,所以操作全局变量就是操作内存,其速度远比操作数据库或者操作文件快得多,而且工程里的任何代码都可以引用全局变量,因此很多时候全局变量是共享 ...

  4. 【线程池】自行准备linux环境,带你手写线程池,只需仅仅150行代码|内存池|API|连接池|应用协议丨C/C++Linux服务器开发

    [线程池]自行准备linux环境,带你手写线程池,只需仅仅150行代码 视频讲解如下,点击观看: [线程池]自行准备linux环境,带你手写线程池,只需仅仅150行代码|内存池|API|连接池|应用协 ...

  5. Windows下Libvirt Java API使用教程(二)- 接口使用说明

    介绍完libvirt Java API的部署工作: <Windows下Libvirt Java API使用教程(一)- 开发环境部署> 接下来我们就介绍一下接口的使用和代码样例. libv ...

  6. 转载:Windows CE内存管理

    内存管理 如果你在写Windows CE 程序中遇到的最重要的问题,那一定是内存问题.一个WinCE 系统可能只有4MB 的RAM,这相对于个人电脑来说是十分少的,因为个人电脑的标准配置已经到了128 ...

  7. 使用 dotnet core 和 Azure PaaS服务进行devOps开发(Web API 实例)

    引子 这一篇文章将用一个完整的实例,给大家介绍如何基于dotnet core(微软.NET的最新版本,支持跨平台,跨设备的应用开发,详情请参考 https://www.microsoft.com/ne ...

  8. 为了分析WebRTC, 重学Windows开发

    N多年没有写过 Window 程序了.为了研究 WebRTC 源码,这两天重新学习一下.还记得上大学的时候看过 <Windows95 程式设计>台湾版,对那本书印象极为深刻.一是当时国内确 ...

  9. DirectX游戏开发之一个API玩转音乐

    DirectX游戏开发之一个API玩转音乐 当你闭上眼睛,打开一款游戏,如刺客信条,英雄联盟,DNF,或者是当有一个人坐在你背后玩一款新游戏,第一时间吸引你的是什么? 没错,就是各种游戏的音效,包括背 ...

  10. Windows的内存管理机制

    Windows下的内存是如何管理的? Windows内存的管理可以分为两个层面:物理内存和虚拟内存 其中物理内存由系统管理,不允许应用程序直接访问,应用程序可见的只有一个2G的地址空间,而内存分配是通 ...

最新文章

  1. iis7 php oracle,PHP+IIS7配置OCI8链接Oracle 10G的方法
  2. hibernate加载持久化对象的两种方式---------------load方式和get方式
  3. 每日冲刺报告——Day4(Java-Team)
  4. Lucene学习之——停用词
  5. soapui返回值类型都有哪些_法兰的类型都有哪些以及法兰的设计
  6. 《天天数学》连载05:一月五日
  7. php5.4 升级,centos上PHP5.3升级到PHP5.4及更高版本方法
  8. Flask + Vue 搭建简易系统步骤总结
  9. 李迟2022年4月工作生活总结
  10. U盘修复“系统找不到指定文件”问题解决方法
  11. Word 只读模式修改
  12. 【GitHub上传文件夹:bug】 ! [rejected] master - master (non-fast-forward)
  13. POJ 3373 模运算 + 折半枚举
  14. Excel中的LEN和LENB,VBA中的Len和LenB
  15. Java反射获取类,方法
  16. linux查看tomcat 控制台,linux 下查看Tomcat的状态,以及开启停止服务命令
  17. 开源Linux面板-1Panel
  18. 区块链技术的概念及作用
  19. Angluar WARNING System.import() is deprecated and will be removed soon. Use import() instead
  20. 爬虫实例:每日一文和豆瓣电影

热门文章

  1. 2021-1-28Linux学习纪要
  2. gvim 命令行粘贴_vim基本命令之剪切复制粘贴替换
  3. linux用megacli看raid信息,Linux中使用MegaCli工具查看、管理Raid卡信息
  4. css两张图片怎么合在一起_PhotoShop怎么把两张图片合成一张?怎么用ps把两张图片合成一张?...
  5. php中is upload,PHP中,文件上传
  6. jQuery特效:实现简易轮播图
  7. Javascript特效:瀑布流
  8. PM_我们是怎么做Code Review的
  9. 论文笔记_S2D.43_2018-CVPR_单张RGB-D图像的深度补全
  10. 从零开始搭二维激光SLAM --- Karto的后端优化与回环检测的实现解读