The most powerful and customizable binary pattern scanner written on modern C++

Related tags

Utilities Sig
Overview

Sig

The most powerful and customizable binary pattern scanner written on modern C++

Capabilities:

  • Support for all common pattern formats:
    • Pattern + mask: "\x11\x22\x00\x44" + "..?."
    • One-line pattern: "11 22 ? AA BB ? ? EE FF"
    • Bitmask + valuable bits mask: "\x11\x13\x33" + "\xFF\x1F\xFF"
  • Support for template-based patterns:
    • Sig::find <1, 2, 3>, Sig::Dword<>, Sig::StrEq<"text">>(buf, size);
  • Support for custom comparators.
  • Extensible and customizable patterns.
  • Header-only.
  • Modern C++ (requires C++17 or above (and requires C++20 for Sig::StrEq<"text">)).
  • Works in usermode and kernelmode on Windows, Linux and MacOS.
  • Unit-tests.

🙏 Special thanks to:

🔍 Overview of pattern types:

, Sig::Mask::Any<'?'>, Sig::Mask::BitMask<'m'> >(buf, size, "\x11\x22\x19\x44", "\x00\x00\x1F\x00", "..m.?."); // Bitmask + mask of meaningful bits in the bitmask: Sig::bitmask(buf, size, "\x11\x22\x19", "\xFF\xFF\x1F"); // One line: Sig::find(buf, size, "11 22 ? 44 ?? 66 AA bb cC Dd"); ">
// Template-based:
Sig::find
   Byte<
   0xAA, 
   0xBB>, Sig::Dword<>, Sig::Char<
   't', 
   'e', 
   'x', 
   't'>>(buf, size);
Sig::find
   
    
     1, 
     2, 
     3>>(buf, size);


     // Pattern + Mask:
Sig::find
     
      <
      '.'>, Sig::Mask::Any<
      '?'>>(buf, size, 
      "\x11\x22\x00\x44", 
      "..?.");


      // Pattern + Subpattern + Mask:
Sig::find<
    Sig::Mask::Eq<
      '.'>,
    Sig::Mask::Any<
      '?'>,
    Sig::Mask::BitMask<
      'm'>
>(buf, size, 
      "\x11\x22\x19\x44", 
      "\x00\x00\x1F\x00", 
      "..m.?.");


      // Bitmask + mask of meaningful bits in the bitmask:

      Sig::bitmask(buf, size, 
      "\x11\x22\x19", 
      "\xFF\xFF\x1F");


      // One line:

      Sig::find(buf, size, 
      "11 22 ? 44 ?? 66 AA bb cC Dd");
     
    
   
  

👾 Template-based patterns:

This type generates a comparing function in compile-time for each pattern:

Sig::find
   (buf, size);
  

There are a lot of predefined tags, comparators and containers:

