《Windows程序设计》[第二版] - 第2章 Win32程序运行原理 - 其他进程内存修改器
1。测试程序
<textarea cols="50" rows="15" name="code" class="cpp">#include <stdio.h> int g_nNum; int main(int argc, char* argv[]) { int i = 198; g_nNum = 1003; while (1) { printf("i = %d, addr=%08lX;g_nNum=%d,add=%08lX/n", ++i, &i, --g_nNum,&g_nNum); getchar(); } return 0; }</textarea>
2。修改内存程序
CMemFinder类 查找内存、修改内存、打印地址表
2.1. CMemFinder类头文件 MemFinder.h
<textarea cols="50" rows="15" name="code" class="cpp">#pragma once #include <Windows.h> #include <stdio.h> class CMemFinder { public: CMemFinder(void); public: ~CMemFinder(void); public: BOOL IsFirst() const { return m_bFirst;} BOOL IsValid() const { return m_hProcess != NULL;} int GetListCount() const {return m_nListCnt;} DWORD operator[](int nIndex){return m_arList[nIndex];} virtual BOOL FindFirst(DWORD dwValue); virtual BOOL FindNext(DWORD dwValue); virtual BOOL WriteMemory(DWORD dwAddr, DWORD dwValue); void SetProcessHandle(HANDLE h){m_hProcess = h;}; void ShowList(); protected: virtual BOOL CompareAPage(DWORD dwBaseAddr, DWORD dwValue); DWORD m_arList[1024]; int m_nListCnt; HANDLE m_hProcess; BOOL m_bFirst; }; </textarea>
2.2. CMemFinder类实现文件 MemFinder.cpp
<textarea cols="50" rows="15" name="code" class="cpp">#include "MemFinder.h" CMemFinder::CMemFinder(void) { } CMemFinder::~CMemFinder(void) { } BOOL CMemFinder::FindFirst(DWORD dwValue) { const DWORD dwOneGB = 1024*1024*1024; const DWORD dwOnePage = 4*1024; if (m_hProcess == NULL) return FALSE; DWORD dwBase; OSVERSIONINFO vi = { sizeof(vi) }; ::GetVersionEx(&vi); if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) dwBase = 1024*1024*4; else dwBase = 1024*64; for (;dwBase<2*dwOneGB;dwBase+=dwOnePage) { CompareAPage(dwBase, dwValue); } return TRUE; } BOOL CMemFinder::FindNext(DWORD dwValue) { int nOrgCnt = m_nListCnt; m_nListCnt = 0; BOOL bRet = FALSE; DWORD dwReadValue; for(int i=0;i<nOrgCnt;i++) { if(::ReadProcessMemory(m_hProcess, (LPVOID)m_arList[i], &dwReadValue, sizeof(DWORD), NULL)) { if(dwReadValue == dwValue) { m_arList[m_nListCnt++] = m_arList[i]; bRet = TRUE; } } } return bRet; } BOOL CMemFinder::WriteMemory(DWORD dwAddr, DWORD dwValue) { return ::WriteProcessMemory(m_hProcess, (LPVOID)dwAddr, &dwValue, sizeof(DWORD), NULL); } BOOL CMemFinder::CompareAPage(DWORD dwBaseAddr, DWORD dwValue) { // 读取1页内存 BYTE arBytes[4096]; if (!::ReadProcessMemory(m_hProcess, (LPVOID)dwBaseAddr, arBytes, 4096, NULL)) { return FALSE; } DWORD* pdw; for(int i=0;i<(int)4096-3;i++) { pdw = (DWORD*)&arBytes[i]; if (pdw[0] == dwValue) { if (m_nListCnt >= 1024) { return FALSE; } m_arList[m_nListCnt++] = dwBaseAddr + i; } } } void CMemFinder::ShowList() { for(int i=0;i<m_nListCnt;i++) { printf("%3d: %08lX/n", i, m_arList[i]); } } </textarea>
2.3. Main函数文件
<textarea cols="50" rows="15" name="code" class="cpp">#include "MemFinder.h" #include <stdio.h> #include <iostream> using namespace std; int main(int argc, char* argv[]) { char szFileName[] = "D://Administrat//Visual Studio 2005//Projects//Memory//debug//Memory.exe"; STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; if(!::CreateProcess(NULL, szFileName, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, π)) { return -1; } ::CloseHandle(pi.hThread); CMemFinder memFinder; memFinder.SetProcessHandle(pi.hProcess); int iVal; int iControl; int nIndex; int iNewVal; toFirst: printf("/n1:ShowList/n2:FindFirst/n3:FindNext/n4:Wirte/n5:Exit/nInput Control="); scanf("%d", &iControl); if (iControl == 2) { printf("/nInput val="); scanf("%d", &iVal); if (memFinder.FindFirst(iVal)) { toSecond: printf("/n1:ShowList/n2:FindFirst/n3:FindNext/n4:Wirte/n5:Exit/nInput Control="); scanf("%d", &iControl); if (iControl == 2) { goto toFirst; }else if(iControl == 1){ memFinder.ShowList(); goto toSecond; }else if(iControl == 3){ printf("/nInput val="); scanf("%d", &iVal); memFinder.FindNext(iVal); goto toSecond; }else if(iControl == 4){ printf("/nInput Index="); scanf("%d", &nIndex); printf("/nInput New Value="); scanf("%d", &iNewVal); memFinder.WriteMemory(memFinder[nIndex], iNewVal); goto toSecond; }else{ goto toExit; } } }else if(iControl == 5){ goto toExit; }else{ goto toFirst; } toExit: ::CloseHandle(pi.hProcess); return 0; } </textarea>