找回密码
  注册[Register]
查看: 241|回复: 5

[vc] C/C++ 高性能特征码定位

[复制链接]
发表于 2022-4-18 16:29 来自手机 | 显示全部楼层 |阅读模式
禁止求评分、诱导评分、互刷评分、互刷悬赏值,违规者封号处理。
禁止发布推广、邀请码、邀请链接、二维码或者有利益相关的任何推广行为。
所有非原创软件请发布在【精品软件区】,发帖必须按照本版块版规格式发帖。

特征码格式: AA BB ?? DD ?? FF (与OD一致),若想其替代别的通配符,请自行修改。
[C++] 纯文本查看 复制代码
#include <string>
#include <algorithm>
#include <array>
#include <immintrin.h>
 
static constexpr char charhexset[] = "0123456789ABCDEFabcdef";
typedef unsigned int                u32;
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
typedef long long               s96;
typedef unsigned long long      u96;
#else
typedef int                     s96;
typedef unsigned int            u96;
#endif
static bool StringReplace(std::string& source, const std::string& delimiters, const std::string& dispose = "", const std::size_t offset = 1)
{
    if (source.empty())
    {
        return false;
    }
 
    if (delimiters.empty())
    {
        return true;
    }
 
    for (std::string::size_type pos = source.find(delimiters); pos != std::string::npos; pos = source.find(delimiters))
    {
        if (source.replace(pos, offset, dispose).size())
        {
            continue;
        }
        return false;
    }
 
    return true;
}
 
static bool Hexadec2xdigit(const std::string& data, std::string& buffer, std::size_t offset)
{
    if (data.empty())
    {
        return false;
    }
 
    for (std::size_t i = 0; i < data.size(); i += offset)
    {
        if (std::isxdigit(data[i]))
        {
            buffer += static_cast<char>(std::stoul(data.substr(i, offset), nullptr, 16));
        }
        else
        {
            buffer += 'X';
        }
    }
 
    return true;
}
 
static bool Hexadec2xdigitEx(const std::string& data, std::string& buffer, u32 checkxdigit = 0, u32 transform = 1)
{
    if (data.empty())
    {
        return false;
    }
 
    std::string masks(data);
    {
        // 去掉 0x 去掉 空格
        if (StringReplace(masks, "0x") && StringReplace(masks, " "))
        {
            // 大小写转换
            if (masks.end() == (1 == transform ? std::transform(masks.begin(), masks.end(), masks.begin(), [] (unsigned char ch) { return toupper(ch); }) : std::transform(masks.begin(), masks.end(), masks.begin(), [] (unsigned char ch) { return tolower(ch); })))
            {
                // 检查是否是完整的十六进制数
                if (checkxdigit)
                {
                    if (std::string::npos != masks.find_first_not_of(charhexset))
                    {
                        return false;
                    }
                }
 
                return Hexadec2xdigit(static_cast<const std::string&>(masks), buffer, 2);
            }
        }
    }
 
    return false;
}
 
static bool SearchPattern(const unsigned char* pos, const std::string& chars)
{
    for (std::string::const_iterator xdigit = chars.cbegin(); xdigit != chars.cend(); ++xdigit, ++pos)
    {
        if (*pos != static_cast<const unsigned char>(*xdigit) &&     // no match
            'X' != static_cast<const unsigned char>(*xdigit))        // filter out arbitrary characters
        {
            return false;
        }
        else
        {
            // hit character
            continue;
        }
    }
 
    return true;
}
 
