游戏内存修改器

CMemScanner.h(内存扫描器类):

#ifndef CMEMSCANNER_H
#define  CMEMSCANNER_H

#include 
< stdio.h >
#include 
" AddrList.h "
#include 
" PageList.h "

class  CMemScanner   // 内存扫描器类
{
private :
    HANDLE m_hProcess;  
// 待扫描进程句柄
public :
    CAddrList 
*  m_lpAddrList;   // 地址列表对象指针
private :
    BOOL EnableDebugPrivilege();  
// 提升应用程序权限,使能调试特权函数
    BOOL GetScanRegion(CPageList  *  lpPageList);   // 获取扫描范围
public :
    CMemScanner();  
// 类构造函数
     ~ CMemScanner();   // 类析构函数
    BOOL SetProcessForScanner(DWORD dwProcessId);   // 设置欲扫描的进程
    BOOL ScanFirst(DWORD dwValue);   // 第一次扫描函数
    BOOL ScanNext(DWORD dwValue);   // 下一次扫描函数
    BOOL WriteMemory(DWORD dwAddr, DWORD dwValue);   // 修改内存函数
    BOOL ReadMemory(DWORD dwAddr,DWORD  *  lpValue);   // 读取内存函数
};

#endif

 CMemScanner.cpp:

#include  " stdafx.h "
#include 
" MemScanner.h "

// 类构造函数
CMemScanner::CMemScanner()
{
    m_hProcess 
=  NULL;   // 初始化类成员变量
    m_lpAddrList  =  NULL;
    EnableDebugPrivilege();  
// 提升应用程序权限,使拥有调试特权
}

// 类析构函数
CMemScanner:: ~ CMemScanner()
{
    
if (m_hProcess)
        ::CloseHandle(m_hProcess);
    
if (m_lpAddrList)
        delete m_lpAddrList;
}

// 设置欲扫描的进程
BOOL CMemScanner::SetProcessForScanner(DWORD dwProcessId)
{
    
if (m_hProcess)
        ::CloseHandle(m_hProcess);
    
    m_hProcess 
=  ::OpenProcess(PROCESS_QUERY_INFORMATION  |  PROCESS_VM_READ  |  PROCESS_VM_WRITE  |  PROCESS_VM_OPERATION, FALSE, dwProcessId);   // 打开欲扫描进程句柄
    
// m_hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);   // 打开欲扫描进程句柄
     if (m_hProcess)   // OpenProcess函数调用失败返回值为零
         return  TRUE;
    
else   
        
return  FALSE;
}
    
// 第一次扫描函数
BOOL CMemScanner::ScanFirst(DWORD dwValue)
{
    CPageList 
*  lpPageList  =  NULL;
    CAddrList 
*  lpAddrList  =  NULL;
    
int  i,j;
    
char   *  lpBuf  =  NULL;
    MEMORY_BASIC_INFORMATION stMemInfo  
=  { 0 };

    
if ( ! m_hProcess)
        
return  FALSE;

    lpPageList 
=   new  CPageList( 100 );   // 构造一个页面列表对象,初始大小或步进值为100个DWORD
     if ( ! GetScanRegion(lpPageList))   // 获取扫描范围
         return  FALSE;
    
    lpAddrList 
=   new  CAddrList( 100 );   // 构造一个地址列表对象,初始大小或步进值为100个DWORD
    
    
for (i  =   0 ; i  <  lpPageList  -> m_nPageListCnt; i ++ )   // 循环扫描已提交页面
    {
        lpBuf 
=   new   char [lpPageList  -> m_lpPageSizeList[i]];
        
if ( ! ::ReadProcessMemory(m_hProcess,(LPCVOID)(lpPageList  -> m_lpPageBaseAddrList[i]),lpBuf,lpPageList  -> m_lpPageSizeList[i],NULL))   // 读取已提交的一块内存,失败返回零
        {
            
if (lpPageList)
                delete lpPageList;
            
return  FALSE;
        }
        
        
for (j  =   0 ; j  <  lpPageList  -> m_lpPageSizeList[i]  -   3 ; j ++ )   // 逐个比较这一块已提交的内存
        {
            
if (dwValue  ==   * (DWORD  * )(lpBuf  +  j))   // 等于要扫描的值
                lpAddrList  -> AddToAddrList((DWORD)(lpPageList  -> m_lpPageBaseAddrList[i]  +  j));   // 添加数据到地址列表
        }
        
        
if (lpBuf)
            delete lpBuf;
    }
    
if (m_lpAddrList)   // 删除原地址列表
        delete m_lpAddrList;
    m_lpAddrList 
=  lpAddrList;   // 保存新地址列表
     if (lpPageList)   // 删除页面列表
        delete lpPageList;
    
return  TRUE;
}

