鱼C论坛

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

[学习笔记] 内存修改

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

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

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

x
《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[1024];// 地址列表
int g_nListCnt;// 有效地址的个数
HANDLE g_hProcess;// 目标进程句柄

BOOL CompareAPage(DWORD dwBaseAddr, DWORD dwValue){
        // 读取一页内存
        BYTE arBytes[4096];
        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[i];
                if (pdw[0] == dwValue){
                        if (g_nListCnt >= 1024){
                                return FALSE;
                        }
                        g_arList[g_nListCnt++] = 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[i]);
        }
}

// 接下来的读取就是都在那个数组里面比较进程的内存地址了
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[i],
                        &dwReadValue,
                        sizeof(DWORD),
                        NULL)){
                        if (dwReadValue == dwValue){
                                g_arList[g_nListCnt++] = g_arList[i];// 每一次都是一层过滤
                                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[0], 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;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-23 21:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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