首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C/C++ 实现内存特征码搜索

C/C++ 实现内存特征码搜索

作者头像
王瑞MVP
发布2022-12-28 17:47:59
发布2022-12-28 17:47:59
1.2K00
代码可运行
举报
运行总次数:0
代码可运行

实现内存特征码扫描,此种扫描方式支持模糊匹配,可使用??代替模糊匹配数值。

代码语言:javascript
代码运行次数:0
运行
复制
#include<Windows.h>
#include<iostream>
#include<vector>
#include<time.h>
 
using namespace std;
 
#define BLOCKMAXSIZE 409600//每次读取内存的最大大小
BYTE* MemoryData;//每次将读取的内存读入这里
short Next[260];
 
//特征码转字节集
WORD GetTzmArray(char* Tzm, WORD* TzmArray)
{
	int len = 0;
	WORD TzmLength = strlen(Tzm) / 3 + 1;
 
	for (int i = 0; i < strlen(Tzm); )//将十六进制特征码转为十进制
	{
		char num[2];
		num[0] = Tzm[i++];
		num[1] = Tzm[i++];
		i++;
		if (num[0] != '?' && num[1] != '?')
		{
			int sum = 0;
			WORD a[2];
			for (int i = 0; i < 2; i++)
			{
				if (num[i] >= '0' && num[i] <= '9')
				{
					a[i] = num[i] - '0';
				}
				else if (num[i] >= 'a' && num[i] <= 'z')
				{
					a[i] = num[i] - 87;
				}
				else if (num[i] >= 'A' && num[i] <= 'Z')
				{
					a[i] = num[i] - 55;
				}
 
			}
			sum = a[0] * 16 + a[1];
			TzmArray[len++] = sum;
		}
		else
		{
			TzmArray[len++] = 256;
		}
	}
	return TzmLength;
}
 
//获取Next数组
void GetNext(short* next, WORD* Tzm, WORD TzmLength)
{
	//特征码(字节集)的每个字节的范围在0-255(0-FF)之间,256用来表示问号,到260是为了防止越界
	for (int i = 0; i < 260; i++)
		next[i] = -1;
	for (int i = 0; i < TzmLength; i++)
		next[Tzm[i]] = i;
}
 
//搜索一块内存
void SearchMemoryBlock(HANDLE hProcess, WORD* Tzm, WORD TzmLength, unsigned __int64 StartAddress, unsigned long size, vector<unsigned __int64>& ResultArray)
{
	if (!ReadProcessMemory(hProcess, (LPCVOID)StartAddress, MemoryData, size, NULL))
	{
		return;
	}
 
	for (int i = 0, j, k; i < size;)
	{
		j = i; k = 0;
 
		for (; k < TzmLength && j < size && (Tzm[k] == MemoryData[j] || Tzm[k] == 256); k++, j++);
 
		if (k == TzmLength)
		{
			ResultArray.push_back(StartAddress + i);
		}
 
		if ((i + TzmLength) >= size)
		{
			return;
		}
 
		int num = Next[MemoryData[i + TzmLength]];
		if (num == -1)
			i += (TzmLength - Next[256]);//如果特征码有问号,就从问号处开始匹配,如果没有就i+=-1
		else
			i += (TzmLength - num);
	}
}
 
//搜索整个程序
int SearchMemory(HANDLE hProcess, char* Tzm, unsigned __int64 StartAddress, unsigned __int64 EndAddress, int InitSize, vector<unsigned __int64>& ResultArray)
{
	int i = 0;
	unsigned long BlockSize;
	MEMORY_BASIC_INFORMATION mbi;
 
	WORD TzmLength = strlen(Tzm) / 3 + 1;
	WORD* TzmArray = new WORD[TzmLength];
 
	GetTzmArray(Tzm, TzmArray);
	GetNext(Next, TzmArray, TzmLength);
 
	//初始化结果数组
	ResultArray.clear();
	ResultArray.reserve(InitSize);
 
	while (VirtualQueryEx(hProcess, (LPCVOID)StartAddress, &mbi, sizeof(mbi)) != 0)
	{
		//获取可读可写和可读可写可执行的内存块
		if (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_EXECUTE_READWRITE)
		{
			i = 0;
			BlockSize = mbi.RegionSize;
			//搜索这块内存
			while (BlockSize >= BLOCKMAXSIZE)
			{
				SearchMemoryBlock(hProcess, TzmArray, TzmLength, StartAddress + (BLOCKMAXSIZE * i), BLOCKMAXSIZE, ResultArray);
				BlockSize -= BLOCKMAXSIZE; i++;
			}
			SearchMemoryBlock(hProcess, TzmArray, TzmLength, StartAddress + (BLOCKMAXSIZE * i), BlockSize, ResultArray);
 
		}
		StartAddress += mbi.RegionSize;
 
		if (EndAddress != 0 && StartAddress > EndAddress)
		{
			return ResultArray.size();
		}
	}
	free(TzmArray);
	return ResultArray.size();
}
 
int main()
{
	//初始化MemoryData大小
	MemoryData = new BYTE[BLOCKMAXSIZE];
 
	DWORD pid=0;
	vector<unsigned __int64> ResultArray;
	
	cout << "请输入进程ID:" << endl;
	cin >> pid;
 
	//通过进程ID获取进程句柄
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
 
	int start = clock();
	SearchMemory(hProcess, (char*)"FF 3F FF ?? FF F2", 0x410000, 0xFFFFFFFF, 30, ResultArray);
	int end = clock();
 
	cout << "用时:" << end-start << "毫秒"<<endl;
	cout << "搜索到" << ResultArray.size() << "个结果" << endl;
 
	for (vector<unsigned __int64>::iterator it = ResultArray.begin(); it != ResultArray.end(); it++)
	{
		printf("%x\n", *it);
	}
 
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档