美文网首页Windows程序设计
API函数写控制台修改内存(最Low)

API函数写控制台修改内存(最Low)

作者: 半数的年 | 来源:发表于2018-03-13 22:09 被阅读0次

    左边程序修改右边程序内存,通过API函数先读内存取得g_nNum(右边程序全局变量),然后修改;

    先贴右边程序代码

    #include <stdio.h>

    int g_nNum; // 全局变量测试

    int main(int argc, char* argv[])

    {

    int i=198; // 局部变量测试

    g_nNum=1003;

    while(1){

    //输出每个变量的值和地址

    printf("i=%d,addr=0x%0x; g_nNum=%d,addr=0x%0x\n",++i,&i,--g_nNum,&g_nNum);

    getchar();

    }

    return 0;

    }

    左边程序代码

    // MemRepair.cpp : Defines the entry point for the console application.//

    #include "stdafx.h"

    #include <windows.h>

    #include <stdio.h>

    BOOL FindFirst(DWORD dwValue); // 在目标进程空间进行第一次查找

    BOOL FindNext(DWORD dwValue); // 在目标进程空间进行第2,3,4....此查找

    BOOL CompareAPage(DWORD dwBaseAddr,DWORD dwValue); // 查找一页4KB的内存 符合存入地址列表

    void ShowList(); //打印搜索到的地址

    BOOL WriteMemory(DWORD dwAddr,DWORD dwValue);

    DWORD g_arList[1024]; // 地址列表

    int g_nListCnt; // 有效地址的个数

    HANDLE g_hProcess; // 目标进程句柄

    int main(int argc, char* argv[])

    {

    // 启动MemRepairTestor进程

    char szFileName[]="..\\MemRepairTestor\\debug\\MemRepairTestor.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;

    }

    BOOL CompareAPage(DWORD dwBaseAddr,DWORD dwValue)

    {

    // 读取1页内存

    BYTE arBytes[4096];

    if(!::ReadProcessMemory(g_hProcess,(LPVOID)dwBaseAddr,arBytes,4096,NULL))

    return FALSE; // 此页不可读

    // 在这1页内存中查找

    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;

    }

    }

    }

    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; //Window98系列,4MB

    else

    dwBase=64*1024; //WindowNT系列,64KB

    // 在开始地址到2GB的地址空间进行查找

    for(;dwBase<2*dwOneGB;dwBase+=dwOnePage){

    // 比较1页大小的内存

    CompareAPage(dwBase,dwValue);

    }

    return TRUE;

    }

    void ShowList()

    {

    for(int i=0;i<g_nListCnt;i++){

    printf("0x%0x\n",g_arList[i]);

    }

    }

    BOOL FindNext(DWORD dwValue)

    {

    // 保存m_arList数组中有效地址的个数,初始化新的m_nListCnt值

    int nOrgCnt=g_nListCnt;

    g_nListCnt=0;

    // 在m_arList数组记录的地址处查找

    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);

    }

    相关文章

      网友评论

        本文标题:API函数写控制台修改内存(最Low)

        本文链接:https://www.haomeiwen.com/subject/zvntqftx.html