鱼C论坛

 找回密码
 立即注册
查看: 2928|回复: 0

[学习笔记] 内存修改

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

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

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

x
《Windows程序设计》 人民邮电出版社》 王艳平编著

小弟今天学习了一下这个第二章的最后一课,是一个类似于金山游侠的内存查找和修改的程序

还请大神们多多指教
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <tlhelp32.h>
  5. #include <stdbool.h>

  6. BOOL FindFirst(DWORD dwValue);
  7. BOOL FindNext(DWORD dwValue);
  8. DWORD g_arList[1024];// 地址列表
  9. int g_nListCnt;// 有效地址的个数
  10. HANDLE g_hProcess;// 目标进程句柄

  11. BOOL CompareAPage(DWORD dwBaseAddr, DWORD dwValue){
  12.         // 读取一页内存
  13.         BYTE arBytes[4096];
  14.         if (!ReadProcessMemory(g_hProcess, (LPVOID)dwBaseAddr, arBytes, 4096, NULL)){
  15.                 return FALSE;
  16.         }

  17.         DWORD *pdw;
  18.         for (int i = 0; i < (int)4 * 1024 - 3; i++){
  19.                 pdw = (DWORD*)&arBytes[i];
  20.                 if (pdw[0] == dwValue){
  21.                         if (g_nListCnt >= 1024){
  22.                                 return FALSE;
  23.                         }
  24.                         g_arList[g_nListCnt++] = dwBaseAddr + i;
  25.                 }
  26.         }
  27.         return TRUE;
  28. }

  29. BOOL FindFirst(DWORD dwValue){
  30.         const DWORD dwOneGB = 1024 * 1024 * 1024;
  31.         const DWORD dwOnePage = 4 * 1024;
  32.         if (g_hProcess == NULL){
  33.                 return FALSE;
  34.         }

  35.         DWORD dwBase;
  36.         OSVERSIONINFO vi = { sizeof(vi) };
  37.         GetVersionEx(&vi);
  38.         // Windows版本判断
  39.         if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS){
  40.                 dwBase = 4 * 1024 * 1024;// Windows 98系列,4MB
  41.         }
  42.         else{
  43.                 dwBase = 64 * 1024;// Windows NT系列 ,64KB
  44.         }

  45.         //在开始地址到2GB的地址空间进行查找
  46.         for (; dwBase < 2 * dwOneGB; dwBase += dwOnePage){
  47.                 CompareAPage(dwBase, dwValue);
  48.         }
  49.         return TRUE;
  50. }

  51. void ShowList(){
  52.         for (int i = 0; i < g_nListCnt; i++){
  53.                 printf("%08lX\n", g_arList[i]);
  54.         }
  55. }

  56. // 接下来的读取就是都在那个数组里面比较进程的内存地址了
  57. BOOL FindNext(DWORD dwValue){
  58.         int nOrgCnt = g_nListCnt;
  59.         g_nListCnt = 0;

  60.         BOOL bRet = FALSE;
  61.         DWORD dwReadValue;
  62.         for (int i = 0; i < nOrgCnt; i++){
  63.                 if (ReadProcessMemory(g_hProcess,
  64.                         (LPVOID)g_arList[i],
  65.                         &dwReadValue,
  66.                         sizeof(DWORD),
  67.                         NULL)){
  68.                         if (dwReadValue == dwValue){
  69.                                 g_arList[g_nListCnt++] = g_arList[i];// 每一次都是一层过滤
  70.                                 bRet = TRUE;
  71.                         }
  72.                 }
  73.         }
  74.         return bRet;
  75. }

  76. BOOL WriteMemory(DWORD dwAddr, DWORD dwValue){
  77.         return WriteProcessMemory(
  78.                 g_hProcess,
  79.                 (LPVOID)dwAddr,
  80.                 &dwValue,
  81.                 sizeof(DWORD),
  82.                 NULL);
  83. }




  84. int main(int argc, char* argv[]){
  85.         char *szCommandLine = "C://Users//pc//Desktop//testor.exe";
  86.         STARTUPINFO si = { sizeof(si) };
  87.         PROCESS_INFORMATION pi;
  88.         si.dwFlags = STARTF_USESHOWWINDOW;
  89.         si.wShowWindow = TRUE;
  90.         //创建进程
  91.         CreateProcess(
  92.                 NULL,
  93.                 szCommandLine,
  94.                 NULL,
  95.                 NULL,
  96.                 FALSE,
  97.                 CREATE_NEW_CONSOLE,
  98.                 NULL,
  99.                 NULL,
  100.                 &si,
  101.                 &pi);

  102.         CloseHandle(pi.hThread);//不用主线程的话关闭

  103.         g_hProcess = pi.hProcess;//进程

  104.         int iVal;
  105.         printf("Input val:");
  106.         scanf("%d", &iVal);
  107.         //进行第一次查找
  108.         FindFirst(iVal);

  109.         //打印出搜索结果
  110.         ShowList();
  111.         while (g_nListCnt > 1){
  112.                 printf("Input val = ");
  113.                 scanf("%d", &iVal);
  114.                 FindNext(iVal);
  115.                 ShowList();
  116.         }

  117.         printf("New value = ");
  118.         scanf("%d", &iVal);
  119.         if (WriteMemory(g_arList[0], iVal)){
  120.                 printf("Write data successfully\n");
  121.         }
  122.         CloseHandle(g_hProcess);
  123.         return 0;
  124. }
复制代码



下面这个是上面例子程序中的那个testor.exe程序
  1. #include <stdio.h>
  2. int g_nNum;
  3. int main(int argc, char* argv[]){
  4.         int i = 198;
  5.         g_nNum = 1003;
  6.         while (1){
  7.                 //输出变量的值和地址
  8.                 printf("i=%d,addr=%08lX       g_nNUm=%d,addr=%08lX\n", ++i, &i, --g_nNum, &g_nNum);
  9.                 getchar();
  10.         }
  11.         return 0;
  12. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-19 14:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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