// Compare the string as-is (not including null-terminator) Sig::StrEqNoCase<"SaMpLe TeXt"> // Case-insensitive comparation (only for English text) // Containers: Sig::Rep // Repeat a tag by a count times, e.g. Sig::Rep <0xFF>, 3> to compare with \xFF\xFF\xFF Sig::Set // Check an equality with one of defined tags, e.g. Sig::Set <1>, Sig::Dword<-1u>> Sig::Range // Check whether a value is in a range [from, to], e.g. Sig::Range Sig::Compound // A storage for creating user defined patterns /* Examples */ // Find the sequence of bytes (0x01 0x02 0x03): Sig::find <1, 2, 3>>(buf, size); // Find the sequence with a couple of unknown bytes (0x01 0x02 ? 0x04): Sig::find <1, 2>, Sig::Byte<>, Sig::Byte<4>>(buf, size); // ^ Any byte // Find the null-terminated strings: Sig::find< Sig::StrEq<"text">, Sig::Char<0x00>, // ASCII-compatible string Sig::StrEqNoCase , Sig::WChar<0x0000> // UTF-16 string >(buf, size); // Using different comparators: Sig::find< Sig::Byte<0xAA>, // (pos[0] == 0xAA) && Sig::CmpByte , // (pos[1] != 0xBB) && (pos[2] != 0xCC) && Sig::CmpDword // (*(dword*)&pos[3] > 0x1EE7C0DE) >(buf, size); // Find the matching bits: Sig::find< Sig::Byte<1>, // (pos[0] == 1) && Sig::ByteMask<0b110100, 0b111101> // (pos[2] == 0b??1101?0) >(buf, size); // Using the Sig::Rep (find the repeating pattern): const uint8_t buf[]{ 1, 2, 3, 'r', 'r', 'r', 'r', 'r', 4, 5 }; Sig::find <'r'>, 5>>(buf, sizeof(buf)); // Using the Sig::Set (find one of the tags): const uint8_t buf[]{ '?', 0xDE, 0xC0, 0xE7, 0x1E, '!' }; Sig::find <1>, Sig::Dword<0x1EE7C0DE>>, Sig::Char<'!'>>(buf, sizeof(buf)); // ^ It is either the Sig::Byte<1> or the Sig::Dword<0x1EE7C0DE>. // The next position will be the current pos + size of matched tag. // Using the Sig::Range (from..to): const uint8_t buf[]{ 10, 20, 30, 40, 50 }; Sig::find >(buf, sizeof(buf)); // ^ The value must be in the range [29 >= x >= 31] // Using the Sig::Compound (user-defined patterns): const uint8_t buf[]{ '?', '?', 0xE9, 0x11, 0x22, 0x33, 0x44, '?', 0x0F, 0x05 }; using RelJump = Sig::Compound <0xE9>, Sig::Dword<>>; // E9 ?? ?? ?? ?? | jmp unknown_offset using Syscall = Sig::Compound <0x0F, 0x05>>; // 0F 05 | syscall Sig::find , Syscall>(buf, sizeof(buf)); // Using the comparator that doesn't depend on pattern: template struct IsOddCmp : Sig::RawCmp { static bool cmp(const void* const pos) { return (*static_cast (pos) % 2) != 0; } }; using IsOddByte = IsOddCmp ; const uint8_t buf[]{ 2, 4, 6, 7, 8, 10, 12 }; Sig::find (buf, sizeof(buf)); // Using the comparator that depends on pattern: template struct IsDivisibleByCmp { static bool cmp(const void* const pos) { return (*static_cast (pos) % val) == 0; } }; template using IsDivisibleByByte = IsDivisibleByCmp ; const uint8_t buf[]{ 3, 4, 5, 10, 15, 17 }; Sig::find <5, 10, 5>>(buf, sizeof(buf)); // Usng the custom comparator for the string: template struct StrCmpNoCase : Sig::Str { static bool cmp(const void* const pos) { using Char = typename decltype(str)::Type; const auto* const mem = static_cast (pos); for (size_t i = 0; i < decltype(str)::k_len; ++i) { const auto low = [](const Char ch) -> Char { return ((ch >= static_cast ('A')) && (ch <= static_cast ('Z'))) ? (ch + static_cast ('a' - 'A')) : (ch); }; const auto left = low(mem[i]); const auto right = low(str.str.buf[i]); if (left != right) { return false; } } return true; } }; Sig::find <"ASCII">, StrCmpNoCase >(buf, size); ">
// Tags:
Sig::Byte/Word/Dword/Qword/Int/UInt/Int64/UInt64/Char/WChar/Short/UShort/Long/ULong/LongLong/ULongLong<...>
Sig::Cmp[Byte/Word/...] 
                                          // Like Sig::CmpByte<...>, Sig::CmpDword<...>, etc.
Sig::[
                                          Byte/Word/Dword/Qword]Mask
                                           
                                           // To check whether the specified bits are equal to


                                           // Comparators for Sig::Cmp***
                                            
                                             :
                                            
Sig::Cmp::Eq       
                                           // Equal
Sig::Cmp::NotEq    
                                           // Not equal
Sig::Cmp::Gr       
                                           // Greater
Sig::Cmp::Le       
                                           // Less
Sig::Cmp::GrEq     
                                           // Greater or equal
Sig::Cmp::LeEq     
                                           // Less or equal
Sig::Cmp::OneOf    
                                           // One of a bits is setted ((value & mask) != 0)
Sig::Cmp::AllOf    
                                           // All of a bits are setted ((value & mask) == mask)
Sig::Cmp::BitMask
                                             
                                            // All of the specified bits are equal to the pattern ((val & mean) == (mask & mean))


                                            // Special cases for strings (requires C++20 or above):
