Skip to content

False negative sparse mask #8

Description

@mrexodia

Repro

#include <Pattern16.h>

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <random>
#include <sstream>
#include <string>
#include <vector>

using u8 = std::uint8_t;

static std::string to_signature(const std::vector<u8>& pattern, const std::string& mask)
{
    std::ostringstream oss;
    for (size_t i = 0; i < mask.size(); ++i)
    {
        if (i) oss << ' ';
        if (mask[i] == 'x')
            oss << std::uppercase << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned>(pattern[i]);
        else
            oss << "??";
    }
    return oss.str();
}

static size_t reference_find_first(const std::vector<u8>& data, const std::vector<u8>& pattern, const std::string& mask)
{
    for (size_t off = 0; off + pattern.size() <= data.size(); ++off)
    {
        bool match = true;
        for (size_t i = 0; i < pattern.size(); ++i)
        {
            if (mask[i] == 'x' && data[off + i] != pattern[i]) { match = false; break; }
        }
        if (match) return off;
    }
    return static_cast<size_t>(-1);
}

int main()
{
    const std::vector<u8> pattern = {
        0x00, 0x00, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0xB8, 0x00, 0x00, 0x00,
        0xD3, 0x00, 0x2C, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x19
    };
    const std::string mask = "??x?????x?????x?x???x?x?x????x";

    const size_t data_len = 4699;
    std::vector<u8> data(data_len);

    std::mt19937 rng(0x88BEA0B2u);
    std::uniform_int_distribution<int> byte_dist(0, 255);
    for (size_t i = 0; i < data_len; ++i)
        data[i] = static_cast<u8>(byte_dist(rng));

    const size_t inject_offsets[] = {440, 684, 1023, 1388, 2011, 2750, 3301, 4096};
    for (size_t off : inject_offsets)
    {
        if (off + pattern.size() > data.size()) continue;
        for (size_t j = 0; j < pattern.size(); ++j)
            if (mask[j] == 'x') data[off + j] = pattern[j];
    }

    const std::string signature = to_signature(pattern, mask);
    const size_t expected = reference_find_first(data, pattern, mask);
    const u8* found = static_cast<const u8*>(Pattern16::scan(data.data(), data.size(), signature));
    const size_t got = found ? static_cast<size_t>(found - data.data()) : static_cast<size_t>(-1);

    std::cout << "expected=" << expected << " got=" << got << "\n";
}

Expected

  • expected=31 got=31

Actual

  • expected=31 got=18446744073709551615

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions