文章目录

  • 前言
  • 一、原理
  • 二、过程
    • 1.获取进程句柄
    • 2.读入数据
    • 3.字节数组比对
    • 4.十六进制字符串转字节数组
  • 总结

前言

特征码定位在很多情况下是非常方便的。如动态地址,游戏更新地址变动等


一、原理

特征码定位的原理,其实就是读程序内存,将读出的字节数组与欲寻找的字节数组做匹配。如果匹配成功,将得到的偏移加上读取首地址就得到指定特征码的地址了。

二、过程

1.获取进程句柄

读取内存之前,要获得具有 PROCESS_VM_READ 权限的进程句柄。用OpenProcess()实现。至于进程pid,方法不唯一,大家自取。我是通过取进程快照遍历对比进程名得到的。

/*** @brief Get the Pro Id object** @param proName 进程名* @return DWORD 进程id*/
DWORD getProIdByName(char *proName)
{PROCESSENTRY32 proInfo;proInfo.dwSize = sizeof(PROCESSENTRY32);//获取所有进程快照HANDLE hProSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hProSnap == INVALID_HANDLE_VALUE){return -1;}Process32First(hProSnap, &proInfo);while (strcmp(proInfo.szExeFile, proName) != 0){if (Process32Next(hProSnap, &proInfo) == 0)break;}//关闭快照句柄CloseHandle(hProSnap);if (strcmp(proInfo.szExeFile, proName) != 0){return -1;}else{//返回进程进程句柄return proInfo.th32ProcessID;}
}//获取进程句柄OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

2.读入数据

使用 ReadProcessMemory()读内存需要注意

要读取的整个区域必须是可访问的,如果不可访问,则函数失败。
此时getLastError() 错误码 为 299 (0x12B) — Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

为了避免这个错误,尽量保证一页内存一页内存来读取

/*** @brief 通过特征码定位到指定地址,支持?通配符** @param hPro 进程HANDLE* @param markStr 特征码。为了支持??,用UINT数组* @param startAdd 起始地址* @return DWORD 获取到的地址。失败返回0*/
PVOID locateAddByMarkStr(HANDLE hPro, UINT *pByteArr, int lengthOfByteArr, DWORD startAdd)
{int offset;// 4096为一个内存页大小byte buffer[4096];startAdd -= startAdd % 4096;DWORD endAdd = 0x7FFFFFFF;while (startAdd <= endAdd){int flag = ReadProcessMemory(hPro, (PVOID)startAdd, buffer, 4096, NULL);if (flag && byteArrComp(buffer, pByteArr, 4096, lengthOfByteArr, &offset)){return (PVOID)(startAdd + offset);}startAdd += 4096;}return 0;
}

3.字节数组比对

在读取到一块内存以后,就要和目标特征码做比对