Sig::StrEq<
                                            "Sample text">        
                                            // Compare the string as-is (not including null-terminator)
Sig::StrEqNoCase<
                                            "SaMpLe TeXt">  
                                            // Case-insensitive comparation (only for English text)


                                            // Containers:
Sig::Rep
                                              
                                             // Repeat a tag by a count times, e.g. Sig::Rep
                                              
                                               <0xFF>, 3> to compare with \xFF\xFF\xFF
                                              
Sig::Set
                                               
                                              // Check an equality with one of defined tags, e.g. Sig::Set
                                               
                                                <1>, Sig::Dword<-1u>>
                                               
Sig::Range
                                               
                                               // Check whether a value is in a range [from, to], e.g. Sig::Range
                                                 Sig::Compound
                                                
                                                // A storage for creating user defined patterns 
                                                /* Examples */ 
                                                // Find the sequence of bytes (0x01 0x02 0x03): Sig::find
                                                
                                                 Byte<
                                                 1, 
                                                 2, 
                                                 3>>(buf, size); 
                                                 // Find the sequence with a couple of unknown bytes (0x01 0x02 ? 0x04): Sig::find
                                                 
                                                  Byte<
                                                  1, 
                                                  2>, Sig::
                                                  Byte<>, Sig::
                                                  Byte<
                                                  4>>(buf, size); 
                                                  // ^ Any byte 
                                                  // Find the null-terminated strings: Sig::find< Sig::StrEq<
                                                  "text">, Sig::Char<
                                                  0x00>, 
                                                  // ASCII-compatible string Sig::StrEqNoCase<
                                                  L"TeXt">, Sig::WChar<
                                                  0x0000> 
                                                  // UTF-16 string >(buf, size); 
                                                  // Using different comparators: Sig::find< Sig::
                                                  Byte<
                                                  0xAA>, 
                                                  // (pos[0] == 0xAA) && Sig::CmpByte
                                                  
                                                   0xBB, 
                                                   0xCC>, 
                                                   // (pos[1] != 0xBB) && (pos[2] != 0xCC) && Sig::CmpDword
                                                   
                                                    0x1EE7C0DE> 
                                                    // (*(dword*)&pos[3] > 0x1EE7C0DE) >(buf, size); 
                                                    // Find the matching bits: Sig::find< Sig::
                                                    Byte<
                                                    1>, 
                                                    // (pos[0] == 1) && Sig::ByteMask<
                                                    0b110100, 
                                                    0b111101> 
                                                    // (pos[2] == 0b??1101?0) >(buf, size); 
                                                    // Using the Sig::Rep (find the repeating pattern): 
                                                    const 
                                                    uint8_t buf[]{ 
                                                    1, 
                                                    2, 
                                                    3, 
                                                    'r', 
                                                    'r', 
                                                    'r', 
                                                    'r', 
                                                    'r', 
                                                    4, 
                                                    5 }; Sig::find
                                                    
                                                     
                                                      <
                                                      'r'>, 
                                                      5>>(buf, 
                                                      sizeof(buf)); 
                                                      // Using the Sig::Set (find one of the tags): 
                                                      const 
                                                      uint8_t buf[]{ 
                                                      '?', 
                                                      0xDE, 
                                                      0xC0, 
                                                      0xE7, 
                                                      0x1E, 
                                                      '!' }; Sig::find
                                                      
                                                       
                                                        Byte<
                                                        1>, Sig::Dword<
                                                        0x1EE7C0DE>>, Sig::Char<
                                                        '!'>>(buf, 
                                                        sizeof(buf)); 
                                                        // ^ It is either the Sig::Byte<1> or the Sig::Dword<0x1EE7C0DE>. 
                                                        // The next position will be the current pos + size of matched tag. 
                                                        // Using the Sig::Range (from..to): 
                                                        const 
                                                        uint8_t buf[]{ 
                                                        10, 
                                                        20, 
                                                        30, 
                                                        40, 
                                                        50 }; Sig::find
                                                        
                                                         
                                                          Byte, 
                                                          29, 
                                                          31>>(buf, 
                                                          sizeof(buf)); 
                                                          // ^ The value must be in the range [29 >= x >= 31] 
                                                          // Using the Sig::Compound (user-defined patterns): 
                                                          const 
                                                          uint8_t buf[]{ 
                                                          '?', 
                                                          '?', 
                                                          0xE9, 
                                                          0x11, 
                                                          0x22, 
                                                          0x33, 
                                                          0x44, 
                                                          '?', 
                                                          0x0F, 
                                                          0x05 }; 
                                                          using RelJump = Sig::Compound
                                                          
                                                           Byte<
                                                           0xE9>, Sig::Dword<>>; 
                                                           // E9 ?? ?? ?? ?? | jmp unknown_offset 
                                                           using Syscall = Sig::Compound
                                                           
                                                            Byte<
                                                            0x0F, 
                                                            0x05>>; 
                                                            // 0F 05 | syscall Sig::find
                                                            
                                                             Byte<>, Syscall>(buf, 
                                                             sizeof(buf)); 
                                                             // Using the comparator that doesn't depend on pattern: 
                                                             template <
                                                             typename Type> 
                                                             struct 
                                                             IsOddCmp : Sig::RawCmp
                                                             
                                                               { 
                                                              static 
                                                              bool 
                                                              cmp(
                                                              const 
                                                              void* 
                                                              const pos) { 
                                                              return (*
                                                              static_cast<
                                                              const Type*>(pos) % 
                                                              2) != 
                                                              0; } }; 
                                                              using IsOddByte = IsOddCmp<
                                                              unsigned 
                                                              char>; 
                                                              const 
                                                              uint8_t buf[]{ 
                                                              2, 
                                                              4, 
                                                              6, 
                                                              7, 
                                                              8, 
                                                              10, 
                                                              12 }; Sig::find
                                                              
                                                               (buf, 
                                                               sizeof(buf)); 
                                                               // Using the comparator that depends on pattern: 
                                                               template <
                                                               typename Type, Type val> 
                                                               struct 
                                                               IsDivisibleByCmp { 
                                                               static 
                                                               bool 
                                                               cmp(
                                                               const 
                                                               void* 
                                                               const pos) { 
                                                               return (*
                                                               static_cast<
                                                               const Type*>(pos) % val) == 
                                                               0; } }; 
                                                               template <
                                                               unsigned 
                                                               char... values> 
                                                               using IsDivisibleByByte = IsDivisibleByCmp<
                                                               unsigned 
                                                               char, values...>; 
                                                               const 
                                                               uint8_t buf[]{ 
                                                               3, 
                                                               4, 
                                                               5, 
                                                               10, 
                                                               15, 
                                                               17 }; Sig::find
                                                               
                                                                <
                                                                5, 
                                                                10, 
                                                                5>>(buf, 
                                                                sizeof(buf)); 
                                                                // Usng the custom comparator for the string: 
                                                                template 
                                                                 
                                                                 struct 
                                                                 StrCmpNoCase : Sig::Str
                                                                 
                                                                   { 
                                                                  static 
                                                                  bool 
                                                                  cmp(
                                                                  const 
                                                                  void* 
                                                                  const pos) { 
                                                                  using Char = 
                                                                  typename 
                                                                  decltype(str)::Type; 
                                                                  const 
                                                                  auto* 
                                                                  const mem = 
                                                                  static_cast<
                                                                  const Char*>(pos); 
                                                                  for (
                                                                  size_t i = 
                                                                  0; i < 
                                                                  decltype(str)::k_len; ++i) { 
                                                                  const 
                                                                  auto low = [](
                                                                  const Char ch) -> Char { 
                                                                  return ((ch >= 
                                                                  static_cast
                                                                  
                                                                   (
                                                                   'A')) && (ch <= 
                                                                   static_cast
                                                                   
                                                                    (
                                                                    'Z'))) ? (ch + 
                                                                    static_cast
                                                                    
                                                                     (
                                                                     'a' - 
                                                                     'A')) : (ch); }; 
                                                                     const 
                                                                     auto left = 
                                                                     low(mem[i]); 
                                                                     const 
                                                                     auto right = 
                                                                     low(str.
                                                                     str.
                                                                     buf[i]); 
                                                                     if (left != right) { 
                                                                     return 
                                                                     false; } } 
                                                                     return 
                                                                     true; } }; Sig::find
                                                                     
                                                                      <
                                                                      "ASCII">, StrCmpNoCase<
                                                                      L"UTF-16">>(buf, size);
                                                                     
                                                                    
                                                                   
                                                                  
                                                                 
                                                                
                                                               
                                                              
                                                             
                                                            
                                                           
                                                          
                                                         
                                                        
                                                       
                                                      
                                                     
                                                    
                                                   
                                                  
                                                 
                                                
                                               
                                              
                                             
                                            
                                           
                                          
                                         

