• 修改程序内存中的值


    #include <stdio.h>
    #include <windows.h>
    #include <tlhelp32.h>//声明快照函数的头文件

    DWORD g_arList[1024]; //地址列表
    int g_nListCnt=0;    //有效地址个数
    HANDLE g_hProcess;   //目标进程句柄

    bool CompareAPage(DWORD dwBaseAddr,DWORD dwValue)
    {
    //读取一页内存
    BYTE arBytes[4096];
    if(!::ReadProcessMemory(g_hProcess,(LPVOID*)dwBaseAddr,&arBytes,4096,NULL))
       return FALSE; //此页不可读
    //在这1页内存中查找
    DWORD *pdw;
    int i=0;
    for(i=0;i<(int)4*1024-3;++i)
    {
       pdw = (DWORD*)&arBytes[i];
       //if(pdw[0] == dwValue)//等于要查找的值?
       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; //1GB
    const DWORD dwOnePage = 4*1024;    //4KB
    if(g_hProcess == NULL)
       return FALSE;
    //查看操作系统类型,以决定开始地址
    DWORD dwBase;
    OSVERSIONINFO vi = { sizeof(vi)};
    ::GetVersionEx(&vi);
    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)
    {
       //比较1页大小的内存
       CompareAPage(dwBase,dwValue);
    }
    return TRUE;
    }

    BOOL FindNext(DWORD dwValue)
    {
    //保存m_arList数组中有效地址的个数,初始化新的m_nListCnt值
    int nOrgCnt = g_nListCnt;
    g_nListCnt = 0;
    //在m_arList数组记录的地址处查找
    BOOL bRet = FALSE ;//假设失败
    DWORD dwReadValue;
    int i=0;
    for(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;
    }

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

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

    int main(int argc,char *argv[])
    {
    //启动testor进程
    char szFileName[] = "Testor\\Debug\\Testor.exe" ;
    STARTUPINFO si = {sizeof(si)};
    PROCESS_INFORMATION pi;
    ::CreateProcess(NULL,szFileName,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 success \n");

    ::CloseHandle(g_hProcess);
    return 0;
    }

    测试程序代码如下:

    #include <stdio.h>

    int g_nNum;

    int main(int argc,char *argv[])
    {
    int i = 198;
    g_nNum = 1003;
    while(1)
    {
       printf("i=%d , add=%08lX ;g_nNum=%d , add=%08lX ; \n",++i,&i,--g_nNum,&g_nNum);
       getchar();
    }
    return 0;
    }

    作者:BuildNewApp
    出处:http://syxchina.cnblogs.comBuildNewApp.com
    本文版权归作者、博客园和百度空间共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则作者会诅咒你的。
    如果您阅读了我的文章并觉得有价值请点击此处,谢谢您的肯定1。
  • 相关阅读:
    hibernate入门
    struts文件上传
    Struts的增删改查
    struts入门
    Maven配置以及环境搭配
    layui增删改查
    easyui三
    A
    C. Permutation Cycle
    E
  • 原文地址:https://www.cnblogs.com/syxchina/p/2197676.html
Copyright © 2020-2023  润新知