• 内存理解之简单的内存修改器


    前段日子因为学习内存把王艳平老师的书看了一遍综合了其他书籍,简单学习做了一个内存修改器,下面是我觉得比较重要的知识,从书上抠了下来

    代码:

    类的形式写的代码:
    // HelloGame.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include"HelloGame.h"
    Game::Game(DWORD ProcessID)
    {
    m_GameCount = 0;
    IsOK = TRUE;
    ToAimProcessHandle = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION,
    FALSE, ProcessID);
    }
    Game::~Game()
    {
    if (ToAimProcessHandle!=NULL)
    {
    CloseHandle(ToAimProcessHandle);
    ToAimProcessHandle = NULL;
    }
    }
    BOOL Game::CompareAPage(DWORD BaseAddress, DWORD Value)//搜索内存
    {
    BYTE PageBytes[4096];
    BOOL IsOK;
    IsOK = ReadProcessMemory(ToAimProcessHandle, (LPVOID)BaseAddress, PageBytes, 4096, NULL);
    if (IsOK == FALSE)
    {
    return NULL;
    }
    DWORD *Buffer;
    for (int i = 0; i < 4 * 1024 - 3; i++)
    {
    Buffer = (DWORD*)&PageBytes[i];//这样才是地址的地址
    if (Buffer[0] == Value)
    {
    m_AddressList[m_GameCount++] = BaseAddress + i;//不懂??

    }

    }
    return TRUE;
    }

    BOOL Game:: FindFirst(DWORD Value)
    {
    const DWORD OneGB = 1024 * 1024 * 1024; // 1GB
    const DWORD OnePage = 4 * 1024; // 4KB

    if (ToAimProcessHandle == NULL)
    return FALSE;

    // 查看操作系统类型,以决定开始地址
    DWORD BaseAddress;
    OSVERSIONINFO vi = { sizeof(vi) };
    ::GetVersionEx(&vi);
    if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
    BaseAddress = 4 * 1024 * 1024; // Windows 98系列,4MB
    else
    BaseAddress = 640 * 1024; // Windows NT系列,64KB

    // 在开始地址到2GB的地址空间进行查找
    for (; BaseAddress < 2 * OneGB; BaseAddress += OnePage)
    {
    // 比较1页大小的内存
    CompareAPage(BaseAddress, Value);
    }
    IsOK = FALSE;
    return TRUE;
    }
    BOOL Game::FindNext(DWORD Value)
    {/*第二次不是从原先进程内存中查找所以直接是进行一个计数而已*/
    // 保存m_arList数组中有效地址的个数,初始化新的m_nListCnt值
    int Count = m_GameCount;//有效个数
    m_GameCount = 0;

    // 在m_arList数组记录的地址处查找
    BOOL IsOK = FALSE; // 假设失败
    DWORD ReadValue;
    for (int i = 0; i<Count; i++)
    {
    if (::ReadProcessMemory(ToAimProcessHandle, (LPVOID)m_AddressList[i], &ReadValue, sizeof(DWORD), NULL))
    {
    if (ReadValue == Value)
    {
    m_AddressList[m_GameCount++] = m_AddressList[i];
    IsOK = TRUE;
    }
    }
    }
    return TRUE;
    }
    BOOL Game::WriteMemory(DWORD Address, DWORD Value)
    {
    return WriteProcessMemory(ToAimProcessHandle, (LPVOID)Address, (LPCVOID)Value, sizeof(Value), NULL);
    }

    main函数中的代码:
    #include"HelloGame.h"
    #include<Windows.h>
    #include<iostream>

    using namespace std;
    Game GamePlay;
    DWORD m_AddressList[4096];
    ULONG GameListCount;
    HANDLE ProcessHandle;
    int main()
    {
    WCHAR FileName[] = L"..\debug\02testor.exe";
    STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    BOOL IsOK=CreateProcess(NULL, FileName, NULL, NULL, FALSE,
    CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
    if (IsOK == FALSE)
    {
    return NULL;
    }
    // 关闭线程句柄,既然我们不使用它
    ::CloseHandle(pi.hThread);
    GamePlay.ToAimProcessHandle = pi.hProcess;
    int ChangeValue;
    printf("输入改变的值");
    scanf("%d", &ChangeValue);
    GamePlay.FindFirst(ChangeValue);
    GamePlay.ShowData();

    while (GamePlay.m_GameCount > 1)
    {
    printf("二次查询:%d ");
    scanf("%d", &ChangeValue);

    // 进行下次搜索
    GamePlay.FindNext(ChangeValue);

    // 显示搜索结果
    GamePlay.ShowData();
    }
    }

  • 相关阅读:
    WinMain函数的修饰符WINAPI的含义
    java字节码指令集简介
    vs2010里面的ipch文件和.sdf文件是什么
    java查看class字节码文件
    从汇编看c++的extern关键字
    highcharts系列教程
    highcharts的文档介绍(英文)
    关于firebug中行号和源文件不一致的问题
    ios中的流状态的定义
    highcharts翻译系列
  • 原文地址:https://www.cnblogs.com/L-Sunny/p/8040532.html
Copyright © 2020-2023  润新知