👻 Pattern + Mask:

It is the common type of pattern format: signature with mask that defines meaningful and meaningless bytes.
E.g.: "\x11\x22\x00\x44" + "..?.".
You can use this format with predefined comparators and define your custom comparators for each mask symbol.

struct IsDivisibleBy : Sig::Mask::MaskCmp { static bool cmp(const char data, const char pattern) { return (data % pattern) == 0; } }; const uint8_t buf[]{ '?', 0x11, 0x22, 0xFF, 0x44, 6, 16, 100, '?' }; Sig::find< Sig::Mask::Eq<'.'>, Sig::Mask::NotEq<'!'>, Sig::Mask::Any<'?'>, IsDivisibleBy<'d'>, >(buf, sizeof(buf), "\x10\x22\x00\x44\x02\x04\x0A", "!.?.ddd"); // Using subpatterns for additional data (e.g., bitmasks): const uint8_t buf[]{ 0xFF, '?', 0b1101'0011, 0x00 }; Sig::find< Sig::Mask::Eq<'.'>, Sig::Mask::BitMask<'m'> >(buf, sizeof(buf), "\xFF\x00\x13\x00", "\x00\x00\x1F\x00", ".?m."); // The meaning: | | // (pos[0] == 0xFF) && +-------+ +-+ Is equivalent to "val == ???1'0011" // (pos[1] == any) && V V // ((pos[2] & 0b0001'1111) == (0b0001'0011 & 0b0001'1111)) && // (pos[3] == 0x00) // The subpattern uses only in extended comparators (e.g. in the Sig::Mask::Bitmask that requires additional info). // Using the custom extended comparator (Sig::Mask::MaskCmpEx, that requires additional pattern): template struct IsInRange : Sig::Mask::MaskCmpEx { static bool cmp(const char data, const char pattern, const char subpattern) { return (data >= pattern) && (data <= subpattern); } }; const uint8_t buf[]{ 0x10, 0x20, 0x30, 0x40, 0x50 }; Sig::find <'r'>>(buf, sizeof(buf), "\x15\x25", "\x25\x35", "rr"); ">
// Predefined comparators (are the same as for template-based patterns),
// they accept a corresponding char in a mask string:
Sig::Mask::Eq       // Equal
Sig::Mask::NotEq    // Not equal
Sig::Mask::Gr       // Greater
Sig::Mask::Le       // Less
Sig::Mask::GrEq     // Greater or equal
Sig::Mask::LeEq     // Less or equal
Sig::Mask::OneOf    // One of a bits is setted ((value & mask) != 0)
Sig::Mask::AllOf    // All of a bits are setted ((value & mask) == mask)
Sig::Mask::BitMask  // All of the specified bits are equal to the pattern ((val & mean) == (mask & mean))