// 下一次扫描函数
BOOL CMemScanner::ScanNext(DWORD dwValue)
{
    CAddrList 
*  lpAddrList  =  NULL;
    DWORD dwBuf 
=   0 ;
    
int  i;

    
if ( ! m_hProcess)
        
return  FALSE;

    lpAddrList 
=   new  CAddrList( 100 );   // 构造一个地址列表对象,初始大小或步进值为100个DWORD

    
for (i  =   0 ; i  <  m_lpAddrList  -> m_nAddrListCnt; i ++ )
    {
        
if ( ! ::ReadProcessMemory(m_hProcess,(LPCVOID)(m_lpAddrList  -> m_lpAddrList[i]), & dwBuf, sizeof  dwBuf,NULL))
        {
            
if (lpAddrList)
                delete lpAddrList;
            
return  FALSE;
        }

        
if (dwValue  ==  dwBuf)   // 等于要扫描的值
            lpAddrList  -> AddToAddrList(m_lpAddrList  -> m_lpAddrList[i]);   // 添加数据到地址列表
    }
    
    
if (m_lpAddrList)   // 删除原地址列表
        delete m_lpAddrList;
    m_lpAddrList 
=  lpAddrList;   // 保存新地址列表
     return  TRUE;
}

// 修改内存函数
BOOL CMemScanner::WriteMemory(DWORD dwAddr, DWORD dwValue)
{
    DWORD dwOldProtect;
    MEMORY_BASIC_INFORMATION stMemInfo  
=  { 0 };

    
if ( ! m_hProcess)
        
return  FALSE;

    
if ( ! ::VirtualQueryEx(m_hProcess,(LPCVOID)dwAddr, & stMemInfo, sizeof (stMemInfo)))
        
return  FALSE;
    
if ( ! ::VirtualProtectEx(m_hProcess,(LPVOID)dwAddr, sizeof (DWORD),PAGE_READWRITE, & dwOldProtect))
        
return  FALSE;
    
    
if (::WriteProcessMemory(m_hProcess,(LPVOID)dwAddr, & dwValue, sizeof (DWORD), NULL))
    {
        ::VirtualProtectEx(m_hProcess,(LPVOID)dwAddr,
sizeof (DWORD),dwOldProtect, 0 );
        
return  TRUE;
    }
    
else
    {
        ::VirtualProtectEx(m_hProcess,(LPVOID)dwAddr,
sizeof (DWORD),dwOldProtect, 0 );
        
return  FALSE;
    }
}

// 读取内存函数
BOOL CMemScanner::ReadMemory(DWORD dwAddr,DWORD  *  lpValue)
{
    
if ( ! m_hProcess)
        
return  FALSE;

    
return  ::ReadProcessMemory(m_hProcess,(LPVOID)dwAddr,lpValue, sizeof (DWORD), 0 );
}

// 提升应用程序权限,使能调试特权函数
BOOL CMemScanner::EnableDebugPrivilege()
{
    HANDLE hProcess 
=  NULL;
    HANDLE hToken 
=  NULL;
    LUID uID 
=  { 0 };
    TOKEN_PRIVILEGES stToken_Privileges 
=  { 0 };

    hProcess 
=  ::GetCurrentProcess();   // 获取当前应用程序进程句柄
    
    
if ( ! ::OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES, & hToken))   // 打开当前进程的访问令牌句柄(OpenProcessToken函数调用失败返回值为零)
         return  FALSE;

    
if ( ! ::LookupPrivilegeValue(NULL,SE_DEBUG_NAME, & uID))   // 获取权限名称为"SetDebugPrivilege"的LUID(LookupPrivilegeValue函数调用失败返回值为零)
         return  FALSE;

    stToken_Privileges.PrivilegeCount 
=   1 ;   // 欲调整的权限个数
    stToken_Privileges.Privileges[ 0 ].Luid  =  uID;   // 权限的LUID
    stToken_Privileges.Privileges[ 0 ].Attributes  =  SE_PRIVILEGE_ENABLED;   // 权限的属性,SE_PRIVILEGE_ENABLED为使能该权限
    
    
if ( ! ::AdjustTokenPrivileges(hToken,FALSE, & stToken_Privileges, sizeof  stToken_Privileges,NULL,NULL))   // 调整访问令牌里的指定权限(AdjustTokenPrivileges函数调用失败返回值为零)
         return  FALSE;

    
if (::GetLastError()  !=  ERROR_SUCCESS)   // 查看权限是否调整成功
         return  FALSE;

    ::CloseHandle(hToken);
    
return  TRUE;
}

