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