// You must define comparators for all unique chars in a mask, otherwise Sig::find will return nullptr. 

// The simpliest example:
const uint8_t buf[]{ '?', 0x11, 0x22, 0xFF, 0x44 };
Sig::find
       <
       '.'>, Sig::Mask::Any<
       '?'>>(buf, 
       sizeof(buf), 
       "\x11\x22\x00\x44", 
       "..?.");

       //                       |                    ^- The '?' will mean any byte

       //                       + The '.' will mean an exact byte



       // The example above means that the char '.' in the mask is the equality comparator

       // and the char '?' is an any byte.


       // Using the custom basic comparator (Sig::MaskCmp):

       template <
       char mask>

       struct 
       IsDivisibleBy : Sig::Mask::MaskCmp
       
        
{
    
        static 
        bool 
        cmp(
        const 
        char data, 
        const 
        char pattern)
    {
        
        return (data % pattern) == 
        0;
    }
};


        const 
        uint8_t buf[]{ 
        '?', 
        0x11, 
        0x22, 
        0xFF, 
        0x44, 
        6, 
        16, 
        100, 
        '?' };
Sig::find<
    Sig::Mask::Eq<
        '.'>,
    Sig::Mask::NotEq<
        '!'>,
    Sig::Mask::Any<
        '?'>,
    IsDivisibleBy<
        'd'>,
