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
#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;
}
#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
#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 ++ ;
}
#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
#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 ++ ;
}
#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_)
//
#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;
}
//
#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_)
//
#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);
}
//
#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_)
#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);
}
//
#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);
}