sunday算法特征码_C++ sunday算法 极速定位指定进程内存特征码!
#include
#include
#include
using namespace std;
/*
findMatchingCode() 参数说明:
1) hProcess 要打开的进程句柄
2) markCode 特征码,支持通配符(??),如: 55 8b ec ?? 56 83 ec 20 ?? ?? 08 d9 ee
3) memBeginAddr 起始搜索地址
4) memEndAddr 结束搜索地址
5) retAddr[] 记录找到的地址,传入这个参数前一定要清0,如 DWORD retAddr[32] = {0}; 或者 DWORD *retAddr = new DWORD[32]();
6) deviation 特征码地址离目标地址的偏移距离,上负下正
7) isCall 是否为找CALL的跳转地址,true 则 retAddr[] 返回的是CALL跳转的地址
8) isAll 是否查找所有符合的地址,false找到第一个符合的地址后就结束搜索,true继续搜索,直到搜索地址大于结束地址(memEndAddr)
return返回值 找到的地址总数
*/
DWORD findMatchingCode(HANDLE hProcess, string markCode, DWORD memBeginAddr, DWORD memEndAddr, DWORD retAddr[], int deviation, bool isCall, bool isAll = false);
DWORD findMatchingCode(HANDLE hProcess, string markCode, DWORD memBeginAddr, DWORD memEndAddr, DWORD retAddr[], int deviation, bool isCall, bool isAll)
{
//----------------------处理特征码----------------------//
//去除所有空格
if (!markCode.empty())
{
int index = 0;
while ((index = markCode.find(' ', index)) >= 0)
{
markCode.erase(index, 1);
}
index = 0;
while (true)
{
//删掉头部通配符
index = markCode.find("??", index);
if (index == 0) {
markCode.erase(index, 2);
}
else {
break;
}
}
}
//特征码长度不能为单数
if (markCode.length() % 2 != 0) return 0;
//特征码长度
int len = markCode.length() / 2;
//Sunday算法模板数组的长度
int nSundayLen = len;
//将特征码转换成byte型
BYTE *pMarkCode = new BYTE[len];
for (int i = 0; i < len; i++)
{
string tempStr = markCode.substr(i*2, 2);
if (tempStr == "??") {
pMarkCode[i] = 0x3F;
if (nSundayLen == len) nSundayLen = i;
}
else{
pMarkCode[i] = strtoul(tempStr.c_str(), 0, 16);
}
}
//--------------------------end-------------------------//
//Sunday算法模板数组赋值,+1防止特征码出现FF时越界
int aSunday[0xFF + 1] = { 0 };
for (int i = 0; i < nSundayLen; i++){
aSunday[pMarkCode[i]] = i + 1;
}
//起始地址
const DWORD dwBeginAddr = memBeginAddr;
//结束地址
const DWORD dwEndAddr = memEndAddr;
//当前读取的内存块地址
DWORD dwCurAddr = dwBeginAddr;
//存放内存数据的缓冲区
BYTE *pMemBuffer = NULL;
//计算参数retAddr[]数组的长度,该参数传入前一定要清0
int nArrayLength = 0;
for (int i = 0; ; i++) {
if (*(retAddr + i) != 0) {
nArrayLength = i;
break;
}
}
//偏移量
int nOffset;
//数组下标:内存、特征码、返回地址
int i = 0, j = 0, nCount = 0;
//内存信息
MEMORY_BASIC_INFORMATION mbi;
//记录起始搜索时间
clock_t nBeginTime = clock();
//扫描内存
while (dwCurAddr < dwEndAddr)
{
//查询地址空间中内存地址的信息
memset(&mbi, 0, sizeof(MEMORY_BASIC_INFORMATION));
if (::VirtualQueryEx(hProcess, (LPCVOID)dwCurAddr, &mbi, sizeof(mbi)) == 0) {
goto end;
}
//过滤内存空间, 根据内存的状态和保护属性进行过滤
//一般扫描(读写及执行)即可,速度极快,扫不到的话在尝试添加(读写)这一属性
if (MEM_COMMIT == mbi.State && //已分配的物理内存
//MEM_PRIVATE == mbi.Type || //私有内存,不被其他进程共享
//MEM_IMAGE == mbi.Type &&
//PAGE_READONLY == mbi.Protect || //只读
//PAGE_EXECUTE_READ == mbi.Protect || //读及执行
//PAGE_READWRITE == mbi.Protect || //读写
PAGE_EXECUTE_READWRITE == mbi.Protect) //读写及执行
{
//申请动态内存
if (pMemBuffer) {
delete[] pMemBuffer;
pMemBuffer = NULL;
}
pMemBuffer = new BYTE[mbi.RegionSize];
//读取进程内存
ReadProcessMemory(hProcess, (LPCVOID)dwCurAddr, pMemBuffer, mbi.RegionSize, 0);
i = 0;
j = 0;
while (j < len)
{
nextAddr:
if (pMemBuffer[i] == pMarkCode[j] || pMarkCode[j] == 0x3F)
{
i++;
j++;
}
else
{
nOffset = i - j + nSundayLen;
//判断偏移量是否大于缓冲区
if (nOffset > mbi.RegionSize - len) break;
//判断 aSunday模板数组 里有没有 内存偏移后的值,有则回溯,否则+1
if (aSunday[pMemBuffer[nOffset]])
{
i = nOffset - aSunday[pMemBuffer[nOffset]] + 1;
j = 0;
}
else
{
i = nOffset + 1;
j = 0;
}
}
}
if (j == len)
{
//计算找到的目标地址:
//特征码地址 = 当前内存块基址 + i偏移 - 特征码长度
//目标地址 = 特征码地址 + 偏移距离
//CALL(E8)跳转的地址 = E8指令后面的4个字节地址 + 下一条指令地址(也就是目标地址 + 5)
retAddr[nCount] = dwCurAddr + i - len + deviation;
if (isCall) {
DWORD temp;
memcpy(&temp, &pMemBuffer[i - len + deviation + 1], 4);
retAddr[nCount] += 5;
retAddr[nCount] += temp;
}
if (++nCount >= nArrayLength)
{
//传入的数组下标越界就结束搜索
goto end;
}
if (isAll) {
i = i - len + 1;
j = 0;
goto nextAddr;
}
else {
goto end;
}
}
dwCurAddr += mbi.RegionSize; //取下一块内存地址
}
else
{
dwCurAddr += mbi.RegionSize;
}
}
end:
//计算搜索用时(ms)
clock_t nEndTime = clock();
int nUseTime = (nEndTime - nBeginTime);
//释放内存
if (pMemBuffer) {
delete[] pMemBuffer;
pMemBuffer = NULL;
}
delete[] pMarkCode;
pMarkCode = NULL;
return nCount;
}
sunday算法特征码_C++ sunday算法 极速定位指定进程内存特征码!相关推荐
- 基于麻雀算法改进的无线传感器网络Dv-hop定位算法 - 附代码
基于麻雀算法改进的无线传感器网络Dv-hop定位算法 文章目录 基于麻雀算法改进的无线传感器网络Dv-hop定位算法 1.DV-Hop算法原理 2.麻雀算法改进DV-Hop算法原理 3.算法测试 4. ...
- tdoa/aoa定位的扩展卡尔曼滤波定位算法matlab源码,TDOA/AOA定位的扩展卡尔曼滤波定位跟踪算法Matlab源码...
TDOA/AOA定位是无线定位领域里使用得最多的一种定位体制,扩展卡尔曼滤波器是最经典的非线性滤波算法,可用于目标的定位和动态轨迹跟踪,GreenSim团队实现了该算法,本源码由GreenSim团队原 ...
- c语言中闰年的流程图_C语言-算法与流程图
<C语言-算法与流程图>由会员分享,可在线阅读,更多相关<C语言-算法与流程图(22页珍藏版)>请在人人文库网上搜索. 1.目录,第一章 绪论 第二章 算法与流程图 第三章 数 ...
- 1. 通用基础算法(1.7动态规划算法/1.8模拟算法/1.9其他算法)
7 动态规划算法 动态规划(Dynamic Programming)是求多阶段决策过程(Multistep Decision Process)最优化的一种数学方法,它将问题的整体按时间或空间的特征分 ...
- BM算法的改进的算法SUNDAY--Boyer-Moore-Horspool-Sunday Aglorithm
BM算法的改进的算法SUNDAY--Boyer-Moore-Horspool-Sunday Aglorithm BM算法优于KMP SUNDAY 算法描述: 字符串查找算法中,最著名的两个是KMP算法 ...
- 遗传算法是一种进化算法_我是如何设计一种算法的,该算法混合了到您镇上的乐队的播放列表...
遗传算法是一种进化算法 by Sina Habibian 通过新浪Habibian 我是如何设计一种算法的,该算法混合了到您镇上的乐队的播放列表 (How I designed an algorith ...
- 经典算法书籍推荐以及算法书排行【算法四库全书】
经典算法书籍推荐以及算法书排行[算法四库全书] 作者:霞落满天 https://linuxstyle.blog.csdn.net/ https://blog.csdn.net/21aspne ...
- Surf算法学习心得(一)——算法原理
Surf算法学习心得(一)--算法原理 写在前面的话: Surf算法是对Sift算法的一种改进,主要是在算法的执行效率上,比Sift算法来讲运行更快!由于我也是初学者,刚刚才开始研究这个算法,然而网上 ...
- SLAM算法总结——经典SLAM算法框架总结
SLAM算法总结--经典SLAM算法框架总结 SLAM算法总结--经典SLAM算法框架总结 SLAM算法总结--经典SLAM算法框架总结 从研究生接触SLAM算法到现在也有两三年了,期间学习了很多经典 ...
最新文章
- mapgis明码文件转为点线面文件_干货|MAPGIS的二十一个实用方法及技巧
- 机器人学习--Robotics 4:Perception(宾夕法尼亚大学COURSERA课程)
- android8.1通知,在Android 8.1 API 27上,通知不会显示
- 9月份计算机应用基础统考,2018年9月计算机应用基础统考题库-网考计算机应用基础真题1...
- Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart)
- 如何手动输入给数组赋值_你是否真的了解VBA数组呢?让我带你认识一下真正的数组...
- redis 命令 释放连接_Redis---gt;02
- 个推 Spark实践教你绕过开发那些“坑”
- 18.go 日志监控系统
- WPF 动态添加控件以及样式字典的引用(Style introduction)
- Python深度学习(什么是深度学习)----学习笔记(一)
- 数据结构之图的基本介绍
- 基于相似性网络融合的目标分类研究
- 虚拟 IO 服务器(VIOS)和 IBM i
- 移动开发即服务,腾讯云移动开发平台打造开发新模式
- 三十而立~2019年终总结
- 基于SDN的访问控制模块实现
- 星淘惠告诉你跨境平台那么多,凭什么要选亚马逊?
- 以计算机思维思考当下面向未来,面向未来的核心素养:从运算能力到计算思维...
- 众言科技SVP郭晓波做客东南大学:选对池塘钓大鱼 | 校企互通