吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1786|回复: 16
收起左侧

[求助] 各位老师,C++用特征码读取内存地址(支持通配符“??”),速度太慢咋优化?

[复制链接]
jtwc 发表于 2022-4-22 14:46
本帖最后由 jtwc 于 2022-4-22 14:51 编辑

各位老师,网上找了一个C++用特征码读取内存地址(支持通配符“??”)的源码,经过“HULANG-BTB”老师修改后完美解决了报错问题。但3-5分钟才读出一个地址,速度太慢咋优化?哪位老师有兴趣用算法优化一下?谢谢了。修改后源码如下:
[C++] 纯文本查看 复制代码
#include <Windows.h>
#include <iostream>
#include <vector>
#include <time.h>
 
using namespace std;
 
#define BLOCKMAXSIZE 409600//每次读取内存的最大大小
BYTE* MemoryData;//每次将读取的内存读入这里
short Next[260];
 
bool isHexCharacter(char c) {
    return (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9');
}
 
// 十六进制转10进制
// 1 2 3 4 5 6 7 8 9 A B C D E F
WORD hexToWord(char c) {
    if (c >= '0' && c <= '9') {
        return c - '0';
    }
    else if (c >= 'A' && c <= 'F') {
        return c - 'A' + 10;
    }
    else if (c >= 'a' && c<= 'f') {
        return c - 'a' + 10;
    }
    return -1;
};
 
// 十六进制转10进制
WORD hexToWord(char c1, char c2) {
    if (isHexCharacter(c1) && isHexCharacter(c2)) 
        return hexToWord(c1) * 16 + hexToWord(c2);
    return 256;
}
 
// 特征码转字节集
WORD GetTzmArray(char* Tzm, vector<WORD> & TzmArray)
{
    int TzmLength = strlen(Tzm);
    for (int i = 0; i < TzmLength; i += 3) {
        TzmArray.push_back(hexToWord(Tzm[i], Tzm[i + 1]));
    }
    return TzmArray.size();
}
 
//获取Next数组
void GetNext(short* next, vector<WORD> TzmArray)
{
    //特征码(字节集)的每个字节的范围在0-255(0-FF)之间,256用来表示问号,到260是为了防止越界
    for (int i = 0; i < 260; i++)
        next[i] = -1;
    for (int i = 0; i < TzmArray.size(); i++)
        next[TzmArray[i]] = i;
}
 
//搜索一块内存
void SearchMemoryBlock(HANDLE hProcess, vector<WORD> TzmArray, 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 < TzmArray.size() && j < size && (TzmArray[k] == MemoryData[j] || TzmArray[k] == 256); k++, j++);
 
        if (k == TzmArray.size())
        {
            ResultArray.push_back(StartAddress + i);
        }
 
        if ((i + TzmArray.size()) >= size)
        {
            return;
        }
 
        int num = Next[MemoryData[i + TzmArray.size()]];
        if (num == -1)
            i += (TzmArray.size() - Next[256]);//如果特征码有问号,就从问号处开始匹配,如果没有就i+=-1
        else
            i += (TzmArray.size() - 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;
 
    vector<WORD> TzmArray;
    GetTzmArray(Tzm, TzmArray);
    GetNext(Next, TzmArray);
 
    //初始化结果数组
    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, StartAddress + (BLOCKMAXSIZE * i), BLOCKMAXSIZE, ResultArray);
                BlockSize -= BLOCKMAXSIZE; i++;
            }
            SearchMemoryBlock(hProcess, TzmArray, StartAddress + (BLOCKMAXSIZE * i), BlockSize, ResultArray);
 
        }
        StartAddress += mbi.RegionSize;
 
        if (EndAddress != 0 && StartAddress > EndAddress)
        {
            return ResultArray.size();
        }
    }
    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*)"?? ?? ?? ?? ?? ?? ?? 40 05 00 00 00 38 AF 40 FF 76 02 00 00 ", 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;
}

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

JuncoJet 发表于 2022-4-22 14:53
首先确定串的长度,匹配首字符,再匹配尾字符,不对的时候就可以长跳
多看看 kmp bm sunday算法
 楼主| jtwc 发表于 2022-4-22 14:55
JuncoJet 发表于 2022-4-22 14:53
首先确定串的长度,匹配首字符,再匹配尾字符,不对的时候就可以长跳
多看看 kmp bm sunday算法

老师,谢谢了,这个目前对我来说有难度
有时候是好人 发表于 2022-4-22 14:55
 楼主| jtwc 发表于 2022-4-22 15:00
有时候是好人 发表于 2022-4-22 14:55
能看到自己的资料嘛?

老师,啥意思?
HULANG-BTB 发表于 2022-4-22 15:08
1、通配符不要放在特征值的头部和尾部
2、试用kmp和sunday算法进行模式匹配
天下一家 发表于 2022-4-22 15:08
电脑  再跑得 慢,也不会 3-5分钟吧,3-5秒就应该 找到1个了。
 楼主| jtwc 发表于 2022-4-22 15:20
天下一家 发表于 2022-4-22 15:08
电脑  再跑得 慢,也不会 3-5分钟吧,3-5秒就应该 找到1个了。

老师,真没有夸张,CE秒出,下图还是速度比较快的
1.png
小小随 发表于 2022-4-22 15:33
jtwc 发表于 2022-4-22 15:20
老师,真没有夸张,CE秒出,下图还是速度比较快的

https://www.52pojie.cn/thread-1623689-1-1.html
 楼主| jtwc 发表于 2022-4-22 16:27
小小随 发表于 2022-4-22 15:33
https://www.52pojie.cn/thread-1623689-1-1.html

谢谢老师,我试试
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-25 12:34

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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