2019-03-21 20:18:31 +01:00
|
|
|
#include "pattern.hpp"
|
|
|
|
|
2023-03-01 21:27:15 +00:00
|
|
|
#include "../common.hpp"
|
|
|
|
|
2019-03-21 20:18:31 +01:00
|
|
|
namespace memory
|
|
|
|
{
|
2023-07-20 22:46:32 +02:00
|
|
|
std::optional<uint8_t> to_hex(char const c)
|
2019-03-21 20:18:31 +01:00
|
|
|
{
|
2022-10-15 19:50:28 -04:00
|
|
|
switch (c)
|
2019-03-21 20:18:31 +01:00
|
|
|
{
|
2023-07-20 22:46:32 +02:00
|
|
|
case '0': return static_cast<uint8_t>(0x0);
|
|
|
|
case '1': return static_cast<uint8_t>(0x1);
|
|
|
|
case '2': return static_cast<uint8_t>(0x2);
|
|
|
|
case '3': return static_cast<uint8_t>(0x3);
|
|
|
|
case '4': return static_cast<uint8_t>(0x4);
|
|
|
|
case '5': return static_cast<uint8_t>(0x5);
|
|
|
|
case '6': return static_cast<uint8_t>(0x6);
|
|
|
|
case '7': return static_cast<uint8_t>(0x7);
|
|
|
|
case '8': return static_cast<uint8_t>(0x8);
|
|
|
|
case '9': return static_cast<uint8_t>(0x9);
|
|
|
|
case 'a': return static_cast<uint8_t>(0xa);
|
|
|
|
case 'b': return static_cast<uint8_t>(0xb);
|
|
|
|
case 'c': return static_cast<uint8_t>(0xc);
|
|
|
|
case 'd': return static_cast<uint8_t>(0xd);
|
|
|
|
case 'e': return static_cast<uint8_t>(0xe);
|
|
|
|
case 'f': return static_cast<uint8_t>(0xf);
|
|
|
|
case 'A': return static_cast<uint8_t>(0xA);
|
|
|
|
case 'B': return static_cast<uint8_t>(0xB);
|
|
|
|
case 'C': return static_cast<uint8_t>(0xC);
|
|
|
|
case 'D': return static_cast<uint8_t>(0xD);
|
|
|
|
case 'E': return static_cast<uint8_t>(0xE);
|
|
|
|
case 'F': return static_cast<uint8_t>(0xF);
|
2023-03-01 21:27:15 +00:00
|
|
|
default: return std::nullopt;
|
2022-10-15 19:50:28 -04:00
|
|
|
}
|
|
|
|
}
|
2019-03-21 20:18:31 +01:00
|
|
|
|
2022-10-15 19:50:28 -04:00
|
|
|
pattern::pattern(std::string_view ida_sig)
|
|
|
|
{
|
|
|
|
const auto size = ida_sig.size();
|
|
|
|
for (std::size_t i{}; i != size; ++i)
|
2019-03-21 20:18:31 +01:00
|
|
|
{
|
|
|
|
if (ida_sig[i] == ' ')
|
|
|
|
continue;
|
|
|
|
bool last = (i == ida_sig.size() - 1);
|
|
|
|
if (ida_sig[i] != '?')
|
|
|
|
{
|
|
|
|
if (!last)
|
|
|
|
{
|
|
|
|
auto c1 = to_hex(ida_sig[i]);
|
|
|
|
auto c2 = to_hex(ida_sig[i + 1]);
|
|
|
|
if (c1 && c2)
|
|
|
|
{
|
2023-07-20 22:46:32 +02:00
|
|
|
m_bytes.emplace_back(static_cast<uint8_t>((*c1 * 0x10) + *c2));
|
2019-03-21 20:18:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-10-15 19:50:28 -04:00
|
|
|
m_bytes.push_back({});
|
2023-01-18 19:02:23 +00:00
|
|
|
|
|
|
|
// add support for double question mark sigs
|
|
|
|
if (ida_sig[i + 1] == '?')
|
|
|
|
{
|
|
|
|
++i;
|
|
|
|
}
|
2019-03-21 20:18:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-01 21:27:15 +00:00
|
|
|
pattern::pattern(const void* bytes, std::string_view mask)
|
2019-03-21 20:18:31 +01:00
|
|
|
{
|
2022-10-15 19:50:28 -04:00
|
|
|
const auto size = mask.size();
|
|
|
|
for (std::size_t i{}; i != size; ++i)
|
2019-03-21 20:18:31 +01:00
|
|
|
{
|
|
|
|
if (mask[i] != '?')
|
2023-07-20 22:46:32 +02:00
|
|
|
m_bytes.emplace_back(static_cast<const uint8_t*>(bytes)[i]);
|
2019-03-21 20:18:31 +01:00
|
|
|
else
|
|
|
|
m_bytes.push_back(std::nullopt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|