>(buf, 
        sizeof(buf), 
        "\x10\x22\x00\x44\x02\x04\x0A", 
        "!.?.ddd");


        // Using subpatterns for additional data (e.g., bitmasks):

        const 
        uint8_t buf[]{ 
        0xFF, 
        '?', 
        0b1101'0011, 
        0x00 };
Sig::find<
    Sig::Mask::Eq<
        '.'>,
    Sig::Mask::BitMask<
        'm'>
>(buf, 
        sizeof(buf), 
        "\xFF\x00\x13\x00", 
        "\x00\x00\x1F\x00", 
        ".?m.");

        // The meaning:                |                   |

        //   (pos[0] == 0xFF) &&       +-------+           +-+  Is equivalent to "val == ???1'0011"

        //   (pos[1] == any) &&                V             V

        //   ((pos[2] & 0b0001'1111) == (0b0001'0011 & 0b0001'1111)) &&

        //   (pos[3] == 0x00)


        // The subpattern uses only in extended comparators (e.g. in the Sig::Mask::Bitmask that requires additional info).


        // Using the custom extended comparator (Sig::Mask::MaskCmpEx, that requires additional pattern):

        template <
        char mask>

        struct 
        IsInRange : Sig::Mask::MaskCmpEx<
        char>
{
    
        static 
        bool 
        cmp(
        const 
        char data, 
        const 
        char pattern, 
        const 
        char subpattern)
    {
        
        return (data >= pattern) && (data <= subpattern);
    }
};


        const 
        uint8_t buf[]{ 
        0x10, 
        0x20, 
        0x30, 
        0x40, 
        0x50 };
Sig::find
        
         <
         'r'>>(buf, 
         sizeof(buf), 
         "\x15\x25", 
         "\x25\x35", 
         "rr");

        
       
      

🧩 Bitmask:

It is the special case of the "pattern + mask" type that compares equality of the specified bits:

Sig::bitmask(buf, size, "\x11\x13\x33", "\xFF\x1F\xFF", 3);
//                         ^ Bitmask       ^ Valuable bits in the bitmask
// This means:
//  (pos[0] & 0xFF == 0x11 & 0xFF) &&   | pos[0] == 0001'0001
//  (pos[1] & 0x1F == 0x13 & 0x1F) &&   | pos[1] == ???1'0011
//  (pos[2] & 0xFF == 0x33 & 0xFF)      | pos[2] == 0011'0011

😊 One-line patterns:

It is the friendly and easy-to-use type of pattern.
It has no customizations, just one line pattern:

const void* const found = Sig::find(buf, size, "AA BB ?? DD 1 2 ? 4 5 6");

Tokens ?? and ? have the same meaning: any byte.

Usage:

Just include the ./include/Sig/Sig.hpp and you're good to go!

#include <Sig/Sig.hpp>

#include <cassert>

static const unsigned char g_arr[]
{
    '?', '?', '?', '?',
    0x11, 0x22, 0x33, 0x44
};

int main()
{
    const void* const found1 = Sig::find
   <
   0x44332211>>(g_arr, 
   sizeof(g_arr));
    
    
   const 
   void* 
   const found2 = Sig::find<
        Sig::Mask::Eq<
   '.'>,
        Sig::Mask::Any<
   '?'>
    >(g_arr, 
   sizeof(g_arr), 
   "\x11\x22\x00\x44", 
   "..?.");

    
   const 
   void* 
   const found3 = 
   Sig::find(g_arr, 
   sizeof(g_arr), 
   "11 22 ? 44");

    
   assert(found1 == &g_arr[
   4]);
    
   assert(found1 == found2);
    
   assert(found2 == found3);

    
   return 
   0;
}
  
You might also like...
A compile-time enabled Modern C++ library that provides compile-time dimensional analysis and unit/quantity manipulation.

mp-units - A Units Library for C++ The mp-units library is the subject of ISO standardization for C++23/26. More on this can be found in ISO C++ paper

