[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);
}