拓冰建站拓冰建站
首页 / 资讯中心 / 正文

4个问答看懂RevokeMsgPatcher特征码匹配:防撤回补丁如何锁定那一个字节

4个问答看懂RevokeMsgPatcher特征码匹配防撤回补丁如何锁定那一个字节【免费下载链接】RevokeMsgPatcher:trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁我已经看到了撤回也没用了项目地址: https://gitcode.com/GitHub_Trending/re/RevokeMsgPatcher先看一个经典场景微信/QQ 里有人发消息后立刻撤回本地聊天记录瞬间被清空。RevokeMsgPatcher 这类防撤回补丁干的事是直接改写客户端核心 DLL 里的机器码让删除本地消息这条分支永远走不到。而整条链路的地基正是特征码匹配——在动辄上百 MB 的二进制文件里精准找出该改的那几字节再安全回写。本文不贴整段源码而是用 4 个高频问题把为什么要匹配、怎么快速匹配、怎么防误伤、匹配不上怎么办这条主线一次讲通。整个匹配系统集中在RevokeMsgPatcher/Matcher/目录下由BoyerMooreMatcher、FuzzyMatcher、ModifyFinder三个类协作完成我们顺着代码逐个拆。先交代背景撤回判断藏在一段指令里消息被撤回时客户端会先检查这条消息是否已经在屏幕上展示过只有展示过才允许删除本地缓存。这个检查 跳转在汇编层面就是一条条件跳转指令比如74JE 相等则跳或75JNE 不等则跳。补丁的思路就是把这条跳转改成无条件跳转或直接EBJMP让删除逻辑永远不触发。难点在于DLL 是编译产物没有源码可查文件又大微信的WeChatWin.dll常超 100MB每个小版本编译出的指令字节还可能偏移。所以工具必须先靠一串固定的字节序列当路标找到路标才能谈修改。上图是作者在 x32dbg 里搜索revokemsg字符串定位代码位置的记录这一步可以看作特征码匹配的前置分析——先人工找到特征再把特征固化进补丁程序。问题一文件上百 MB怎么快速找到目标字节串大白话把 DLL 想象成一本很厚的字典你要找一段特定的文字。最笨的办法是从第一页开始逐字翻翻到哪算哪聪明的办法是翻到某个词拼不上时直接跳过大段注定匹配不上的区域。严谨定义朴素扫描对每个起点都做全长比较复杂度 O(n×m)BoyerMooreMatcher实现的 Boyer-Moore 算法则用两种启发式规则决定跳多远多数场景能把开销压到亚线性。算法核心是这两张预处理表启发式作用坏字符规则匹配失败时看文本中失配的那个字节在特征串里最后一次出现在哪据此向后跳好后缀规则利用已匹配成功的后缀部分来决定最安全的跳跃距离主循环长这样见RevokeMsgPatcher/Matcher/BoyerMooreMatcher.cspublic static bool TryMatch(byte[] text, byte[] pattern, out int firstShift) { int n text.Length, m pattern.Length, s 0; int[] badChar PreprocessToBuildBadCharactorHeuristic(pattern); int[] goodSuf PreprocessToBuildGoodSuffixHeuristic(pattern); while (s n - m) { int j m - 1; while (j 0 pattern[j] text[s j]) j--; // 从尾部倒着比对 if (j 0) { firstShift s; return true; } // 整段命中 s Math.Max(goodSuf[j], badChar[text[s j]] - (m - 1) j); // 失败时取两个规则里跳得更远的一方一次跳过多个字节 } return false; }类比落地就像查词典时发现目标词第 3 个字就对不上而这个错字在整本词典里再没出现过你完全可以把后面所有页翻过去。Boyer-Moore 就是把这种翻页直觉固化成可计算的跳跃量。问题二版本一升级特征码就失效通配符怎么救场大白话特征码里总有每次编译都会变的字节比如内存地址、偏移量与其硬记死值不如在这些位置留一个任意字节都算对的占位符。严谨定义FuzzyMatcher把0x3FASCII 的?定义为通配符。以RevokeMsgPatcher/Modifier/WechatModifier.cs里一条真实特征为例68 3F 3F 3F 3F 8B 08 50 FF 51 7868 3F 3F 3F 3F对应汇编push 0x????????四个字节是调用地址每个版本都不同必须用0x3F占位。但问题来了带通配符就没法直接套用 Boyer-Moore。作者的解法是两阶段匹配见RevokeMsgPatcher/Matcher/FuzzyMatcher.cspublic static int[] MatchAll(byte[] content, byte[] pattern) { byte[] head GetHead(pattern); // 取第一个通配符之前的固定头串 int[] indexs BoyerMooreMatcher.MatchAll(content, head); if (head.Length pattern.Length) return indexs; // 没有通配符直接返回结果 Listint res new Listint(); foreach (int idx in indexs) if (IsEqual(content, idx, pattern)) // 头串命中后做全串复验 res.Add(idx); return res.ToArray(); }复验逻辑更直白public static bool IsEqual(byte[] content, int start, byte[] whole) { for (int i 0; i whole.Length; i) { if (whole[i] 0x3F) continue; // 通配符位置任意字节都通过 if (content[start i] ! whole[i]) return false; } return true; }流程归纳先取通配符前的固定头串用 Boyer-Moore 快速框定候选位置通常只有少数几个再对每个候选点用IsEqual逐字节验证含通配符的完整特征。头串负责广撒网复验负责精准捞鱼两者配合把模糊匹配的速度拉回接近精确匹配的水平。问题三怎么判断该打补丁还是已经打过补丁大白话补丁执行前得先体检否则用户反复点补丁、或混用其他工具会把文件改坏。严谨定义ModifyFinder.FindChanges负责统揽匹配与校验。它先为每条替换规则做全量匹配再对命中位置判断当前字节是否已等于替换串——如果已经等于说明这里早就被改过了不该再算一次变更foreach (ReplacePattern p in replacePatterns) { int[] hits FuzzyMatcher.MatchAll(fileBytes, p.Search); matchNum hits.Length; foreach (int pos in hits) if (!FuzzyMatcher.IsEqual(fileBytes, pos, p.Replace)) changes.Add(new Change(pos, p.Replace)); } if (matchNum replacePatterns.Count) throw new BusinessException(match_inconformity, 特征码匹配数量与预期不一致请确认版本或已装补丁……);匹配数量校验之后还有一层更细的冲突检测逻辑封装在IsAllReplaced里可以用一张流程图说明对每个功能特征 ① 查找串原始指令还匹配得到吗 ② 替换串补丁后指令能否匹配到 ③ 若查找串 0 且 替换串 0 → 判定该功能已打过补丁这套双向匹配的思路很实用查找串消失 替换串现身 补丁已应用。据此工具能区分三种情况完全没打过正常开始、部分功能已装提示取消勾选、全部已装直接提示无需重复操作。上图是补丁生成后的界面74 → EB、55 → C3这类改动点被列出用户确认后再统一回写文件——回写前还会自动备份原始 DLL方便一键还原。问题四当前版本一条特征都匹配不上怎么办大白话特征码是写给特定版本看的暗号版本变了暗号就得换。所以项目不是只存一套特征码而是按版本区间维护多套匹配时自动对号入座。严谨定义看RevokeMsgPatcher.Assistant/Data/下的patch.json你会发现数据按版本目录0.7到2.1组织每个版本区间FileCommonModifyInfos里列着多条ReplacePatterns。以 QQ 为例同一个防撤回功能在多个版本段各配了一套不同的 Search/Replace这就是多特征码策略——9.4.7一套、9.1.6 ~ 9.4.7另一套保证版本升级后仍能兜底命中。当匹配数严格小于预期时FindChanges会先走IsAllReplaced排查是不是已经装过补丁排除后才报特征码失效。此时通常的解法只有两个确认版本检查工具版本是否落后于客户端必要时下载新版特征数据联系维护者如果是最新版客户端仍匹配失败多半是官方调整了逻辑需要作者重新逆向提取特征码。补丁本身的改动往往是一字节级的如74改EB这正是它轻量、可逆的原因但也意味着任何一次版本大改都可能让整条特征报废——维护成本全部压在了特征码的持续更新上。收尾把整条链路串一遍回到最初的问题防撤回补丁凭什么能在 100MB 文件里精准改对地方答案可以浓缩成一条流水线快BoyerMooreMatcher用坏字符 好后缀跳跃定位固定头串稳FuzzyMatcher用0x3F通配符吸收版本间的字节漂移准ModifyFinder做全串复验、替换态判断与重复补丁检测杜绝误改全patch.json按版本区间维护多套特征尽可能覆盖新旧版本。如果你想亲手读一遍实现可以先 clone 仓库git clone https://gitcode.com/GitHub_Trending/re/RevokeMsgPatcher然后重点看RevokeMsgPatcher/Matcher/下三个文件的完整代码再对照RevokeMsgPatcher/Modifier/里各应用的特征配置基本就能把定位 → 验证 → 回写 → 备份的完整闭环拼出来。理解这套机制不只对防撤回工具有用——任何需要在二进制里找特征、改字节的逆向工程场景用的都是同一套思路。【免费下载链接】RevokeMsgPatcher:trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁我已经看到了撤回也没用了项目地址: https://gitcode.com/GitHub_Trending/re/RevokeMsgPatcher创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门