C++特征搜索源码
/////////////////////////////////////////////////////////////////////////////
//
#include "stdafx.h"
#include "TeZhengMa.h"
#include "TeZhengMaDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CTeZhengMaDlg 对话框
CTeZhengMaDlg::CTeZhengMaDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CTeZhengMaDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTeZhengMaDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CTeZhengMaDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_CALL, &CTeZhengMaDlg::OnBnClickedButtonCall)
END_MESSAGE_MAP()
// CTeZhengMaDlg 消息处理程序
BOOL CTeZhengMaDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CTeZhengMaDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
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;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CTeZhengMaDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
HWND g_hWnd=NULL; //定义窗口句柄变量
DWORD processId=0; //定义进程标识符变量
HANDLE m_process=0; //进程句柄变量
int Find_process_true=0;//获取进程句柄判断
/************************************************************************/
/* 函数说明:根据特征码扫描基址
/* 参数一:process 要查找的进程
/* 参数二:markCode 特征码字符串,不能有空格
/* 参数二:m_Dword 用来保存特征码的在的基址
/************************************************************************/
DWORD M_ScanAddress(HANDLE process,
char *markCode,
DWORD m_Dword
)
{
//************处理特征码,转化成字节*****************
if (strlen(markCode) % 2 != 0) return 0;
//特征码长度
int len = strlen(markCode) / 2; //获取代码的字节数
//将特征码转换成byte型 保存在m_code 中
BYTE *m_code = new BYTE[len];
for (int i = 0; i < len; i++)
{
//定义可容纳单个字符的一种基本数据类型。
char c[] = {markCode[i*2], markCode[i*2+1], '\0'};
//将参数nptr字符串根据参数base来转换成长整型数
m_code[i]= (BYTE)::strtol(c, NULL, 16);
}
//起始地址
const DWORD beginAddr = 0x400000;
//结束地址
const DWORD endAddr = 0x7FFFFFFF;
//每次读取游戏内存数目的大小
const DWORD pageSize = 4096;
/////////////////////////查找特征码/////////////////////
//每页读取4096个字节
BYTE *page = new BYTE[pageSize];
DWORD tmpAddr = beginAddr;
//定义和特征码一样长度的标识
int compare_one=0;
while (tmpAddr <= endAddr )
{
::ReadProcessMemory(process, (LPCVOID)tmpAddr, page, pageSize, 0); //读取0x400000的内存数据,保存在page,长度为pageSize
//在该页中查找特征码
for (int i = 0; i < pageSize; i++)
{
if(m_code[0]==page[i])//有一个字节与特征码的第一个字节相同,则搜索
{
for(int j=0;j<len-1;j++)
{
if(m_code[j+1]==page[i+j+1])//比较每一个字节的大小,不相同则退出
{
compare_one++;
}
else
{
compare_one=0;
break;
}//如果下个对比的字节不相等,则退出,减少资源被利用
}
if((compare_one+1)==len)
{
// 找到特征码处理
//赋值时要给初始值,避免冲突
char *m_b=new char;
m_Dword=tmpAddr+i;
itoa(tmpAddr+i,m_b,16);
CString m_a;
m_a=m_b;
AfxMessageBox(_T("特征码的内存地址:")+m_a);
return 1 ;
}
}
}
tmpAddr=tmpAddr+pageSize-len;//下一页搜索要在前一页最后长度len 开始查找,避免两页交接中间有特征码搜索不出来
}
AfxMessageBox(_T("end"));
return 0 ;
}
void CTeZhengMaDlg::OnBnClickedButtonCall()
{
// TODO: 在此添加控件通知处理程序代码
//1、查找窗口
g_hWnd=::FindWindow(NULL,_T("My_ADD"));//可以修改自己的窗口名字
::GetWindowThreadProcessId(g_hWnd, &processId); //获取创建者的标志符
m_process = ::OpenProcess(PROCESS_ALL_ACCESS, false, processId); //打开进程获取进程句柄
//:: SetWindowPos(AfxGetMainWnd()->m_hWnd,HWND_BOTTOM,10,10,450,300,SWP_NOMOVE);
if(m_process)
{
AfxMessageBox(_T("Success find window"));
M_ScanAddress(m_process,"f7d81bc0f7d859485dc38bff558bec",NULL);
}
}
下载地址: 特征码例子