A Template Engine for Modern C++

Inja is a template engine for modern C++, loosely inspired by jinja for python. It has an easy and yet powerful template syntax with all variables, lo

Mustache text templates for modern C++

About Mustache implementation for modern C++ (requires C++11) Header only Zero dependencies Templated string type for compatibility with any STL-like

Pretty Printer for Modern C++
Pretty Printer for Modern C++

Highlights Single header file Requires C++17 MIT License Quick Start Simply include pprint.hpp and you're good to go. #include pprint.hpp To start p

LibOS is a modern C++17 library that makes OS-specific features cross-platform.

LibOS is a modern C++17 library that makes OS-specific features cross-platform. Ever tried to get Windows version after Windows 8? Or to send ke

Windows kernel hacking framework, driver template, hypervisor and API written on C++

Windows kernel hacking framework, driver template, hypervisor and API written on C++

A 2D collision detection and physics library written in C.
A 2D collision detection and physics library written in C.

A 2D collision detection and physics library written in C. WARNING: This library is in an early alpha stage, use it at your own risk. Documentation —

Tool based in nodes to build GLSL shaders without any programming knowledge written in C using OpenGL and GLFW.
Tool based in nodes to build GLSL shaders without any programming knowledge written in C using OpenGL and GLFW.

FNode Tool based in nodes to build GLSL shaders without any programming knowledge written in C using OpenGL and GLFW (raylib library). It contains a c

My CS:GO cheat, written with performance in mind.

sinclair_csgo My CS:GO cheat, written with performance in mind. Currently in development, and I plan to keep this as such!

Comments
  • Cant compile with g++ version 11.1.0

    Cant compile with g++ version 11.1.0

    Hi, i tried your example code and sadly cant compile it on linux with g++ 11.1.0 which is the newest for my distro.

    I tried the following code:

    #include "Sig.hpp"
    
    #include <cassert>
    
    static const unsigned char g_arr[]{
        '?', '?', '?', '?',
        0x11, 0x22, 0x33, 0x44};
    
    int main()
    {
        const void *const found1 = Sig::find<Sig::Dword<0x44332211>>(g_arr, sizeof(g_arr));
    
        const void *const found2 = Sig::find<
            Sig::Mask::Eq<'.'>,
            Sig::Mask::Any<'?'>>(g_arr, sizeof(g_arr), "\x11\x22\x00\x44", "..?.");
    
        const void *const found3 = Sig::find(g_arr, sizeof(g_arr), "11 22 ? 44");
    
        assert(found1 == &g_arr[4]);
        assert(found1 == found2);
        assert(found2 == found3);
    
        return 0;
    }
    

    and got these errors:

    In file included from test.cpp:1:
    Sig.hpp:297:15: error: explicit specialization in non-namespace scope ‘struct Sig’
      297 |     template <>
          |               ^
    Sig.hpp:298:12: error: too few template-parameter-lists
      298 |     struct SetComparator<>
          |            ^~~~~~~~~~~~~~~
    Sig.hpp:444:15: error: explicit specialization in non-namespace scope ‘struct Sig’
      444 |     template <>
          |               ^
    Sig.hpp:445:12: error: too few template-parameter-lists
      445 |     struct Comparator<>
          |            ^~~~~~~~~~~~
    Sig.hpp:822:15: error: explicit specialization in non-namespace scope ‘struct Sig’
      822 |     template <>
          |               ^
    Sig.hpp:823:12: error: too few template-parameter-lists
      823 |     struct MaskComparator<>
          |            ^~~~~~~~~~~~~~~~
    Sig.hpp: In instantiation of ‘static bool Sig::Comparator<Entry>::cmp(const void*) [with Entry = Sig::Holder<unsigned int, Sig::Cmp::Eq, 1144201745>]’:
    Sig.hpp:464:60:   required from ‘static const void* Sig::find(const void*, size_t) [with Entries = {Sig::Holder<unsigned int, Sig::Cmp::Eq, 1144201745>}; size_t = long unsigned int]’
    test.cpp:11:65:   required from here
    Sig.hpp:403:45: error: no type named ‘cmp’ in ‘using Cmp = struct Sig::Cmp::Eq<unsigned int, 1144201745>’ {aka ‘struct Sig::Cmp::Eq<unsigned int, 1144201745>’}
      403 |                 return typename Entry::Cmp::cmp(pos);
          |                                             ^~~~~~~~
    Sig.hpp: In instantiation of ‘static bool Sig::MaskComparator<Entry, Entries ...>::cmp(char, char, char) [with Entry = Sig::Mask::Any<'?'>; Entries = {}]’:
    Sig.hpp:794:55:   required from ‘static bool Sig::MaskComparator<Entry, Entries ...>::cmp(char, char, char) [with Entry = Sig::Mask::Eq<'.'>; Entries = {Sig::Mask::Any<'?'>}]’
    Sig.hpp:854:73:   required from ‘static const void* Sig::find(const void*, size_t, const char*, const char*, size_t) [with Comparators = {Sig::Mask::Eq<'.'>, Sig::Mask::Any<'?'>}; size_t = long unsigned int]’
    Sig.hpp:882:36:   required from ‘static const void* Sig::find(const void*, size_t, const char*, const char*) [with Comparators = {Sig::Mask::Eq<'.'>, Sig::Mask::Any<'?'>}; size_t = long unsigned int]’
    test.cpp:15:29:   required from here
    Sig.hpp:794:55: error: ‘cmp’ is not a member of ‘Sig::MaskComparator<>’
      794 |                 return MaskComparator<Entries...>::cmp(data, pattern, mask);
    
    opened by qdlmcfresh 3
  • [FEATURE REQUEST]

    [FEATURE REQUEST]

    Respected Developer, I appreciate your work so far. But the scanner is not able to detect more matches after it finds the first match. So for example I have an array {0x00,0x13,0x00,0x56,0x00,0x13,0x66,0x77} The algorithm can find 00 13 first offset, but not the next one. If there are multiple matches, the program should return offsets for all of those matches.

    opened by Naeemullah1 2