static bool SearchPattern(const void* start,                    // start address
                          const void* end,                      // end address
                          const std::string& keyword,           // characteristic code
                          std::size_t index,                    // take out the serial number
                          void*& address)                       // return to address
{
    if (keyword.empty())
    {
        return false;
    }
 
    if (start != end && static_cast<const unsigned char*>(end) > static_cast<const unsigned char*>(start) && static_cast<std::size_t>(static_cast<const unsigned char*>(end) - static_cast<const unsigned char*>(start)) > keyword.size())
    {
        std::string chars;
        {
            if (Hexadec2xdigitEx(keyword, chars, 0))
            {
                for (auto [pos, i] = std::make_tuple(static_cast<const unsigned char*>(start), static_cast<std::size_t>(0)); pos <= end; ++pos)
                {
                    if (SearchPattern(pos, chars))
                    {
                        if (++i != index)
                        {
                            continue;
                        }
                        else
                        {
                            address = const_cast<void*>(reinterpret_cast<const void*>(pos));
                        }
 
                        return true;
                    }
                }
            }
        }
    }
 
    return false;
}
 
static bool SearchPattern(const u96 start, const u96 end, const std::string& keyword, std::size_t index, void*& address)
{
    return SearchPattern(reinterpret_cast<const void*>(start), reinterpret_cast<const void*>(end), keyword, index, address);
}
 
static bool SearchPatternEx(const void* start, const void* end, const std::string& chars, std::size_t index, std::size_t count, void*& address)
{
    for (auto [masks, i, n, pos] = std::make_tuple(std::array<std::size_t, 32>{}, static_cast<std::size_t>(0), static_cast<std::size_t>(0), static_cast<const unsigned char*>(start)); i < count; ++i)
    {
        for (std::size_t j = 0; j < 16 && n < chars.size(); ++j, ++n)
        {
            if ('X' != static_cast<const char*>(chars.c_str() + i * 16)[j])
            {
                masks[i] |= static_cast<std::size_t>(1) << j;
            }
        }
 
        for (auto [store, j] = std::make_tuple(_mm_loadu_si128(reinterpret_cast<const __m128i *>(chars.c_str() + i * 16)), static_cast<std::size_t>(0)); pos <= end; _mm_prefetch(reinterpret_cast<const char*>(++pos + 64), _MM_HINT_NTA))
        {
            if (static_cast<std::size_t>(static_cast<std::size_t>(_mm_movemask_epi8(_mm_cmpeq_epi8(_mm_loadu_si128(reinterpret_cast<const __m128i *>(pos + i * 16)), store))) & masks[i]) == masks[i])
            {
                if (n < chars.size())
                {
                    break;
                }
 
                if (++j != index)
                {
                    continue;
                }
                else
                {
                    address = const_cast<void*>(reinterpret_cast<const void*>(pos));
                }
 
                return true;
            }
        }
    }
 
    return false;
}
 
static bool SearchPatternEx(const void* start, const void* end, const std::string& keyword, std::size_t index, void*& address)
{
    if (keyword.empty())
    {
        return false;
    }
 
    if (start != end && static_cast<const unsigned char*>(end) > static_cast<const unsigned char*>(start) && static_cast<std::size_t>(static_cast<const unsigned char*>(end) - static_cast<const unsigned char*>(start)) > keyword.size())
    {
        std::string chars;
        {
            if (Hexadec2xdigitEx(keyword, chars, 0))
            {
                return SearchPatternEx(start, end, chars, index, static_cast<std::size_t>((((chars.size()) + (16 - 1)) & ~(16 - 1)) >> 4), address);
            }
        }
    }
 
    return false;
}
 
static bool SearchPatternEx(const u96 start, const u96 end, const std::string& keyword, std::size_t index, void*& address)
{
    return SearchPatternEx(reinterpret_cast<const void*>(start), reinterpret_cast<const void*>(end), keyword, index, address);
}

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2022-4-18 16:29 | 显示全部楼层

支持楼主,谢谢分享。
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2022-4-18 16:29 | 显示全部楼层
先收藏了,万一用到呢
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2022-4-18 16:37 | 显示全部楼层
谢谢大牛
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2022-4-18 16:38 | 显示全部楼层
谢谢大佬
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

发表于 2022-4-18 19:45 | 显示全部楼层
谢谢分享,必须支持
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心值】和【牛币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 有用 没用

使用道具 举报

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

RSS订阅|手机版|小黑屋|大牛论坛 |我的广告

GMT+8, 2024-4-29 20:23 , Processed in 0.042924 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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