huiyadanli/RevokeMsgPatcher · error · Exception

不正确的通配符位置!

Error message

不正确的通配符位置!

What it means

FuzzyMatcher.GetHead(pattern) extracts the concrete byte prefix before the first wildcard byte (0x3F, the ASCII '?'). Boyer-Moore anchoring needs at least one real leading byte; if the very first byte is a wildcard, len becomes 0 and it throws a plain Exception. A pattern must therefore not begin with a wildcard.

Source

Thrown at RevokeMsgPatcher/Matcher/FuzzyMatcher.cs:97

        /// <summary>
        /// 获取头串
        /// </summary>
        /// <param name="whole">完整查找串</param>
        /// <returns></returns>
        private static byte[] GetHead(byte[] whole)
        {
            int len = whole.Length;
            for (int i = 0; i < whole.Length; i++)
            {
                if (whole[i] == wildcard)
                {
                    len = i;
                    break;
                }
            }
            if (len == 0)
            {
                throw new Exception("不正确的通配符位置!");
            }
            return whole.Take(len).ToArray();
        }

        /// <summary>
        /// 确认整个查找串是否匹配
        /// </summary>
        /// <param name="content">被查找对象</param>
        /// <param name="start">头串匹配位置</param>
        /// <param name="whole">完整查找串</param>
        /// <returns></returns>
        public static bool IsEqual(byte[] content, int start, byte[] whole)
        {
            int i = 0;
            for (i = 0; i < whole.Length; i++)
            {
                if (whole[i] == wildcard)
                {

View on GitHub (pinned to 89cbbb3f0c)

Solutions

  1. Rewrite the pattern so it starts with at least one concrete byte, not a wildcard (0x3F / '??').
  2. If the signature genuinely has no fixed leading byte, find a nearby anchor and extend the pattern to include one concrete byte at the front.
  3. Add an authoring-time check that rejects any Search/Replace array starting with 0x3F.

Example fix

// before (throws)
Search  = ByteUtil.HexStringToByteArray("?? 8B 45 EC");

// after
Search  = ByteUtil.HexStringToByteArray("8B 45 EC ?? ?? 52");
Defensive patterns

Strategy: validation

Validate before calling

static bool HasValidHead(byte[] pattern) => pattern != null && pattern.Length > 0 && pattern[0] != FuzzyMatcher.wildcard;

if (!HasValidHead(pattern.Search) || !HasValidHead(pattern.Replace))
{
    throw new InvalidOperationException("特征码不能以通配符(?? / 0x3F)开头");
}
int[] idx = FuzzyMatcher.MatchAll(fileByteArray, pattern.Search);

Prevention

When it happens

Trigger: A ReplacePattern.Search (or Replace) array whose first element equals 0x3F, i.e. a pattern authored as '?? XX YY' rather than 'XX ?? YY'. GetHead runs inside MatchAll/MatchNotReplaced on every search.

Common situations: Authoring patch signatures in patch.json with a leading wildcard; copying a signature from a disassembler that pads the start with ?? tokens.

Related errors


AI-assisted analysis of huiyadanli/RevokeMsgPatcher@89cbbb3f0c (2026-08-13). Data as JSON: /api/errors/a52df56e675b03fd. Report an issue: GitHub.