// 获取扫描范围
BOOL CMemScanner::GetScanRegion(CPageList  *  lpPageList)
{
    SYSTEM_INFO stSysInfo 
=  { 0 };
    
int  nAppStartAddr  =   0 ,nAppEndAddr  =   0 ;
    MEMORY_BASIC_INFORMATION stMemInfo  
=  { 0 };
    
int  i;

    ::GetSystemInfo(
& stSysInfo);
    nAppStartAddr 
=  ( int )stSysInfo.lpMinimumApplicationAddress;   // 应用程序私有地址空间的起始地址
    nAppEndAddr  =  ( int )stSysInfo.lpMaximumApplicationAddress;   // 应用程序私有地址空间的终止地址
    
    
for (i  =  nAppStartAddr; i  <  nAppEndAddr;)
    {
        
if ( ! ::VirtualQueryEx(m_hProcess,(LPCVOID)i, & stMemInfo, sizeof (stMemInfo)))   // 查询基地址从i开始的页面的属性
             return  FALSE;

        
if (stMemInfo.State  ==  MEM_COMMIT)   // 该页面是已提交的并且属性是可读写和可执行的
             if (stMemInfo.Protect  ==  PAGE_READWRITE  ||  stMemInfo.Protect  ==  PAGE_EXECUTE_READWRITE)
                lpPageList 
-> AddToPageList((DWORD)stMemInfo.BaseAddress,(DWORD)stMemInfo.RegionSize);   // 添加数据到页面列表
        
        i 
=  i  +  stMemInfo.RegionSize;   // 跳到下一个页面基址
    }
    
return  TRUE;
}

AddrList.h(地址列表类):

#ifndef CADDRLIST_H
#define  CADDRLIST_H

#include 
< windows.h >

class  CAddrList
{
private :
    
int  m_nAddrListMaxCnt;   // 地址列表最大计数
     int  m_nStep;   // 调用realloc时相对原列表空间大小的步进值
public :
    DWORD 
*  m_lpAddrList;   // 地址列表指针
     int  m_nAddrListCnt;   // 地址列表计数
public :
    CAddrList(
int  nStep);   // 类构造函数
     ~ CAddrList();   // 类析构函数
     void  AddToAddrList(DWORD dwAddr);   // 添加数据到地址列表
};

#endif

AddrList.cpp

#include  " stdafx.h "
#include 
" AddrList.h "

// 类构造函数
CAddrList::CAddrList( int  nStep)
{
    m_nAddrListCnt 
=   0 ;
    m_nStep 
=  nStep;
    m_nAddrListMaxCnt 
=  nStep;
    m_lpAddrList 
=  (DWORD  * )malloc(m_nAddrListMaxCnt  *   sizeof (DWORD));
}

// 类析构函数
CAddrList:: ~ CAddrList()
{
    
if (m_lpAddrList)
        free(m_lpAddrList);
}

// 添加数据到地址列表
void  CAddrList::AddToAddrList(DWORD dwAddr)
{
    
if (m_nAddrListMaxCnt  <=  m_nAddrListCnt)
    {
        m_nAddrListMaxCnt 
=  m_nAddrListMaxCnt  +  m_nStep;
        m_lpAddrList 
=  (DWORD  * )realloc(m_lpAddrList,m_nAddrListMaxCnt   *   sizeof (DWORD));
    }
    m_lpAddrList[m_nAddrListCnt] 
=  dwAddr;
    m_nAddrListCnt
++ ;
}

PageList.h(页面列表类):

#ifndef CPAGELIST_H
#define  CPAGELIST_H

#include 
< windows.h >

class  CPageList   // 页面列表类
{
private :
    
int  m_nPageListMaxCnt;   // 页面列表最大计数(以上两个列表的计数,相同)
     int  m_nStep;   // 每次realloc时相对原来空间大小的步进值
public :
    DWORD 
*  m_lpPageBaseAddrList;   // 页面基址列表指针
    DWORD  *  m_lpPageSizeList;   // 页面大小列表指针
     int  m_nPageListCnt;   // 页面列表计数(以上两个列表的计数,相同)
public :
    CPageList(
int  nStep);   // 类构造函数
     ~ CPageList();   // 类析构函数
     void  AddToPageList(DWORD dwPageBaseAddr,DWORD dwPageSize);   // 添加数据到页面列表
};

#endif

PageList..cpp

#include  " stdafx.h "
#include 
" PageList.h "

// 类构造函数
CPageList::CPageList( int  nStep)
{
    m_nPageListCnt 
=   0 ;
    m_nStep 
=  nStep;
    m_nPageListMaxCnt 
=  nStep;
    m_lpPageBaseAddrList 
=  (DWORD  * )malloc(m_nPageListMaxCnt  *   sizeof (DWORD));
    m_lpPageSizeList 
=  (DWORD  * )malloc(m_nPageListMaxCnt  *   sizeof (DWORD));
}

// 类析构函数
CPageList:: ~ CPageList()
{
    
if (m_lpPageBaseAddrList)
        free(m_lpPageBaseAddrList);
    
if (m_lpPageSizeList)
        free(m_lpPageSizeList);
}

// 添加数据到页面列表
void  CPageList::AddToPageList(DWORD dwPageBaseAddr,DWORD dwPageSize)
{
    
if (m_nPageListMaxCnt  <=  m_nPageListCnt)
    {
        m_nPageListMaxCnt 
=  m_nPageListMaxCnt  +  m_nStep;
        m_lpPageBaseAddrList 
=  (DWORD  * )realloc(m_lpPageBaseAddrList,m_nPageListMaxCnt  *   sizeof (DWORD));
        m_lpPageSizeList 
=  (DWORD  * )realloc(m_lpPageSizeList,m_nPageListMaxCnt  *   sizeof (DWORD));
    }
    
// char Buf[128] = {0};
    
// sprintf(Buf,"总%d,当%d",m_nPageListMaxCnt,m_nPageListCnt);
    
// MessageBox(NULL,Buf,"222",0);
    m_lpPageBaseAddrList[m_nPageListCnt]  =  dwPageBaseAddr;   // 该页面的基址
    m_lpPageSizeList[m_nPageListCnt]  =  dwPageSize;   // 该页的大小
    m_nPageListCnt ++ ;
}

GameEditor.h(应用程序类)

//  GameEditor.h : main header file for the GAMEEDITOR application
//

#if  !defined(AFX_GAMEEDITOR_H__AC0A553E_7E31_49B9_BA63_FF72A2CE15F8__INCLUDED_)
#define  AFX_GAMEEDITOR_H__AC0A553E_7E31_49B9_BA63_FF72A2CE15F8__INCLUDED_

#if  _MSC_VER > 1000
#pragma  once
#endif   //  _MSC_VER > 1000

#ifndef __AFXWIN_H__
    
#error  include 'stdafx.h' before including this file for PCH
#endif

#include 
" resource.h "          //  main symbols

/// //
//  CGameEditorApp:
//  See GameEditor.cpp for the implementation of this class
//

class  CGameEditorApp :  public  CWinApp
{
public :
    CGameEditorApp();

//  Overrides
    
//  ClassWizard generated virtual function overrides
    
// {{AFX_VIRTUAL(CGameEditorApp)
     public :
    
virtual  BOOL InitInstance();
    
// }}AFX_VIRTUAL

//  Implementation

    
// {{AFX_MSG(CGameEditorApp)
        
//  NOTE - the ClassWizard will add and remove member functions here.
        
//     DO NOT EDIT what you see in these blocks of generated code !
    
// }}AFX_MSG
    DECLARE_MESSAGE_MAP()
};


/// //

// {{AFX_INSERT_LOCATION}}
//  Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif   //  !defined(AFX_GAMEEDITOR_H__AC0A553E_7E31_49B9_BA63_FF72A2CE15F8__INCLUDED_)

GameEditor.cpp

//  GameEditor.cpp : Defines the class behaviors for the application.
//

#include 
" stdafx.h "
#include 
" GameEditor.h "
#include 
" GameEditorDlg.h "

#ifdef _DEBUG
#define  new DEBUG_NEW
#undef  THIS_FILE
static   char  THIS_FILE[]  =  __FILE__;
#endif

/// //
//  CGameEditorApp

BEGIN_MESSAGE_MAP(CGameEditorApp, CWinApp)
    
// {{AFX_MSG_MAP(CGameEditorApp)
        
//  NOTE - the ClassWizard will add and remove mapping macros here.
        
//     DO NOT EDIT what you see in these blocks of generated code!
    
// }}AFX_MSG
    ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/// //
//  CGameEditorApp construction

CGameEditorApp::CGameEditorApp()
{
    
//  TODO: add construction code here,
    
//  Place all significant initialization in InitInstance
}

/// //
//  The one and only CGameEditorApp object

CGameEditorApp theApp;

/// //
//  CGameEditorApp initialization

BOOL CGameEditorApp::InitInstance()
{
    AfxEnableControlContainer();

    
//  Standard initialization
    
//  If you are not using these features and wish to reduce the size
    
//   of your final executable, you should remove from the following
    
//   the specific initialization routines you do not need.

#ifdef _AFXDLL
    Enable3dControls();            
//  Call this when using MFC in a shared DLL
#else
    Enable3dControlsStatic();    
//  Call this when linking to MFC statically
#endif

    CGameEditorDlg dlg;
    m_pMainWnd 
=   & dlg;
    
int  nResponse  =  dlg.DoModal();
    
if  (nResponse  ==  IDOK)
    {
        
//  TODO: Place code here to handle when the dialog is
        
//   dismissed with OK
    }
    
else   if  (nResponse  ==  IDCANCEL)
    {
        
//  TODO: Place code here to handle when the dialog is
        
//   dismissed with Cancel
    }

    
//  Since the dialog has been closed, return FALSE so that we exit the
    
//   application, rather than start the application's message pump.
     return  FALSE;
}

GameEditorDlg.h(主对话框类)

//  GameEditorDlg.h : header file
//

#if  !defined(AFX_GAMEEDITORDLG_H__457F57F1_F4EA_4B2B_BA4C_3220F297B11F__INCLUDED_)
#define  AFX_GAMEEDITORDLG_H__457F57F1_F4EA_4B2B_BA4C_3220F297B11F__INCLUDED_

#if  _MSC_VER > 1000
#pragma  once
#endif   //  _MSC_VER > 1000

/// //
//  CGameEditorDlg dialog
#include  " MemScanner.h "    // 包含内存扫描器类头文件