/*** @brief 字节数组比对** @param arr1 大数组* @param arr2 小数组* @param len1 大数组长度* @param len2 小数组长度* @return BOOL*/
BOOL byteArrComp(byte *arr1, UINT *arr2, int len1, int len2, int *position)
{for (int i = 0; i < len1 - len2 + 1; i++){for (int j = 0; j < len2; j++){//字节为256时,表示该字节是??if (arr2[j] != arr1[j + i] && arr2[j] != 256){break;}else if (j == len2 - 1){//匹配时记录偏移*position = i;return 1;}}}return 0;
}

4.十六进制字符串转字节数组

/*** @brief 十六进制转字节型,?? 返回256** @param str 欲转换的字符* @return UINT*/
UINT hexToByte(char *str)
{if (str[0] == '?')return 256;return (byte)strtol(str, NULL, 16);
}
/*** @brief 十六进制转字节数组** @param str 十六进制文本* @param pLength 指向保存字节数组长度的指针* @return UINT* 字节数组*/
UINT *hexToByteArr(const char *str, int *pLength)
{char tmp[3];int lengthOfArr = 0;int len = strlen(str);int *arr = (int *)malloc((len + 1) / 2 * sizeof(int));for (int i = 0, j = 0; i < len; i++){//过滤空格if (str[i] == ' ')continue;//往临时数组里面添加两个字符。每两个十六进制可表示一字节tmp[j % 2] = str[i];if ((j + 1) % 2 == 0){tmp[2] = '\0';arr[lengthOfArr++] = hexToByte(tmp);}j++;}*pLength = lengthOfArr;return arr;
}

总结

由于byteArrComp()所在的循环要循环几十万次,为了加快效率,大家可以自行优化算法。

c语言实现特征码定位内存,支持通配符相关推荐

  1. 易语言特征码定位工具源码

    点击阅读原文 调用API函数实现文件的特征码定位. 链接: http://pan.baidu.com/s/1kU5mE4B 密码: mwdx

  2. 通过php extension使disable_function支持通配符

    为什么80%的码农都做不了架构师?>>>    本人学C语言不久,对指针内存管理等都还没入门,php扩展的编写更是胡乱在拼凑,以下是我"乱搞"的一点记录,希望大家 ...

  3. Linux内存管理内存映射以及通过反汇编定位内存错误问题

    提到C语言,我们知道C语言和其他高级语言的最大的区别就是C语言是要操作内存的! 我们需要知道--变量,其实是内存地址的一个抽像名字罢了.在静态编译的程序中,所有的变量名都会在编译时被转成内存地址.机器 ...

  4. 用c语言为程序分配内存,关于C语言程序的内存分配的入门知识学习

    C语言程序的存储区域 C语言编写的程序经过编绎-链接后,将形成一个统一的文件,它由几个部分组成,在程序运行时又会产生几个其他部分,各个部分代表了不同的存储区域: 代码段(Code or Text):代 ...

  5. github snap android,GitHub - albuer/heapsnap: HeapSnap 是一个定位内存泄露的工具,适用于Android平台。...

    HeapSnap 1.HeapSnap 是什么 HeapSnap 是一个定位内存泄露的工具,适用于Android平台. 主要特性如下: 对系统负载低 不需要修改目标进程的源代码 支持Andoroid上 ...

  6. 用mtrace定位内存泄漏

    一. 缘起 有的公众号读者,看完我上次写给大学生的查bug方法后,希望我多分享一些查bug的实践经验和具体步骤,比如如何查内存泄漏和core dump问题.所以,就打算写这篇文章. 二. 内存泄漏简介 ...

  7. c语言作业系统输出超限,C语言网Online Judge系统支持语言和编译说明

    Online Judge系统支持语言和编译情况: 语言 编译器 语言版本 编译参数 C gcc 4.6.3 C99 gcc Main.c -o Main -Wall -lm –static -std= ...

  8. 王爽 汇编语言第三版 第7章 --- 更灵活的定位内存地址的方法(可以理解为 数组形式的内存定位)

    汇编语言(第三版)王爽著 的十二个实验:https://blog.csdn.net/OrangeHap/article/details/89791064 大小端 字节对齐 对于 arm,intel 这 ...

  9. 更灵活的定位内存地址的方法02 - 零基础入门学习汇编语言33

    第七章:更灵活的定位内存地址的方法02 让编程改变世界 Change the world by program [bx+idata] 在前面,我们可以用[bx]的方式来指明一个内存单元, 我们还可以用 ...

最新文章

  1. java实现将汉语转换为拼音
  2. Marketing Cloud launchpad中的meta标签
  3. 一文说通C#中的异步编程补遗
  4. 如何在ASP.NET Core中自定义Azure Storage File Provider
  5. 2020年上半年小程序互联网发展报告
  6. kafka 在 360 商业化的实践
  7. 单元测试 Spring
  8. Thread类和Runnable接口如何运用?
  9. lj2400恢复出厂_联想LJ2400加粉后如何清零
  10. 百度分享代码--一键分享Baidu Share BEGIN
  11. CSS实现平行四边形
  12. JS中数组迭代方法(JavaScript从入门到疯癫)
  13. 基于Ubuntu系统,调用opencv在图片上显示数字和汉字
  14. FCM公式详细推及代码
  15. smarty新闻管理系统
  16. 玩转spring boot——ajax跨域
  17. 百度搜索风云榜 准确吗?
  18. office 软件常用备忘(删除线/冻结等)
  19. 新人学习笔记-分布式基础学习-分布式文件系统
  20. Java实现文字转语音(TTS)和指定路径播放音频文件

热门文章

  1. 完全PIN对PIN SN2711B系列 存储器配置 OTP ROM 空间:1K * 16 位。 RAM 空间:64 字节。
  2. 谈谈对电机过调制理解
  3. Qt QSS常用样式总结
  4. Unity3D中关于SendMessage的三种用法
  5. 计算机桌面图标变小了怎么恢复,window_win7电脑桌面图标变大怎么恢复?win7桌面图标怎么变小?,win7电脑桌面图标变大怎么恢复 - phpStudy...
  6. java东风破笑傲江湖游戏下载_笑傲江湖游戏
  7. Cortex-A7 常用汇编指令
  8. 关于召开2023第81届中国教育装备展示会通知
  9. uniAPP tabBar 设置
  10. layui ,弹出层修改颜色