Owner
Александр
Александр
Edf is an event-driven framework for embedded system (e.g. FreeRTOS) with state machine and subscriber-publisher pattern.

Edf means event-driven framework. Event-driven programming is a common pattern in embedded systems. However, if you develop software directly on top o

Arrow89 7 Oct 16, 2022
match(it): A lightweight header-only pattern-matching library for C++17 with macro-free APIs.

match(it): A lightweight header-only pattern-matching library for C++17 with macro-free APIs. Features Easy to get started. Single header library. Mac

Bowen Fu 434 Dec 27, 2022
Orbit, the Open Runtime Binary Instrumentation Tool, is a standalone C/C++ profiler for Windows and Linux

Orbit, the Open Runtime Binary Instrumentation Tool, is a standalone C/C++ profiler for Windows and Linux. Its main purpose is to help developers visualize the execution flow of a complex application.

Google 3k Dec 30, 2022
A powerful C++ timer, requires C++14 or later standard.

Timer A powerful C++ timer, requires C++14 or later standard. Concepts Not invade the target program API I want to design a timer that does not "invad

null 2 Nov 30, 2021
VMPImportFixer is a tool aimed to resolve import calls in a VMProtect'd (3.x) binary.

VMPImportFixer VMPImportFixer is a tool aimed to resolve import calls in a VMProtect'd (3.x) binary. Information VMPImportFixer attempts to resolve al

null 256 Dec 28, 2022
A combined suite of utilities for manipulating binary data files.

BinaryTools A combined suite of utilities for manipulating binary data files. It was developed for use on Windows but might compile on other systems.

David Walters 6 Oct 1, 2022
Translates binary information (images, fonts, shaders) into C++ source code.

Binary bakery ?? Translates binary files (images, fonts etc.) into C++ source code and gives access to that data at compile- or runtime. There are dif

Sebastian Werhausen 129 Oct 28, 2022
The lightweight and modern Map SDK for Android and iOS

Open Mobile Maps The lightweight and modern Map SDK for Android (6.0+) and iOS (10+) openmobilemaps.io Getting started Readme Android Readme iOS Featu

Open Mobile Maps 95 Dec 23, 2022
An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples

rootkit-arsenal-guacamole An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples All projects have been por

Matteo Malvica 51 Nov 6, 2022
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

Microsoft 7.2k Jan 2, 2023