class  CGameEditorDlg :  public  CDialog
{
//  Construction
public :
    CGameEditorDlg(CWnd
*  pParent  =  NULL);     //  standard constructor

public :
    
void  UpdataProcessList();   // 更新进程列表函数
     void  UpdataAddrList();   // 更新地址列表函数

//  Dialog Data
    
// {{AFX_DATA(CGameEditorDlg)
     enum  { IDD  =  IDD_GAMEEDITOR_DIALOG };
    CListCtrl    m_clsAddrList;
    CListCtrl    m_clsProcessList;
    
// }}AFX_DATA

    
//  ClassWizard generated virtual function overrides
    
// {{AFX_VIRTUAL(CGameEditorDlg)
     public :
    
virtual  BOOL PreTranslateMessage(MSG *  pMsg);
    
protected :
    
virtual   void  DoDataExchange(CDataExchange *  pDX);     //  DDX/DDV support
    
// }}AFX_VIRTUAL

//  Implementation
protected :
    HICON m_hIcon;
    BOOL m_bFirst;  
// 是否是第一次搜索标志
public :
    CMemScanner m_clsMemScanner;  
// 内存扫描器对象

    
//  Generated message map functions
    
// {{AFX_MSG(CGameEditorDlg)
     virtual  BOOL OnInitDialog();
    afx_msg 
void  OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg 
void  OnSearch();
    afx_msg 
void  OnDblclkProcesslist(NMHDR *  pNMHDR, LRESULT *  pResult);
    afx_msg 
void  OnReset();
    afx_msg 
void  OnDblclkAddrlist(NMHDR *  pNMHDR, LRESULT *  pResult);
    
// }}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

// {{AFX_INSERT_LOCATION}}
//  Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif   //  !defined(AFX_GAMEEDITORDLG_H__457F57F1_F4EA_4B2B_BA4C_3220F297B11F__INCLUDED_)

GameEditorDlg.cpp

//  GameEditorDlg.cpp : implementation file
//

#include 
" stdafx.h "
#include 
" GameEditor.h "
#include 
" GameEditorDlg.h "
#include 
< tlhelp32.h >

#ifdef _DEBUG
#define  new DEBUG_NEW
#undef  THIS_FILE
static   char  THIS_FILE[]  =  __FILE__;
#endif

/// //
//  CGameEditorDlg dialog
#include  " ModifyDlg.h "    //

CGameEditorDlg::CGameEditorDlg(CWnd
*  pParent  /* =NULL */ )
    : CDialog(CGameEditorDlg::IDD, pParent)
{
    
// {{AFX_DATA_INIT(CGameEditorDlg)
        
//  NOTE: the ClassWizard will add member initialization here
    
// }}AFX_DATA_INIT
    
//  Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon  =  AfxGetApp() -> LoadIcon(IDR_MAINFRAME);
}

void  CGameEditorDlg::DoDataExchange(CDataExchange *  pDX)
{
    CDialog::DoDataExchange(pDX);
    
// {{AFX_DATA_MAP(CGameEditorDlg)
    DDX_Control(pDX, IDL_ADDRLIST, m_clsAddrList);
    DDX_Control(pDX, IDL_PROCESSLIST, m_clsProcessList);
    
// }}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CGameEditorDlg, CDialog)
    
// {{AFX_MSG_MAP(CGameEditorDlg)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDB_SEARCH, OnSearch)
    ON_NOTIFY(NM_DBLCLK, IDL_PROCESSLIST, OnDblclkProcesslist)
    ON_BN_CLICKED(IDB_RESET, OnReset)
    ON_NOTIFY(NM_DBLCLK, IDL_ADDRLIST, OnDblclkAddrlist)
    
// }}AFX_MSG_MAP
END_MESSAGE_MAP()

/// //
//  CGameEditorDlg message handlers

BOOL CGameEditorDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    
//  Set the icon for this dialog.  The framework does this automatically
    
//   when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);             //  Set big icon
    SetIcon(m_hIcon, FALSE);         //  Set small icon
    
    
//  TODO: Add extra initialization here
    DWORD dwStyle;

    m_clsProcessList.InsertColumn(
0 , " Name " ,LVCFMT_IMAGE  |  LVCFMT_LEFT, 120 );   // 初始化进程列表框控件
    m_clsProcessList.InsertColumn( 1 , " PID " ,LVCFMT_CENTER, 50 );

    dwStyle 
=  m_clsProcessList.GetExtendedStyle();
    dwStyle 
=  dwStyle  |  LVS_EX_FULLROWSELECT  |  LVS_EX_GRIDLINES;   // 设置选择一整行和高亮显示选择行的扩展风格
    m_clsProcessList.SetExtendedStyle(dwStyle);

    m_clsAddrList.InsertColumn(
0 , " 序号 " ,LVCFMT_CENTER, 80 );   // 初始化地址列表框控件
    m_clsAddrList.InsertColumn( 1 , " 地址 " ,LVCFMT_CENTER, 120 );
    m_clsAddrList.InsertColumn(
2 , " 当前值 " ,LVCFMT_CENTER, 130 );

    dwStyle 
=  m_clsAddrList.GetExtendedStyle();
    dwStyle 
=  dwStyle  |  LVS_EX_FULLROWSELECT  |  LVS_EX_GRIDLINES;   // 设置选择一整行和高亮显示选择行的扩展风格
    m_clsAddrList.SetExtendedStyle(dwStyle);

    m_bFirst 
=  TRUE;
    UpdataProcessList();  
// 更新进程列表
     return  TRUE;   //  return TRUE  unless you set the focus to a control
}

//  If you add a minimize button to your dialog, you will need the code below
//   to draw the icon.  For MFC applications using the document/view model,
//   this is automatically done for you by the framework.

void  CGameEditorDlg::OnPaint() 
{
    
if  (IsIconic())
    {
        CPaintDC dc(
this );  //  device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 
0 );

        
//  Center icon in client rectangle
         int  cxIcon  =  GetSystemMetrics(SM_CXICON);
        
int  cyIcon  =  GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(
& rect);
        
int  x  =  (rect.Width()  -  cxIcon  +   1 /   2 ;
        
int  y  =  (rect.Height()  -  cyIcon  +   1 /   2 ;

        
//  Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    
else
    {
        CDialog::OnPaint();
    }
}

//  The system calls this to obtain the cursor to display while the user drags
//   the minimized window.
HCURSOR CGameEditorDlg::OnQueryDragIcon()
{
    
return  (HCURSOR) m_hIcon;
}

void  CGameEditorDlg::OnSearch()   // 搜索按钮单击事件处理过程
{
    
//  TODO: Add your control notification handler code here
    DWORD dwProcessId,dwValue;
    CString strTip;

    
if (GetDlgItem(IDE_PID)  -> GetWindowTextLength()  <=   0 )
    {
        MessageBox(
" 请双击进程列表框选择一个目标进程! " );
        
return ;
    }

    
if (GetDlgItem(IDE_SEARCH)  -> GetWindowTextLength()  <=   0 )
    {
        MessageBox(
" 请输入一个搜索值! " );
        GetDlgItem(IDE_SEARCH) 
-> SetFocus();
        
return ;
    }

    dwProcessId 
=  GetDlgItemInt(IDE_PID);   // 获取进程ID文本框的值
    dwValue  =  GetDlgItemInt(IDE_SEARCH);   // 获取用户输入搜索文本框的值

    
if (m_bFirst)   // 第一次搜索
    {
        
if ( ! m_clsMemScanner.SetProcessForScanner(dwProcessId))
        {
            MessageBox(
" 打开目标进程时失败! " );
            
return ;
        }
        m_clsMemScanner.ScanFirst(dwValue);
        
if (m_clsMemScanner.m_lpAddrList  -> m_nAddrListCnt)
            m_bFirst 
=  FALSE;
    }
    
else
    {
        m_clsMemScanner.ScanNext(dwValue);
    }
    UpdataAddrList();  
// 更新地址列表
    
    strTip.Format(
" 总共搜索到%d个结果! " ,(m_clsMemScanner.m_lpAddrList  -> m_nAddrListCnt));
    MessageBox(strTip);
}

void  CGameEditorDlg::UpdataProcessList()   // 更新进程列表函数
{
    HANDLE hSnapShot;
    PROCESSENTRY32 stProcessEntry32 
=  { 0 };
    
int  nIndex;
    CString strItemText;

    hSnapShot 
=  ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0 );
    
if (hSnapShot  ==  INVALID_HANDLE_VALUE)
        
return ;

    m_clsProcessList.DeleteAllItems();  
// 删除进程列表框所有项
    nIndex  =   0 ;

    stProcessEntry32.dwSize 
=   sizeof  stProcessEntry32;
    
if (::Process32First(hSnapShot, & stProcessEntry32))
    { 
        
do
        {     
            strItemText 
=  stProcessEntry32.szExeFile;
            m_clsProcessList.InsertItem(nIndex,strItemText,
0 );
            strItemText.Format(
" %d " ,stProcessEntry32.th32ProcessID);
            m_clsProcessList.SetItemText(nIndex,
1 ,strItemText);
            nIndex
++ ;
        } 
        
while (::Process32Next(hSnapShot,  & stProcessEntry32)); 
    }
    
// strItemText.Format("总共进程数:%d",nIndex);
    
// MessageBox(strItemText);
    ::CloseHandle(hSnapShot);
}

void  CGameEditorDlg::OnDblclkProcesslist(NMHDR *  pNMHDR, LRESULT *  pResult)   // 进程列表框鼠标双击事件处理过程
{
    
//  TODO: Add your control notification handler code here
     int  nIndex;
    CString strItemText;

    nIndex 
=  ( int )m_clsProcessList.GetFirstSelectedItemPosition();   // 获取进程列表框当前所选择的行的索引号(从1开始)
     if ( ! nIndex)   // 索引号为0则未选择任何一行
         return ;

    strItemText 
=  m_clsProcessList.GetItemText(nIndex  -   1 , 0 );   // 获取进程列表框指定行和列的文本值(从0开始);
    SetDlgItemText(IDE_PNAME,strItemText);   // 设置进程名称文本框内容
    strItemText  =  m_clsProcessList.GetItemText(nIndex  -   1 , 1 );   // 获取进程列表框指定行和列的文本值(从0开始);
    SetDlgItemText(IDE_PID,strItemText);   // 设置进程ID文本框内容
    m_bFirst  =  TRUE;

    
* pResult  =   0 ;
}

void  CGameEditorDlg::UpdataAddrList()   // 更新地址列表函数
{
    
int  nCount,i;
    DWORD dwAddr,dwValue 
=   0 ;
    CString strItemText;

    m_clsAddrList.DeleteAllItems();  
// 删除地址列表框所有项

    nCount 
=  m_clsMemScanner.m_lpAddrList  -> m_nAddrListCnt;
    
for (i  =   0 ; i  <  nCount; i ++ )
    {
        dwAddr 
=  m_clsMemScanner.m_lpAddrList  -> m_lpAddrList[i];
        m_clsMemScanner.ReadMemory(dwAddr,
& dwValue);
        strItemText.Format(
" %d " ,i  +   1 );
        m_clsAddrList.InsertItem(i,strItemText,
0 );
        strItemText.Format(
" 0x%08X " ,dwAddr);
        m_clsAddrList.SetItemText(i,
1 ,strItemText);
        strItemText.Format(
" %d " ,dwValue);
        m_clsAddrList.SetItemText(i,
2 ,strItemText);
    }
}

void  CGameEditorDlg::OnReset()   // 重置按钮单击事件处理过程
{
    
//  TODO: Add your control notification handler code here
    m_bFirst  =  TRUE;
}

void  CGameEditorDlg::OnDblclkAddrlist(NMHDR *  pNMHDR, LRESULT *  pResult)   // 地址列表框鼠标双击事件处理过程
{
    
//  TODO: Add your control notification handler code here
     int  nIndex  =   0 ;
    
    nIndex 
=  ( int )m_clsAddrList.GetFirstSelectedItemPosition();   // 获取进程列表框当前所选择的行的索引号(从1开始)
     if ( ! nIndex)   // 索引号为0则未选择任何一行
         return ;
    
    CModifyDlg clsModifyDlg 
=   new  CModifyDlg( this );
    clsModifyDlg.m_lpMainDlg 
=   this ;
    clsModifyDlg.m_strModifyAddr 
=  m_clsAddrList.GetItemText(nIndex  -   1 , 1 );   // 获取进程列表框指定行和列的文本值(从0开始);
     if (clsModifyDlg.DoModal()  ==   1 )   // 显示修改内存模态对话框
        UpdataAddrList();   // 更新地址列表
    delete clsModifyDlg;

    
* pResult  =   0 ;
}

BOOL CGameEditorDlg::PreTranslateMessage(MSG
*  pMsg) 
{
    
//  TODO: Add your specialized code here and/or call the base class
     if (pMsg  ->  message  ==  WM_KEYDOWN)
    {
        
switch (pMsg  ->  wParam)
        {
        
case  VK_RETURN:   // 屏蔽回车键
         case  VK_ESCAPE:   // 屏蔽ESC键
             return  TRUE;
        }
    }
    
return  CDialog::PreTranslateMessage(pMsg);
}

ModifyDlg.h(修改对话框类)

#if  !defined(AFX_MODIFYDLG_H__540F01D9_9707_4D58_885D_3131C1FA4AB8__INCLUDED_)
#define  AFX_MODIFYDLG_H__540F01D9_9707_4D58_885D_3131C1FA4AB8__INCLUDED_

#if  _MSC_VER > 1000
#pragma  once
#endif   //  _MSC_VER > 1000
//  ModifyDlg.h : header file
//

/// //
//  CModifyDlg dialog
#include  " GameEditorDlg.h "

class  CModifyDlg :  public  CDialog
{
//  Construction
public :
    CModifyDlg(CWnd
*  pParent  =  NULL);    //  standard constructor

//  Dialog Data
    
// {{AFX_DATA(CModifyDlg)
     enum  { IDD  =  IDD_MODIFYDLG };
        
//  NOTE: the ClassWizard will add data members here
    
// }}AFX_DATA


//  Overrides
    
//  ClassWizard generated virtual function overrides
    
// {{AFX_VIRTUAL(CModifyDlg)
     public :
    
virtual  BOOL PreTranslateMessage(MSG *  pMsg);
    
protected :
    
virtual   void  DoDataExchange(CDataExchange *  pDX);     //  DDX/DDV support
    
// }}AFX_VIRTUAL

//  Implementation
protected :
    HICON m_hIcon;
public :
    CGameEditorDlg 
*  m_lpMainDlg;   // 主窗口对象指针
    CString m_strModifyAddr;   // 从主窗口传递过来的用户欲修改的内存的地址值

    
//  Generated message map functions
    
// {{AFX_MSG(CModifyDlg)
    afx_msg HBRUSH OnCtlColor(CDC *  pDC, CWnd *  pWnd, UINT nCtlColor);
    afx_msg 
void  OnOk();
    
virtual  BOOL OnInitDialog();
    afx_msg 
void  OnCancel();
    
// }}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

// {{AFX_INSERT_LOCATION}}
//  Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif   //  !defined(AFX_MODIFYDLG_H__540F01D9_9707_4D58_885D_3131C1FA4AB8__INCLUDED_)

ModifyDlg.cpp

//  ModifyDlg.cpp : implementation file
//

#include 
" stdafx.h "
#include 
" GameEditor.h "
#include 
" ModifyDlg.h "

#ifdef _DEBUG
#define  new DEBUG_NEW
#undef  THIS_FILE
static   char  THIS_FILE[]  =  __FILE__;
#endif

/// //
//  CModifyDlg dialog


CModifyDlg::CModifyDlg(CWnd
*  pParent  /* =NULL */ )
    : CDialog(CModifyDlg::IDD, pParent)
{
    
// {{AFX_DATA_INIT(CModifyDlg)
        
//  NOTE: the ClassWizard will add member initialization here
    
// }}AFX_DATA_INIT
    m_hIcon  =  AfxGetApp() -> LoadIcon(IDR_MAINFRAME);
}


void  CModifyDlg::DoDataExchange(CDataExchange *  pDX)
{
    CDialog::DoDataExchange(pDX);
    
// {{AFX_DATA_MAP(CModifyDlg)
        
//  NOTE: the ClassWizard will add DDX and DDV calls here
    
// }}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CModifyDlg, CDialog)
    
// {{AFX_MSG_MAP(CModifyDlg)
    ON_WM_CTLCOLOR()
    ON_BN_CLICKED(IDB_OK, OnOk)
    ON_BN_CLICKED(IDB_CANCEL, OnCancel)
    
// }}AFX_MSG_MAP
END_MESSAGE_MAP()

/// //
//  CModifyDlg message handlers

HBRUSH CModifyDlg::OnCtlColor(CDC
*  pDC, CWnd *  pWnd, UINT nCtlColor) 
{
    HBRUSH hbr 
=  CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
    
    
//  TODO: Change any attributes of the DC here
     if (pWnd  ->  GetDlgCtrlID()  ==  IDE_ADDR)
    {
        pDC
-> SetBkColor(RGB( 255 , 255 , 255 ));
        pDC
-> SetTextColor(RGB( 255 , 0 , 0 ));   
        
return  (HBRUSH)GetStockObject(WHITE_BRUSH);
    }
    
//  TODO: Return a different brush if the default is not desired
     return  hbr;
}

void  CModifyDlg::OnOk()   // 确定按钮单击事件处理过程
{
    
//  TODO: Add your control notification handler code here
    DWORD dwAddr  =   0 ,dwValue  =   0 ;

    
if (GetDlgItem(IDE_VALUE)  -> GetWindowTextLength()  <=   0 )
        
return ;

    m_strModifyAddr 
=  m_strModifyAddr.Mid( 2 );   // 去掉"0x"
    sscanf(m_strModifyAddr, " %x " , & dwAddr);   // 转换成数字

    dwValue 
=  GetDlgItemInt(IDE_VALUE);
    m_lpMainDlg 
-> m_clsMemScanner.WriteMemory(dwAddr,dwValue);   // 修改内存
    MessageBox( " 修改成功! " );
    EndDialog(
1 );
}

BOOL CModifyDlg::OnInitDialog()  
// 对话框初始化函数
{
    CDialog::OnInitDialog();
    
    
//  TODO: Add extra initialization here
    SetIcon(m_hIcon, TRUE);             //  Set big icon
    SetIcon(m_hIcon, FALSE);         //  Set small icon

    SetDlgItemText(IDE_ADDR,m_strModifyAddr);  
// 设置目标地址文本框内容

    
return  TRUE;   //  return TRUE unless you set the focus to a control
                  
//  EXCEPTION: OCX Property Pages should return FALSE
}

void  CModifyDlg::OnCancel()   // 取消对话框单击事件处理过程
{
    
//  TODO: Add your control notification handler code here
    EndDialog( 0 );
}

BOOL CModifyDlg::PreTranslateMessage(MSG
*  pMsg) 
{
    
//  TODO: Add your specialized code here and/or call the base class
     if (pMsg  ->  message  ==  WM_KEYDOWN)
    {
        
switch (pMsg  ->  wParam)
        {
        
case  VK_RETURN:   // 屏蔽回车键
         case  VK_ESCAPE:   // 屏蔽ESC键
             return  TRUE;
        }
    }
    
return  CDialog::PreTranslateMessage(pMsg);
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值