#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算法 极速定位指定进程内存特征码!相关推荐

  1. 基于麻雀算法改进的无线传感器网络Dv-hop定位算法 - 附代码

    基于麻雀算法改进的无线传感器网络Dv-hop定位算法 文章目录 基于麻雀算法改进的无线传感器网络Dv-hop定位算法 1.DV-Hop算法原理 2.麻雀算法改进DV-Hop算法原理 3.算法测试 4. ...

  2. tdoa/aoa定位的扩展卡尔曼滤波定位算法matlab源码,TDOA/AOA定位的扩展卡尔曼滤波定位跟踪算法Matlab源码...

    TDOA/AOA定位是无线定位领域里使用得最多的一种定位体制,扩展卡尔曼滤波器是最经典的非线性滤波算法,可用于目标的定位和动态轨迹跟踪,GreenSim团队实现了该算法,本源码由GreenSim团队原 ...

  3. c语言中闰年的流程图_C语言-算法与流程图

    <C语言-算法与流程图>由会员分享,可在线阅读,更多相关<C语言-算法与流程图(22页珍藏版)>请在人人文库网上搜索. 1.目录,第一章 绪论 第二章 算法与流程图 第三章 数 ...

  4. 1. 通用基础算法(1.7动态规划算法/1.8模拟算法/1.9其他算法)

    7  动态规划算法 动态规划(Dynamic Programming)是求多阶段决策过程(Multistep Decision Process)最优化的一种数学方法,它将问题的整体按时间或空间的特征分 ...

  5. BM算法的改进的算法SUNDAY--Boyer-Moore-Horspool-Sunday Aglorithm

    BM算法的改进的算法SUNDAY--Boyer-Moore-Horspool-Sunday Aglorithm BM算法优于KMP SUNDAY 算法描述: 字符串查找算法中,最著名的两个是KMP算法 ...

  6. 遗传算法是一种进化算法_我是如何设计一种算法的,该算法混合了到您镇上的乐队的播放列表...

    遗传算法是一种进化算法 by Sina Habibian 通过新浪Habibian 我是如何设计一种算法的,该算法混合了到您镇上的乐队的播放列表 (How I designed an algorith ...

  7. 经典算法书籍推荐以及算法书排行【算法四库全书】

    经典算法书籍推荐以及算法书排行[算法四库全书] 作者:霞落满天   https://linuxstyle.blog.csdn.net/    https://blog.csdn.net/21aspne ...

  8. Surf算法学习心得(一)——算法原理

    Surf算法学习心得(一)--算法原理 写在前面的话: Surf算法是对Sift算法的一种改进,主要是在算法的执行效率上,比Sift算法来讲运行更快!由于我也是初学者,刚刚才开始研究这个算法,然而网上 ...

  9. SLAM算法总结——经典SLAM算法框架总结

    SLAM算法总结--经典SLAM算法框架总结 SLAM算法总结--经典SLAM算法框架总结 SLAM算法总结--经典SLAM算法框架总结 从研究生接触SLAM算法到现在也有两三年了,期间学习了很多经典 ...

最新文章

  1. mapgis明码文件转为点线面文件_干货|MAPGIS的二十一个实用方法及技巧
  2. 机器人学习--Robotics 4:Perception(宾夕法尼亚大学COURSERA课程)
  3. android8.1通知,在Android 8.1 API 27上,通知不会显示
  4. 9月份计算机应用基础统考,2018年9月计算机应用基础统考题库-网考计算机应用基础真题1...
  5. Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart)
  6. 如何手动输入给数组赋值_你是否真的了解VBA数组呢?让我带你认识一下真正的数组...
  7. redis 命令 释放连接_Redis---gt;02
  8. 个推 Spark实践教你绕过开发那些“坑”
  9. 18.go 日志监控系统
  10. WPF 动态添加控件以及样式字典的引用(Style introduction)
  11. Python深度学习(什么是深度学习)----学习笔记(一)
  12. 数据结构之图的基本介绍
  13. 基于相似性网络融合的目标分类研究
  14. 虚拟 IO 服务器(VIOS)和 IBM i
  15. 移动开发即服务,腾讯云移动开发平台打造开发新模式
  16. 三十而立~2019年终总结
  17. 基于SDN的访问控制模块实现
  18. 星淘惠告诉你跨境平台那么多,凭什么要选亚马逊?
  19. 以计算机思维思考当下面向未来,面向未来的核心素养:从运算能力到计算思维...
  20. 众言科技SVP郭晓波做客东南大学:选对池塘钓大鱼 | 校企互通

热门文章

  1. 从盗亦有道看盗道,商道和师道
  2. 如何开网店,itdaxue手把手教你开店方法。
  3. UI(十)模拟服务器配置
  4. 快捷键关闭c语言程序,C语言:VS环境下的程序快捷键大全以及Windows快捷键命令...
  5. 基于Bootstrap简洁的后台UI框架
  6. html提示框的分类,【干货贴】关于提示框的那些事儿
  7. 【51单片机】数码管的静态显示
  8. 青山依旧在,2021这一年
  9. ARChon 分析之五 : chrome-app的开发方法
  10. 【MPC5744P】劳特巴赫调试器Trace32的使用方法