吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 517|回复: 5
上一主题 下一主题
收起左侧

[C&C++ 原创] 内存特征码暴力搜索算法支持 ?? F? ?F

  [复制链接]
跳转到指定楼层
楼主
wtujoxk 发表于 2024-11-16 15:24 回帖奖励
本帖最后由 wtujoxk 于 2024-11-17 12:34 编辑

核心算法来自:https://www.52pojie.cn/thread-1961155-1-1.html
SSE2需要硬件支持,但有极个别设备不支持,故做一个纯软运行……

①通过掩码的方式使其支持 前、中、后通配符 及半字节;
②通过循环找到特征码字节序列中的第一个不为'??'的元素后,后续的字节只比较不是'??'的特征字节,优化比较字节数。

代码:
[C++] 纯文本查看 复制代码
#include <iostream>
#include <windows.h>
#include <vector>
#include <Psapi.h>

/// <summary>
/// 内存搜索算法
/// </summary>
/// <param name="startAddress">起始地址</param>
/// <param name="endAddress">结束地址</param>
/// <param name="patternStr">特征码字符串</param>
/// <param name="searchNum">搜索个数,0不限制</param>
/// <returns>搜索到的地地集合</returns>
std::vector<ULONG_PTR> SearchMemory(ULONG_PTR startAddress, ULONG_PTR endAddress, const char* patternStr, ULONG_PTR searchNum)
{
	std::vector<ULONG_PTR> resultList;
	std::string pattern = patternStr;
	int index = 0;
	while ((index = pattern.find(' ', index)) >= 0) pattern.erase(index, 1); //去除特征码所有空格
	ULONG_PTR len = pattern.length() / 2; //计算特征码长度
	ULONG_PTR nFirstMatch = len;  // 跳过头部??,记录第一次匹配的位置半字符或非??,用于优化搜索
	BYTE* pMarkCode = new BYTE[len];  // 存储转换后的特征码字节
	BYTE* pWildcard = new BYTE[len];  // 存储特征字符串中??、?(??=FF、?=F、非?=0) 通配符

	//处理特征码字符串,转换成字节数组
	for (ULONG_PTR i = 0; i < len; i++)
	{
		std::string tmpStr = pattern.substr(i * 2, 2);
		if ("??" == tmpStr) // 是"??"的特征字符
		{
			tmpStr = "FF";
			pWildcard[i] = 0xFF;
		}
		else  // 不是"??"的特征字符
		{
			if ('?' == tmpStr[0]) // 左半字节为'?'
			{
				tmpStr[0] = 'F';
				pWildcard[i] = (0xF << 4);
			}
			else if ('?' == tmpStr[1]) // 右半字节为'?'
			{
				tmpStr[1] = 'F';
				pWildcard[i] = 0xF;
			}
			else
			{
				pWildcard[i] = 0x0;
			}
			if (nFirstMatch == len)	nFirstMatch = i;
		}

		pMarkCode[i] = strtoul(tmpStr.c_str(), nullptr, 16);
	}

	ULONG_PTR nMemSize = endAddress - startAddress; //计算内存大小
	BYTE* pMemBuffer = new BYTE[nMemSize]; // 存放内存数据的缓冲区
	memcpy(pMemBuffer, (void*)startAddress, nMemSize);
	//跨进程搜索内存,可使用ReadProcessMemory函数,目标进程用参数传入
	//ReadProcessMemory((HANDLE)-1, (void*)startAddress, pMemBuffer, nMemSize, 0);

	//搜索内存,匹配特征码算法
	for (ULONG_PTR m = 0; m < nMemSize; ++m)
	{
		if (!((pMemBuffer[m] | pWildcard[nFirstMatch]) ^ pMarkCode[nFirstMatch])) //匹配上第一个字节
		{
			ULONG_PTR offset = m - nFirstMatch; //记录偏移量
			for (ULONG_PTR n = nFirstMatch; n < len; ++n) //匹配后续字节
			{
				if (offset > nMemSize - len) break; //超出内存范围
				if (pWildcard[n] != 0xFF)  //后续字节是"??"的通配符,跳过,这句代码可以优化搜索
					if ((pMemBuffer[offset + n] | pWildcard[n]) ^ pMarkCode[n]) break; //匹配失败
				if (n + 1 == len) //匹配成功
				{
					if ((ULONG_PTR)pMarkCode != startAddress + offset) // 排除自己
						resultList.push_back(startAddress + offset);
					if (resultList.size() >= searchNum && searchNum != 0) goto endSearchMemory; //限制搜索数量
				}
			}
		}
	}
endSearchMemory:
	delete[] pMarkCode; pMarkCode = nullptr;
	delete[] pWildcard; pWildcard = nullptr;
	delete[] pMemBuffer; pMemBuffer = nullptr;
	return resultList;
}

int main()
{
	//特征码为:?9 ?? 0? ?? 67
	//会处理成:F9 FF 0F FF 67 进行匹配
	//通配符为:F0 FF 0F FF 00
	const char* pattern = "?9 ?? 0? ?? 67 ";

	// 获取进程模块内存信息
	MODULEINFO moduleInfo = { };
	GetModuleInformation((HANDLE)-1, GetModuleHandle(L"ntdll.dll"), &moduleInfo, sizeof(moduleInfo));
	ULONG_PTR startAddress = (ULONG_PTR)moduleInfo.lpBaseOfDll; //模块起始地址
	ULONG_PTR endAddress = startAddress + moduleInfo.SizeOfImage; //模块结束地址

	clock_t nBeginTime = clock();
	// 调用内存搜索算法
	std::vector<ULONG_PTR> resultList = SearchMemory(startAddress, endAddress, pattern, 0);
	printf("共搜到:%d个地址-->搜索时间:%d ms\n", resultList.size(), clock() - nBeginTime);

	for (ULONG_PTR i = 0; i < resultList.size(); ++i)
	{
		printf("第%d个:%IX\n", i + 1, resultList[i]);
	}
	system("pause");
	return 0;
}

免费评分

参与人数 3威望 +1 吾爱币 +22 热心值 +3 收起 理由
苏紫方璇 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
laozhang4201 + 1 + 1 我很赞同!
伟大的卓哥 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
freecat 发表于 2024-11-16 16:17
不错 收藏 学习了 谢谢
3#
lyn1875 发表于 2024-11-16 16:43
4#
wufei00 发表于 2024-11-16 20:00
5#
michael137 发表于 2024-11-17 14:13
感谢分享,很有用
6#
PaulYangss 发表于 2024-11-18 11:58
非常实用哈哈
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 07:20

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表