溯影 发表于 2018-4-24 19:58:13

内存修改

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

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

还请大神们多多指教
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
#include <stdbool.h>

BOOL FindFirst(DWORD dwValue);
BOOL FindNext(DWORD dwValue);
DWORD g_arList;// 地址列表
int g_nListCnt;// 有效地址的个数
HANDLE g_hProcess;// 目标进程句柄

BOOL CompareAPage(DWORD dwBaseAddr, DWORD dwValue){
        // 读取一页内存
        BYTE arBytes;
        if (!ReadProcessMemory(g_hProcess, (LPVOID)dwBaseAddr, arBytes, 4096, NULL)){
                return FALSE;
        }

        DWORD *pdw;
        for (int i = 0; i < (int)4 * 1024 - 3; i++){
                pdw = (DWORD*)&arBytes;
                if (pdw == dwValue){
                        if (g_nListCnt >= 1024){
                                return FALSE;
                        }
                        g_arList = dwBaseAddr + i;
                }
        }
        return TRUE;
}

BOOL FindFirst(DWORD dwValue){
        const DWORD dwOneGB = 1024 * 1024 * 1024;
        const DWORD dwOnePage = 4 * 1024;
        if (g_hProcess == NULL){
                return FALSE;
        }

        DWORD dwBase;
        OSVERSIONINFO vi = { sizeof(vi) };
        GetVersionEx(&vi);
        // Windows版本判断
        if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS){
                dwBase = 4 * 1024 * 1024;// Windows 98系列,4MB
        }
        else{
                dwBase = 64 * 1024;// Windows NT系列 ,64KB
        }

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

void ShowList(){
        for (int i = 0; i < g_nListCnt; i++){
                printf("%08lX\n", g_arList);
        }
}

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

        BOOL bRet = FALSE;
        DWORD dwReadValue;
        for (int i = 0; i < nOrgCnt; i++){
                if (ReadProcessMemory(g_hProcess,
                        (LPVOID)g_arList,
                        &dwReadValue,
                        sizeof(DWORD),
                        NULL)){
                        if (dwReadValue == dwValue){
                                g_arList = g_arList;// 每一次都是一层过滤
                                bRet = TRUE;
                        }
                }
        }
        return bRet;
}

BOOL WriteMemory(DWORD dwAddr, DWORD dwValue){
        return WriteProcessMemory(
                g_hProcess,
                (LPVOID)dwAddr,
                &dwValue,
                sizeof(DWORD),
                NULL);
}




int main(int argc, char* argv[]){
        char *szCommandLine = "C://Users//pc//Desktop//testor.exe";
        STARTUPINFO si = { sizeof(si) };
        PROCESS_INFORMATION pi;
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = TRUE;
        //创建进程
        CreateProcess(
                NULL,
                szCommandLine,
                NULL,
                NULL,
                FALSE,
                CREATE_NEW_CONSOLE,
                NULL,
                NULL,
                &si,
                &pi);

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

        g_hProcess = pi.hProcess;//进程

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

        //打印出搜索结果
        ShowList();
        while (g_nListCnt > 1){
                printf("Input val = ");
                scanf("%d", &iVal);
                FindNext(iVal);
                ShowList();
        }

        printf("New value = ");
        scanf("%d", &iVal);
        if (WriteMemory(g_arList, iVal)){
                printf("Write data successfully\n");
        }
        CloseHandle(g_hProcess);
        return 0;
}



下面这个是上面例子程序中的那个testor.exe程序
#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,addr=%08lX\n", ++i, &i, --g_nNum, &g_nNum);
                getchar();
        }
        return 0;
}
页: [1]
查看完整版本: 内存修改