<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>微信 on 猫猫鱼的小窝</title>
    <link>https://cat.fjh1997.top/tags/%E5%BE%AE%E4%BF%A1/</link>
    <description>Recent content from 猫猫鱼的小窝</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    
    <managingEditor>xxx@example.com (catcatyu)</managingEditor>
    <webMaster>xxx@example.com (catcatyu)</webMaster>
    
    <copyright>本博客所有文章除特别声明外，均采用 BY-NC-SA 许可协议。转载请注明出处！</copyright>
    
    <lastBuildDate>Sat, 25 Jul 2026 21:00:00 +0800</lastBuildDate>
    
    
    <atom:link href="https://cat.fjh1997.top/tags/%E5%BE%AE%E4%BF%A1/atom.xml" rel="self" type="application/rss&#43;xml" />
    

    
    

    <item>
      <title>Windows 微信 / QQNT 阻止自动更新（配合 RevokeMsgPatcher 版本上限）</title>
      <link>https://cat.fjh1997.top/posts/2026072501.html</link>
      <pubDate>Sat, 25 Jul 2026 21:00:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://cat.fjh1997.top/posts/2026072501.html</guid>
      <description>
        <![CDATA[<h1>Windows 微信 / QQNT 阻止自动更新（配合 RevokeMsgPatcher 版本上限）</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="为什么要阻止升级">
<a class="header-anchor" href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e8%a6%81%e9%98%bb%e6%ad%a2%e5%8d%87%e7%ba%a7"></a>
为什么要阻止升级
</h2><p><a href="https://github.com/huiyadanli/RevokeMsgPatcher" target="_blank" rel="noopener noreferrer nofollow">RevokeMsgPatcher</a>
 通过对客户端二进制做特征 patch，实现 PC 微信 / QQ 的防撤回等能力。特征是跟<strong>具体版本</strong>绑定的，客户端一升，偏移和指令序列往往就失效。</p>
<p>社区 PR <a href="https://github.com/huiyadanli/RevokeMsgPatcher/pull/1193" target="_blank" rel="noopener noreferrer nofollow">huiyadanli/RevokeMsgPatcher#1193</a>
（<code>fix: update QQNT anti-recall patterns</code>）把 QQNT 防撤回特征更新到了：</p>
<table>
  <thead>
      <tr>
          <th>客户端</th>
          <th>PR / 工具侧可用上限（本文写作时）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>QQNT</strong></td>
          <td><strong>9.9.20-36330</strong></td>
      </tr>
      <tr>
          <td><strong>微信（Weixin 4.x）</strong></td>
          <td><strong>4.1.9.30</strong></td>
      </tr>
  </tbody>
</table>
<p>也就是说：</p>
<ul>
<li>你装了更高版本的 QQNT / 微信，这个 PR 里的规则<strong>不一定还能匹配</strong>；</li>
<li>腾讯客户端默认会<strong>后台检查 + 热更新/补丁下载</strong>，一重启就可能悄悄升上去；</li>
<li>想稳定用防撤回，就得先把版本<strong>钉住</strong>，再跑 patch 工具。</li>
</ul>
<p>本文记录在 Windows 宿主机上实际踩过的路径：只拦 <code>dldir*.qq.com</code> <strong>不够</strong>；QQNT 和微信 4.x 的更新通道、本地缓存位置都不一样。</p>
<blockquote>
<p>说明：这是<strong>延后升级</strong>，不是永久锁死。服务端若强制最低版本，旧客户端仍可能无法登录。也不要用来路不明的「免更新破解版」。</p>
</blockquote>
<hr>
<h2 id="历史版本从哪里下">
<a class="header-anchor" href="#%e5%8e%86%e5%8f%b2%e7%89%88%e6%9c%ac%e4%bb%8e%e5%93%aa%e9%87%8c%e4%b8%8b"></a>
历史版本从哪里下
</h2><p>当前版本已经高于 patch 上限时，需要先<strong>降回可用版本</strong>，再立刻做防更新。不要去搜来路不明的「绿色版 / 免更新破解包」；社区有专门归档安装包的仓库（Release 资产，可自行核对哈希）：</p>
<table>
  <thead>
      <tr>
          <th>客户端</th>
          <th>历史版本仓库</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>QQNT</strong></td>
          <td><a href="https://github.com/PRO-2684/qqnt-version-history" target="_blank" rel="noopener noreferrer nofollow">PRO-2684/qqnt-version-history</a>
</td>
      </tr>
      <tr>
          <td><strong>微信 Windows</strong></td>
          <td><a href="https://github.com/cscnk52/wechat-windows-versions" target="_blank" rel="noopener noreferrer nofollow">cscnk52/wechat-windows-versions</a>
</td>
      </tr>
  </tbody>
</table>
<p>配合本文目标上限时，优先找：</p>
<ul>
<li>QQNT：<code>9.9.20-36330</code>（或 PR / 工具说明支持的最近一档）</li>
<li>微信：<code>4.1.9.30</code>（Weixin 4.x）</li>
</ul>
<p>建议流程：</p>
<ol>
<li>卸载当前过高版本（或至少退出客户端）</li>
<li>从上述仓库的 <strong>Releases</strong> 下载对应安装包</li>
<li>安装完成后<strong>先不要登录</strong>，立刻做本文后面的 hosts / 清缓存 / 锁目录</li>
<li>再登录，并运行 RevokeMsgPatcher</li>
</ol>
<blockquote>
<p>仓库由第三方维护，安装包是否完整、是否被服务端拒绝登录，以你本机实测为准；下载后尽量核对 Release 里公布的校验信息。</p>
</blockquote>
<hr>
<h2 id="先确认当前版本">
<a class="header-anchor" href="#%e5%85%88%e7%a1%ae%e8%ae%a4%e5%bd%93%e5%89%8d%e7%89%88%e6%9c%ac"></a>
先确认当前版本
</h2><h3 id="qqnt">
<a class="header-anchor" href="#qqnt"></a>
QQNT
</h3><p>安装目录常见：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">C:\Program Files\Tencent\QQNT\
</span></span></code></pre></td></tr></table>
</div>
</div><p>看当前热更新配置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">C:\Program Files\Tencent\QQNT\versions\config.json
</span></span></code></pre></td></tr></table>
</div>
</div><p>关键字段：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;curVersion&#34;</span><span class="p">:</span> <span class="s2">&#34;9.9.20-36330&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;readyVersion&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;readyType&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li><code>curVersion</code>：正在用的版本目录名</li>
<li><code>readyVersion</code> 非空：本地<strong>已经下好/解压好</strong>，提示「新版本已就绪」，重启就会切过去</li>
</ul>
<p>进程命令行里也能看到：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">--app-path=&#34;C:\Program Files\Tencent\QQNT\versions\9.9.20-36330\resources\app&#34;
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="微信新版-weixin-4x">
<a class="header-anchor" href="#%e5%be%ae%e4%bf%a1%e6%96%b0%e7%89%88-weixin-4x"></a>
微信（新版 Weixin 4.x）
</h3><p>新版安装目录是 <code>Weixin</code>，不是老的 <code>WeChat</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">C:\Program Files\Tencent\Weixin\
</span></span><span class="line"><span class="cl">C:\Program Files\Tencent\Weixin\4.1.9.30\
</span></span></code></pre></td></tr></table>
</div>
</div><p>用户数据与更新缓存：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">%AppData%\Tencent\xwechat\
</span></span><span class="line"><span class="cl">%AppData%\Tencent\xwechat\update\
</span></span></code></pre></td></tr></table>
</div>
</div><p>更新组件：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">%AppData%\Tencent\xwechat\xplugin\plugins\WeixinUpdate\&lt;id&gt;\extracted\WeixinUpdate.exe
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="总原则更新分两段">
<a class="header-anchor" href="#%e6%80%bb%e5%8e%9f%e5%88%99%e6%9b%b4%e6%96%b0%e5%88%86%e4%b8%a4%e6%ae%b5"></a>
总原则：更新分两段
</h2><table>
  <thead>
      <tr>
          <th>阶段</th>
          <th>含义</th>
          <th>只改 hosts 够不够</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>检查更新</td>
          <td>问服务器有没有新版本 → <strong>弹窗</strong></td>
          <td>通常<strong>不够</strong></td>
      </tr>
      <tr>
          <td>下载 / 落地</td>
          <td>把安装包或热更新包写到本地</td>
          <td><strong>hosts / 权限 / 防火墙</strong> 能挡</td>
      </tr>
      <tr>
          <td>已就绪</td>
          <td>包已在本地，<code>readyVersion</code> 或 <code>update\patch</code> 已齐</td>
          <td><strong>必须删本地缓存</strong>，光拦域名没用</td>
      </tr>
  </tbody>
</table>
<p>所以会出现：</p>
<ul>
<li>hosts 已生效，但客户端仍提示「发现新版本 / 新版本已就绪」——正常；</li>
<li>点「立即更新」仍能下——说明走了<strong>别的域名</strong>，或<strong>IPv6 / 已建立连接</strong>没被拦；</li>
<li>点了就能装——说明包<strong>早就下完了</strong>。</li>
</ul>
<hr>
<h2 id="一qqnt真正的热更新域名不是-dldir">
<a class="header-anchor" href="#%e4%b8%80qqnt%e7%9c%9f%e6%ad%a3%e7%9a%84%e7%83%ad%e6%9b%b4%e6%96%b0%e5%9f%9f%e5%90%8d%e4%b8%8d%e6%98%af-dldir"></a>
一、QQNT：真正的热更新域名不是 dldir
</h2><h3 id="1-特征串从-majornode-里能抠到">
<a class="header-anchor" href="#1-%e7%89%b9%e5%be%81%e4%b8%b2%e4%bb%8e-majornode-%e9%87%8c%e8%83%bd%e6%8a%a0%e5%88%b0"></a>
1. 特征串（从 <code>major.node</code> 里能抠到）
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">https://qqpatch.gtimg.cn
</span></span><span class="line"><span class="cl">https://qqpatch.gtimg.cn/hotUpdate_new
</span></span><span class="line"><span class="cl">https://qqpatch.gtimg.cn/dynamic_module/
</span></span></code></pre></td></tr></table>
</div>
</div><p>实际下载时 DNS 缓存里还出现过腾讯下载 CDN 变体，例如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">downv6.ydcdn.tcdnos.com
</span></span><span class="line"><span class="cl">downv6.aly.tcdnos.com
</span></span></code></pre></td></tr></table>
</div>
</div><p>（会随线路变化，以本机 DNS 缓存 / 抓包为准。）</p>
<h3 id="2-本地落地位置">
<a class="header-anchor" href="#2-%e6%9c%ac%e5%9c%b0%e8%90%bd%e5%9c%b0%e4%bd%8d%e7%bd%ae"></a>
2. 本地落地位置
</h3><p>热更新包会进：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">C:\Program Files\Tencent\QQNT\versions\
</span></span><span class="line"><span class="cl">  9.9.20-36330\          ← 当前版本目录
</span></span><span class="line"><span class="cl">  9.9.xx-xxxxx\          ← 已解压的新版本
</span></span><span class="line"><span class="cl">  9.9.xx-xxxxx.zip       ← 下载中的包（有时还会出现奇怪的 .zip.zip）
</span></span><span class="line"><span class="cl">  config.json
</span></span></code></pre></td></tr></table>
</div>
</div><p>若 <code>config.json</code> 里已有：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;readyVersion&#34;</span><span class="err">:</span> <span class="s2">&#34;9.9.32-51246&#34;</span><span class="err">,</span>
</span></span><span class="line"><span class="cl"><span class="s2">&#34;readyType&#34;</span><span class="err">:</span> <span class="s2">&#34;HOT_UPDATE&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>则界面就是「新版本已就绪」——<strong>不必再下载</strong>。</p>
<h3 id="3-hosts管理员编辑">
<a class="header-anchor" href="#3-hosts%e7%ae%a1%e7%90%86%e5%91%98%e7%bc%96%e8%be%91"></a>
3. hosts（管理员编辑）
</h3><p>路径：<code>C:\Windows\System32\drivers\etc\hosts</code></p>
<p>建议同时写 <strong>IPv4 + IPv6</strong>（只写 <code>127.0.0.1</code> 时，IPv6 仍可能通）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl"># QQNT 热更新
</span></span><span class="line"><span class="cl">127.0.0.1 qqpatch.gtimg.cn
</span></span><span class="line"><span class="cl">::1 qqpatch.gtimg.cn
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"># 实测出现过的下载 CDN（可按抓包增减）
</span></span><span class="line"><span class="cl">127.0.0.1 downv6.ydcdn.tcdnos.com
</span></span><span class="line"><span class="cl">::1 downv6.ydcdn.tcdnos.com
</span></span><span class="line"><span class="cl">127.0.0.1 downv6.aly.tcdnos.com
</span></span><span class="line"><span class="cl">::1 downv6.aly.tcdnos.com
</span></span><span class="line"><span class="cl">127.0.0.1 down.ydcdn.tcdnos.com
</span></span><span class="line"><span class="cl">::1 down.ydcdn.tcdnos.com
</span></span><span class="line"><span class="cl">127.0.0.1 down.aly.tcdnos.com
</span></span><span class="line"><span class="cl">::1 down.aly.tcdnos.com
</span></span><span class="line"><span class="cl">127.0.0.1 downv6.tcdnos.com
</span></span><span class="line"><span class="cl">::1 downv6.tcdnos.com
</span></span><span class="line"><span class="cl">127.0.0.1 down.tcdnos.com
</span></span><span class="line"><span class="cl">::1 down.tcdnos.com
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">ipconfig /flushdns
</span></span></code></pre></td></tr></table>
</div>
</div><p>验证：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">ping qqpatch.gtimg.cn
</span></span></code></pre></td></tr></table>
</div>
</div><p>应指向 <code>127.0.0.1</code>。</p>
<h3 id="4-清掉已就绪的新版本">
<a class="header-anchor" href="#4-%e6%b8%85%e6%8e%89%e5%b7%b2%e5%b0%b1%e7%bb%aa%e7%9a%84%e6%96%b0%e7%89%88%e6%9c%ac"></a>
4. 清掉「已就绪」的新版本
</h3><ol>
<li>托盘彻底退出 QQ</li>
<li>删除高于目标版本的目录和 zip，例如不要的 <code>9.9.32-*</code></li>
<li>编辑 <code>versions\config.json</code>，保证：</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;curVersion&#34;</span><span class="err">:</span> <span class="s2">&#34;9.9.20-36330&#34;</span><span class="err">,</span>
</span></span><span class="line"><span class="cl"><span class="s2">&#34;readyVersion&#34;</span><span class="err">:</span> <span class="s2">&#34;&#34;</span><span class="err">,</span>
</span></span><span class="line"><span class="cl"><span class="s2">&#34;readyInstaller&#34;</span><span class="err">:</span> <span class="s2">&#34;&#34;</span><span class="err">,</span>
</span></span><span class="line"><span class="cl"><span class="s2">&#34;readyType&#34;</span><span class="err">:</span> <span class="s2">&#34;&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="4">
<li>再启动 QQ</li>
</ol>
<p>可选加固：给 <code>versions</code> 目录去掉普通用户的写入权限（过狠可能影响正常运行，慎用）。</p>
<h3 id="5-副作用">
<a class="header-anchor" href="#5-%e5%89%af%e4%bd%9c%e7%94%a8"></a>
5. 副作用
</h3><ul>
<li><code>qqpatch.gtimg.cn</code> 还承载部分主题 / 动态资源，拦截后个别皮肤资源可能异常。</li>
<li><code>tcdnos.com</code> 若被其它腾讯下载共用，也可能受影响。</li>
</ul>
<hr>
<h2 id="二微信-weixin-4xdldir--本地-update-目录">
<a class="header-anchor" href="#%e4%ba%8c%e5%be%ae%e4%bf%a1-weixin-4xdldir--%e6%9c%ac%e5%9c%b0-update-%e7%9b%ae%e5%bd%95"></a>
二、微信 Weixin 4.x：dldir + 本地 update 目录
</h2><h3 id="1-二进制里的下载入口">
<a class="header-anchor" href="#1-%e4%ba%8c%e8%bf%9b%e5%88%b6%e9%87%8c%e7%9a%84%e4%b8%8b%e8%bd%bd%e5%85%a5%e5%8f%a3"></a>
1. 二进制里的下载入口
</h3><p><code>Weixin.dll</code> 里能看到类似：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">https://dldir1.qq.com
</span></span><span class="line"><span class="cl">https://dldir1v6.qq.com
</span></span><span class="line"><span class="cl">https://dldir1v6.qq.com/weixin/Universal/Windows/XPlugin/updateConfigUniWin.xml
</span></span><span class="line"><span class="cl">https://support.weixin.qq.com/update/
</span></span></code></pre></td></tr></table>
</div>
</div><p>老办法「只 hosts 几个 dldir」对<strong>下载</strong>有帮助，但：</p>
<ol>
<li>要补 <strong>IPv6 <code>::1</code></strong>，否则 v6 线路可能绕过；</li>
<li>若 <code>%AppData%\Tencent\xwechat\update\</code> 里已经有完整 patch，点更新照样能装。</li>
</ol>
<h3 id="2-本地更新缓存长什么样">
<a class="header-anchor" href="#2-%e6%9c%ac%e5%9c%b0%e6%9b%b4%e6%96%b0%e7%bc%93%e5%ad%98%e9%95%bf%e4%bb%80%e4%b9%88%e6%a0%b7"></a>
2. 本地更新缓存长什么样
</h3><p>示例（版本号按你机器上的为准）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">%AppData%\Tencent\xwechat\update\
</span></span><span class="line"><span class="cl">  download\4.1.11.55\Weixin.dll.zip
</span></span><span class="line"><span class="cl">  download\4.1.11.55\Weixin.exe.zip
</span></span><span class="line"><span class="cl">  download\4.1.11.55\patch.zip
</span></span><span class="line"><span class="cl">  patch\4.1.11.55\Weixin.dll
</span></span><span class="line"><span class="cl">  patch\4.1.11.55\Weixin.exe
</span></span><span class="line"><span class="cl">  ...
</span></span></code></pre></td></tr></table>
</div>
</div><p>同时进程列表里可能出现：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">WeixinUpdate.exe
</span></span></code></pre></td></tr></table>
</div>
</div><p>路径类似：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">%AppData%\Tencent\xwechat\xplugin\plugins\WeixinUpdate\9013\extracted\WeixinUpdate.exe
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="3-hosts">
<a class="header-anchor" href="#3-hosts"></a>
3. hosts
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl"># 微信 / 腾讯通用下载域（IPv4 + IPv6）
</span></span><span class="line"><span class="cl">127.0.0.1 dldir1.qq.com
</span></span><span class="line"><span class="cl">::1 dldir1.qq.com
</span></span><span class="line"><span class="cl">127.0.0.1 dldir1v6.qq.com
</span></span><span class="line"><span class="cl">::1 dldir1v6.qq.com
</span></span><span class="line"><span class="cl">127.0.0.1 dldir2.qq.com
</span></span><span class="line"><span class="cl">::1 dldir2.qq.com
</span></span><span class="line"><span class="cl">127.0.0.1 dldir3.qq.com
</span></span><span class="line"><span class="cl">::1 dldir3.qq.com
</span></span><span class="line"><span class="cl">127.0.0.1 dldir4.qq.com
</span></span><span class="line"><span class="cl">::1 dldir4.qq.com
</span></span><span class="line"><span class="cl">127.0.0.1 dldir5.qq.com
</span></span><span class="line"><span class="cl">::1 dldir5.qq.com
</span></span><span class="line"><span class="cl">127.0.0.1 dldir6.qq.com
</span></span><span class="line"><span class="cl">::1 dldir6.qq.com
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">ipconfig /flushdns
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="4-删缓存--锁-update-目录">
<a class="header-anchor" href="#4-%e5%88%a0%e7%bc%93%e5%ad%98--%e9%94%81-update-%e7%9b%ae%e5%bd%95"></a>
4. 删缓存 + 锁 update 目录
</h3><ol>
<li>退出微信（含托盘）</li>
<li>结束残留的 <code>WeixinUpdate.exe</code></li>
<li>删除整个：</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">%AppData%\Tencent\xwechat\update
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="4">
<li>重建空目录后，对 <code>update</code>：<strong>拒绝当前用户 / Users 的写入、修改、删除</strong>（Administrators / SYSTEM 保留完全控制）。</li>
</ol>
<p>这样即使检查到更新，也<strong>写不进缓存</strong>。</p>
<h3 id="5-防火墙拦-weixinupdateexe推荐">
<a class="header-anchor" href="#5-%e9%98%b2%e7%81%ab%e5%a2%99%e6%8b%a6-weixinupdateexe%e6%8e%a8%e8%8d%90"></a>
5. 防火墙拦 WeixinUpdate.exe（推荐）
</h3><p><code>Win + R</code> → <code>wf.msc</code> → <strong>出站规则</strong> → 新建规则 → 程序 → 选中上述 <code>WeixinUpdate.exe</code> → <strong>阻止连接</strong>。</p>
<p>插件版本目录（如 <code>9012</code> / <code>9013</code>）可能并存，每个路径各建一条，或更新后检查是否换了路径。</p>
<p>主程序 <code>Weixin.exe</code> <strong>不要</strong>整进程出站全拦，容易直接没法登录/收消息。</p>
<h3 id="6-副作用">
<a class="header-anchor" href="#6-%e5%89%af%e4%bd%9c%e7%94%a8"></a>
6. 副作用
</h3><ul>
<li><code>dldir*.qq.com</code> 是腾讯通用下载域，QQ 安装包、其它腾讯软件下载也可能受影响。</li>
<li>锁 <code>update</code> 后，官方热更新基本失效——对「钉死 4.1.9.30」是预期行为。</li>
</ul>
<hr>
<h2 id="三推荐操作顺序想钉在-revokemsgpatcher-可用版本">
<a class="header-anchor" href="#%e4%b8%89%e6%8e%a8%e8%8d%90%e6%93%8d%e4%bd%9c%e9%a1%ba%e5%ba%8f%e6%83%b3%e9%92%89%e5%9c%a8-revokemsgpatcher-%e5%8f%af%e7%94%a8%e7%89%88%e6%9c%ac"></a>
三、推荐操作顺序（想钉在 RevokeMsgPatcher 可用版本）
</h2><p>以目标 <strong>QQNT 9.9.20-36330</strong>、<strong>微信 4.1.9.30</strong> 为例：</p>
<ol>
<li><strong>先确认当前就是目标版本</strong>；若更高，从历史版本仓库装回：
<ul>
<li>QQNT：<a href="https://github.com/PRO-2684/qqnt-version-history" target="_blank" rel="noopener noreferrer nofollow">PRO-2684/qqnt-version-history</a>
</li>
<li>微信：<a href="https://github.com/cscnk52/wechat-windows-versions" target="_blank" rel="noopener noreferrer nofollow">cscnk52/wechat-windows-versions</a>
</li>
</ul>
</li>
<li><strong>立刻</strong>改 hosts（QQNT 的 <code>qqpatch</code> + 微信的 <code>dldir</code>，都带 <code>::1</code>）。</li>
<li><strong>立刻</strong>清 QQNT <code>versions</code> 里多余版本 + 清空 <code>readyVersion</code>。</li>
<li><strong>立刻</strong>清微信 <code>xwechat\update</code>，并锁写 + 拦 <code>WeixinUpdate.exe</code>。</li>
<li>再运行 <a href="https://github.com/huiyadanli/RevokeMsgPatcher" target="_blank" rel="noopener noreferrer nofollow">RevokeMsgPatcher</a>
（含 PR #1193 那套特征）。</li>
<li>日常少点「立即更新」；看到「已就绪」优先当本地缓存，先清再谈拦域名。</li>
</ol>
<hr>
<h2 id="四怎么确认拦截生效">
<a class="header-anchor" href="#%e5%9b%9b%e6%80%8e%e4%b9%88%e7%a1%ae%e8%ae%a4%e6%8b%a6%e6%88%aa%e7%94%9f%e6%95%88"></a>
四、怎么确认拦截生效
</h2><h3 id="dns">
<a class="header-anchor" href="#dns"></a>
DNS
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bat" data-lang="bat"><span class="line"><span class="cl">ping qqpatch.gtimg.cn
</span></span><span class="line"><span class="cl">ping dldir1v6.qq.com
</span></span></code></pre></td></tr></table>
</div>
</div><p>应解析到 <code>127.0.0.1</code> / 本机。</p>
<h3 id="qqnt-1">
<a class="header-anchor" href="#qqnt-1"></a>
QQNT
</h3><ul>
<li><code>versions</code> 下不应再长出新的大体积 zip / 新版本目录；</li>
<li><code>config.json</code> 的 <code>readyVersion</code> 应保持空。</li>
</ul>
<h3 id="微信">
<a class="header-anchor" href="#%e5%be%ae%e4%bf%a1"></a>
微信
</h3><ul>
<li><code>xwechat\update</code> 下不应再出现 <code>download\</code> / <code>patch\</code> 大文件；</li>
<li>若仍弹更新但装不上、写目录失败，说明权限锁在起作用。</li>
</ul>
<h3 id="仍能下载时">
<a class="header-anchor" href="#%e4%bb%8d%e8%83%bd%e4%b8%8b%e8%bd%bd%e6%97%b6"></a>
仍能下载时
</h3><ol>
<li>在下载过程中看 DNS 缓存：</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-DnsClientCache</span> <span class="p">|</span> <span class="nb">Where-Object</span> <span class="p">{</span> <span class="nv">$_</span><span class="p">.</span><span class="py">Entry</span> <span class="o">-match</span> <span class="s1">&#39;qq|weixin|gtimg|tcdnos|dldir&#39;</span> <span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="2">
<li>看进程出站连接（<code>Get-NetTCPConnection -OwningProcess &lt;pid&gt;</code>），把新域名补进 hosts。</li>
<li>已建立的 TCP 连接不会因改 hosts 立刻断，需退出客户端再试。</li>
</ol>
<hr>
<h2 id="五和-revokemsgpatcher-的关系再强调一次">
<a class="header-anchor" href="#%e4%ba%94%e5%92%8c-revokemsgpatcher-%e7%9a%84%e5%85%b3%e7%b3%bb%e5%86%8d%e5%bc%ba%e8%b0%83%e4%b8%80%e6%ac%a1"></a>
五、和 RevokeMsgPatcher 的关系（再强调一次）
</h2><p>防更新的目的不是「永远不用新版本」，而是：</p>
<blockquote>
<p><strong>把客户端钉在 patch 特征仍然匹配的版本上，避免热更新把防撤回打失效。</strong></p>
</blockquote>
<p>PR #1193 侧当前明确测过 / 面向的上限是：</p>
<ul>
<li>QQNT：<code>9.9.20-36330</code>（含私聊 C2C 被动撤回路径）</li>
<li>微信：<code>4.1.9.30</code></li>
</ul>
<p>版本一涨，需要重新找特征、更新 <code>patch.json</code> / 资源，而不是指望旧二进制一直能用。<br>
上游合并进度、后续版本支持范围以仓库与 PR 讨论为准：<br>
<a href="https://github.com/huiyadanli/RevokeMsgPatcher/pull/1193" target="_blank" rel="noopener noreferrer nofollow">https://github.com/huiyadanli/RevokeMsgPatcher/pull/1193</a>
</p>
<hr>
<h2 id="六恢复方法简要">
<a class="header-anchor" href="#%e5%85%ad%e6%81%a2%e5%a4%8d%e6%96%b9%e6%b3%95%e7%ae%80%e8%a6%81"></a>
六、恢复方法（简要）
</h2><ol>
<li>从改 hosts 前的备份恢复 <code>C:\Windows\System32\drivers\etc\hosts</code>，或删掉本文相关段落。</li>
<li><code>ipconfig /flushdns</code></li>
<li>删除防火墙规则「Block WeixinUpdate outbound*」</li>
<li>恢复 <code>xwechat\update</code> 目录权限（去掉 Deny 写入）</li>
<li>需要升级时再走官方更新即可</li>
</ol>
<hr>
<h2 id="小结">
<a class="header-anchor" href="#%e5%b0%8f%e7%bb%93"></a>
小结
</h2><table>
  <thead>
      <tr>
          <th>客户端</th>
          <th>关键域名</th>
          <th>本地缓存</th>
          <th>额外手段</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>QQNT</td>
          <td><code>qqpatch.gtimg.cn</code>，以及 <code>*.tcdnos.com</code> 下载 CDN</td>
          <td><code>QQNT\versions\</code> + <code>config.json</code> 的 <code>readyVersion</code></td>
          <td>删已就绪版本目录</td>
      </tr>
      <tr>
          <td>微信 4.x</td>
          <td><code>dldir*.qq.com</code>（补 IPv6）</td>
          <td><code>%AppData%\Tencent\xwechat\update\</code></td>
          <td>锁目录 + 拦 <code>WeixinUpdate.exe</code></td>
      </tr>
  </tbody>
</table>
<p><strong>只拦 dldir、不管本地已就绪包，是最常见的「hosts 设了还是在更」原因。</strong><br>
为了配合 RevokeMsgPatcher 的版本上限，应把「拦域名 + 清缓存 + 必要时权限/防火墙」当成一套流程，而不是单点技巧。</p>

        
        <hr><p>本文2026-07-25首发于<a href='https://cat.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-07-25</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>通过读取微信进程内存提取公众号信息流广告视频下载地址</title>
      <link>https://cat.fjh1997.top/posts/58321.html</link>
      <pubDate>Sun, 15 Mar 2026 17:31:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://cat.fjh1997.top/posts/58321.html</guid>
      <description>
        <![CDATA[<h1>通过读取微信进程内存提取公众号信息流广告视频下载地址</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="背景">
<a class="header-anchor" href="#%e8%83%8c%e6%99%af"></a>
背景
</h2><p><img
  src="/images/2026-03-15-18-47-23.png"
  alt="2026-03-15-18-47-23" width="1649" height="1052"
  loading="lazy"
  decoding="async"
/>

在PC端微信的公众号列表中，经常会看到信息流广告视频，比如游戏广告。这些广告视频有时候挺有意思，想下载下来，但微信并没有提供下载按钮。比如看到这个广告视频的妹妹很好看🤪，那么应该怎么下载呢？本文以这个&quot;三国冰河时代&quot;游戏广告为例，介绍如何通过读取微信进程内存来提取广告视频的下载地址。</p>
<h2 id="尝试一寻找本地缓存文件失败">
<a class="header-anchor" href="#%e5%b0%9d%e8%af%95%e4%b8%80%e5%af%bb%e6%89%be%e6%9c%ac%e5%9c%b0%e7%bc%93%e5%ad%98%e6%96%87%e4%bb%b6%e5%a4%b1%e8%b4%a5"></a>
尝试一：寻找本地缓存文件（失败）
</h2><p>首先想到的思路是微信可能把视频缓存到了本地磁盘。微信PC端的数据目录一般在：</p>
<pre tabindex="0"><code>C:\Users\{用户名}\Documents\WeChat Files\{微信ID}\FileStorage\
</code></pre><p>该目录下有这些子目录：</p>
<pre tabindex="0"><code>Cache、Video、Image、Temp、Sns、MsgAttach ...
</code></pre><p>其中 <code>Video</code> 目录按月份分文件夹存放：</p>
<pre tabindex="0"><code>2024-04、2024-05、... 2025-08
</code></pre><p>但逐个检查后发现这些目录要么为空，要么只有聊天中收发的视频。<strong>公众号信息流广告的视频并不会被缓存到这里。</strong></p>
<p>同样检查了 <code>AppData</code> 下的微信目录：</p>
<pre tabindex="0"><code>C:\Users\{用户名}\AppData\Roaming\Tencent\WeChat\
C:\Users\{用户名}\AppData\Roaming\Tencent\xwechat\
</code></pre><p>新版微信（xwechat）使用了 Chromium 内核（RadiumWMPF），有类似浏览器的缓存结构：</p>
<pre tabindex="0"><code>xwechat\radium\web\profiles\webview_{用户hash}\
xwechat\radium\web\profiles\multitab_{用户hash}\
</code></pre><p>里面有 <code>Code Cache</code>、<code>IndexedDB</code>、<code>GPUCache</code> 等 Chromium 标准缓存目录，但也没找到视频文件。</p>
<p><strong>结论：公众号信息流广告视频是流式加载的，不会完整缓存到本地磁盘。</strong></p>
<h2 id="尝试二通过开发者工具远程调试失败">
<a class="header-anchor" href="#%e5%b0%9d%e8%af%95%e4%ba%8c%e9%80%9a%e8%bf%87%e5%bc%80%e5%8f%91%e8%80%85%e5%b7%a5%e5%85%b7%e8%bf%9c%e7%a8%8b%e8%b0%83%e8%af%95%e5%a4%b1%e8%b4%a5"></a>
尝试二：通过开发者工具/远程调试（失败）
</h2><p>既然新版微信使用 Chromium 内核，理论上可以通过 <code>--remote-debugging-port</code> 参数连接 DevTools 来抓取网络请求。</p>
<p>查看微信进程的命令行参数：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-CimInstance</span> <span class="n">Win32_Process</span> <span class="n">-Filter</span> <span class="s2">&#34;Name=&#39;WeChatAppEx.exe&#39;&#34;</span> <span class="p">|</span> <span class="nb">Select-Object</span> <span class="n">ProcessId</span><span class="p">,</span> <span class="n">CommandLine</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>发现主进程的启动参数中并没有 <code>--remote-debugging-port</code>，说明远程调试未开启，这条路也走不通。</p>
<h2 id="尝试三进程内存扫描成功">
<a class="header-anchor" href="#%e5%b0%9d%e8%af%95%e4%b8%89%e8%bf%9b%e7%a8%8b%e5%86%85%e5%ad%98%e6%89%ab%e6%8f%8f%e6%88%90%e5%8a%9f"></a>
尝试三：进程内存扫描（成功）
</h2><p>既然视频是流式加载的，那视频的URL一定在微信进程的内存中。思路是：<strong>直接读取微信进程内存，搜索视频URL模式。</strong></p>
<h3 id="第一步定位微信进程">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%80%e6%ad%a5%e5%ae%9a%e4%bd%8d%e5%be%ae%e4%bf%a1%e8%bf%9b%e7%a8%8b"></a>
第一步：定位微信进程
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-Process</span> <span class="p">|</span> <span class="nb">Where-Object</span> <span class="p">{</span> <span class="nv">$_</span><span class="p">.</span><span class="py">ProcessName</span> <span class="o">-match</span> <span class="s1">&#39;wechat&#39;</span> <span class="p">}</span> <span class="p">|</span>
</span></span><span class="line"><span class="cl">    <span class="nb">Select-Object</span> <span class="n">Id</span><span class="p">,</span> <span class="n">ProcessName</span><span class="p">,</span> <span class="n">Path</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>发现微信运行了多个 <code>WeChatAppEx.exe</code> 进程，这是典型的 Chromium 多进程架构：</p>
<table>
  <thead>
      <tr>
          <th>进程类型</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主进程（无 &ndash;type 参数）</td>
          <td>浏览器主进程，包含页面数据</td>
      </tr>
      <tr>
          <td>&ndash;type=gpu-process</td>
          <td>GPU渲染进程</td>
      </tr>
      <tr>
          <td>&ndash;type=renderer</td>
          <td>页面渲染进程</td>
      </tr>
      <tr>
          <td>&ndash;type=utility &ndash;utility-sub-type=network</td>
          <td>网络服务进程</td>
      </tr>
  </tbody>
</table>
<p>我们要扫描的是<strong>主进程</strong>（没有 <code>--type</code> 参数的那个）。</p>
<h3 id="第二步编写内存扫描脚本">
<a class="header-anchor" href="#%e7%ac%ac%e4%ba%8c%e6%ad%a5%e7%bc%96%e5%86%99%e5%86%85%e5%ad%98%e6%89%ab%e6%8f%8f%e8%84%9a%e6%9c%ac"></a>
第二步：编写内存扫描脚本
</h3><p>通过 PowerShell 调用 Windows API 来读取进程内存：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Add-Type</span> <span class="n">-TypeDefinition</span> <span class="sh">@&#39;
</span></span></span><span class="line"><span class="cl"><span class="sh">using System;
</span></span></span><span class="line"><span class="cl"><span class="sh">using System.Runtime.InteropServices;
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">public class MemoryReader {
</span></span></span><span class="line"><span class="cl"><span class="sh">    [DllImport(&#34;kernel32.dll&#34;)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public static extern IntPtr OpenProcess(
</span></span></span><span class="line"><span class="cl"><span class="sh">        int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">    [DllImport(&#34;kernel32.dll&#34;)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public static extern bool ReadProcessMemory(
</span></span></span><span class="line"><span class="cl"><span class="sh">        IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer,
</span></span></span><span class="line"><span class="cl"><span class="sh">        int dwSize, ref int lpNumberOfBytesRead);
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">    [DllImport(&#34;kernel32.dll&#34;)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public static extern int VirtualQueryEx(
</span></span></span><span class="line"><span class="cl"><span class="sh">        IntPtr hProcess, IntPtr lpAddress,
</span></span></span><span class="line"><span class="cl"><span class="sh">        out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">    [DllImport(&#34;kernel32.dll&#34;)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public static extern bool CloseHandle(IntPtr hObject);
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">    [StructLayout(LayoutKind.Sequential)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public struct MEMORY_BASIC_INFORMATION {
</span></span></span><span class="line"><span class="cl"><span class="sh">        public IntPtr BaseAddress;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public IntPtr AllocationBase;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public uint AllocationProtect;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public IntPtr RegionSize;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public uint State;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public uint Protect;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public uint Type;
</span></span></span><span class="line"><span class="cl"><span class="sh">    }
</span></span></span><span class="line"><span class="cl"><span class="sh">}
</span></span></span><span class="line"><span class="cl"><span class="sh">&#39;@</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>核心逻辑是遍历进程的所有已提交内存区域（<code>MEM_COMMIT = 0x1000</code>），读取内容后用正则匹配视频URL：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nv">$targetPid</span> <span class="p">=</span> <span class="mf">42172</span>  <span class="c"># 微信主进程PID</span>
</span></span><span class="line"><span class="cl"><span class="nv">$handle</span> <span class="p">=</span> <span class="p">[</span><span class="no">MemoryReader</span><span class="p">]::</span><span class="n">OpenProcess</span><span class="p">(</span><span class="n">0x0410</span><span class="p">,</span> <span class="vm">$false</span><span class="p">,</span> <span class="nv">$targetPid</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c"># 0x0410 = PROCESS_VM_READ | PROCESS_QUERY_INFORMATION</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">$address</span> <span class="p">=</span> <span class="p">[</span><span class="no">IntPtr</span><span class="p">]::</span><span class="n">Zero</span>
</span></span><span class="line"><span class="cl"><span class="nv">$mbi</span> <span class="p">=</span> <span class="nb">New-Object</span> <span class="n">MemoryReader</span><span class="p">+</span><span class="n">MEMORY_BASIC_INFORMATION</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="p">([</span><span class="no">MemoryReader</span><span class="p">]::</span><span class="n">VirtualQueryEx</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="nv">$handle</span><span class="p">,</span> <span class="nv">$address</span><span class="p">,</span> <span class="p">[</span><span class="no">ref</span><span class="p">]</span><span class="nv">$mbi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="no">uint32][Runtime.InteropServices.Marshal</span><span class="p">]::</span><span class="n">SizeOf</span><span class="p">(</span><span class="nv">$mbi</span><span class="p">))</span> <span class="o">-ne</span> <span class="mf">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c"># 只扫描已提交的、大小合理的内存区域</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nv">$mbi</span><span class="p">.</span><span class="py">State</span> <span class="o">-eq</span> <span class="n">0x1000</span> <span class="o">-and</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$mbi</span><span class="p">.</span><span class="py">RegionSize</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">()</span> <span class="o">-lt</span> <span class="mf">10</span><span class="p">MB</span> <span class="o">-and</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$mbi</span><span class="p">.</span><span class="py">RegionSize</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">()</span> <span class="o">-gt</span> <span class="mf">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$buffer</span> <span class="p">=</span> <span class="nb">New-Object</span> <span class="n">byte</span><span class="p">[]</span> <span class="p">(</span><span class="nv">$mbi</span><span class="p">.</span><span class="py">RegionSize</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$bytesRead</span> <span class="p">=</span> <span class="mf">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">([</span><span class="no">MemoryReader</span><span class="p">]::</span><span class="n">ReadProcessMemory</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$handle</span><span class="p">,</span> <span class="nv">$mbi</span><span class="p">.</span><span class="n">BaseAddress</span><span class="p">,</span> <span class="nv">$buffer</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$buffer</span><span class="p">.</span><span class="n">Length</span><span class="p">,</span> <span class="p">[</span><span class="no">ref</span><span class="p">]</span><span class="nv">$bytesRead</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$text</span> <span class="p">=</span> <span class="p">[</span><span class="no">System.Text.Encoding</span><span class="p">]::</span><span class="n">UTF8</span><span class="p">.</span><span class="py">GetString</span><span class="p">(</span><span class="nv">$buffer</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="c"># 匹配广告视频URL模式</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$regex</span> <span class="p">=</span> <span class="s1">&#39;https?://[^\x00\s&#34;&lt;&gt;]{10,500}&#39;</span> <span class="p">+</span>
</span></span><span class="line"><span class="cl">                     <span class="s1">&#39;(?:\.mp4|mpvideo|finder.*video|wxv_|video\.qq|findermp)&#39;</span> <span class="p">+</span>
</span></span><span class="line"><span class="cl">                     <span class="s1">&#39;[^\x00\s&#34;&lt;&gt;]{0,200}&#39;</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$matches</span> <span class="p">=</span> <span class="p">[</span><span class="no">regex</span><span class="p">]::</span><span class="n">Matches</span><span class="p">(</span><span class="nv">$text</span><span class="p">,</span> <span class="nv">$regex</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">foreach</span> <span class="p">(</span><span class="nv">$m</span> <span class="k">in</span> <span class="nv">$matches</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nv">$url</span> <span class="p">=</span> <span class="nv">$m</span><span class="p">.</span><span class="py">Value</span> <span class="o">-replace</span> <span class="s1">&#39;[\x00-\x1f]&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span> <span class="p">(</span><span class="nv">$url</span><span class="p">.</span><span class="py">Length</span> <span class="o">-gt</span> <span class="mf">20</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="nb">Write-Host</span> <span class="nv">$url</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nv">$address</span> <span class="p">=</span> <span class="p">[</span><span class="no">IntPtr</span><span class="p">](</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$mbi</span><span class="p">.</span><span class="py">BaseAddress</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">()</span> <span class="p">+</span> <span class="nv">$mbi</span><span class="p">.</span><span class="py">RegionSize</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nv">$address</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">()</span> <span class="o">-lt</span> <span class="mf">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">break</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="no">MemoryReader</span><span class="p">]::</span><span class="n">CloseHandle</span><span class="p">(</span><span class="nv">$handle</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="第三步扫描结果">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%89%e6%ad%a5%e6%89%ab%e6%8f%8f%e7%bb%93%e6%9e%9c"></a>
第三步：扫描结果
</h3><p>扫描了 2357 个内存区域，找到了 <strong>115 个视频URL</strong>，去重后主要是以下几个广告视频（来自 <code>wxsmw.wxs.qq.com</code> 域名）：</p>
<pre tabindex="0"><code>http://wxsmw.wxs.qq.com/.../ads_svp_video__0bc3qyabeaaacyapvlro4zurvbqeckdaaesa.f142000.mp4?dis_k=...&amp;dis_t=1764683224&amp;...
http://wxsmw.wxs.qq.com/.../ads_svp_video__0b53xabuuaad6aap6xr4u5ubtoaejk4agssa.f142000.mp4?dis_k=...&amp;dis_t=1749005722&amp;...
http://wxsmw.wxs.qq.com/.../ads_svp_video__0b53qiaowaaapmaabparcrubvaqe5obab22a.f142000.mp4?dis_k=...&amp;dis_t=1746007401&amp;...
</code></pre><p>URL的规律：</p>
<ul>
<li>域名：<code>wxsmw.wxs.qq.com</code> 或 <code>wxsnsdy.wxs.qq.com</code>（腾讯视频CDN）</li>
<li>路径包含 <code>ads_svp_video</code> 标识这是广告视频</li>
<li>参数 <code>dis_t</code> 是时间戳，可以用来判断哪个是最近的广告</li>
<li>参数 <code>dis_k</code> 和 <code>sha256</code> 用于鉴权</li>
</ul>
<h3 id="第四步确认目标视频">
<a class="header-anchor" href="#%e7%ac%ac%e5%9b%9b%e6%ad%a5%e7%a1%ae%e8%ae%a4%e7%9b%ae%e6%a0%87%e8%a7%86%e9%a2%91"></a>
第四步：确认目标视频
</h3><p>有多个广告视频URL，需要确认哪个是&quot;三国冰河时代&quot;。用同样的内存扫描方法，搜索中文关键词&quot;三国&quot;（注意要同时搜索 UTF-8 和 UTF-16LE 两种编码，因为 Windows 进程内存中两种编码都可能存在）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># UTF-8 编码的&#34;三国&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">$searchUtf8</span> <span class="p">=</span> <span class="p">[</span><span class="no">System.Text.Encoding</span><span class="p">]::</span><span class="n">UTF8</span><span class="p">.</span><span class="py">GetBytes</span><span class="p">(</span><span class="s1">&#39;三国&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c"># UTF-16LE 编码的&#34;三国&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">$searchUtf16</span> <span class="p">=</span> <span class="p">[</span><span class="no">System.Text.Encoding</span><span class="p">]::</span><span class="n">Unicode</span><span class="p">.</span><span class="py">GetBytes</span><span class="p">(</span><span class="s1">&#39;三国&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在内存中确实找到了多处&quot;三国冰河时代&quot;的引用，包括：</p>
<ul>
<li>公众号文章元数据：<code>&quot;三国冰河时代挥师定山河活动解析&quot;</code></li>
<li>搜索记录：<code>&quot;query&quot;: &quot;三国 冰河时代&quot;</code></li>
<li>视频播放记录：<code>kVideoTracks...三国 冰河时代 - 搜一搜</code>，编码格式 <code>h264 high</code></li>
</ul>
<p>通过 <code>dis_t</code> 时间戳判断，最新的广告视频URL就是目标视频。</p>
<h3 id="第五步下载视频">
<a class="header-anchor" href="#%e7%ac%ac%e4%ba%94%e6%ad%a5%e4%b8%8b%e8%bd%bd%e8%a7%86%e9%a2%91"></a>
第五步：下载视频
</h3><p>直接用 curl 下载：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -o <span class="s2">&#34;三国冰河时代_广告视频.mp4&#34;</span> <span class="s2">&#34;http://wxsmw.wxs.qq.com/131/20210/snssvpdownload/SH/reserved/ads_svp_video__0bc3qyabeaaacyapvlro4zurvbqeckdaaesa.f142000.mp4?dis_k=...&amp;dis_t=...&amp;sha256=...&amp;m=...&amp;posid=...&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>返回 HTTP 200，文件大小约 7MB，<code>Content-Type: video/mp4</code>，下载成功。</p>
<h2 id="原理总结">
<a class="header-anchor" href="#%e5%8e%9f%e7%90%86%e6%80%bb%e7%bb%93"></a>
原理总结
</h2><pre tabindex="0"><code>微信公众号信息流
    ↓ 加载广告
腾讯CDN（wxsmw.wxs.qq.com）
    ↓ 流式传输视频
WeChatAppEx.exe 进程内存
    ↓ ReadProcessMemory
提取视频URL → curl下载
</code></pre><p>整个过程的关键点：</p>
<ol>
<li><strong>公众号信息流广告视频不缓存到本地磁盘</strong>，只在进程内存中存在</li>
<li>新版微信（xwechat）基于 Chromium 内核（RadiumWMPF），视频URL以明文形式保存在进程内存中</li>
<li>使用 Windows API <code>OpenProcess</code> + <code>VirtualQueryEx</code> + <code>ReadProcessMemory</code> 可以遍历读取目标进程的内存</li>
<li>广告视频URL的特征是域名为 <code>wxsmw.wxs.qq.com</code>，路径包含 <code>ads_svp_video</code></li>
<li>URL中的鉴权参数（<code>dis_k</code>、<code>sha256</code>、<code>m</code>）有时效性，需要在有效期内下载</li>
</ol>
<h2 id="注意事项">
<a class="header-anchor" href="#%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9"></a>
注意事项
</h2><ul>
<li>需要以当前用户权限运行，不需要管理员权限（因为微信也是当前用户启动的）</li>
<li>视频URL中的鉴权token有时效性，过期后需要重新扫描</li>
<li>扫描过程中微信需要保持运行，且目标广告页面需要已加载过</li>
<li>此方法同样适用于提取微信中其他流式加载的媒体内容的URL</li>
</ul>

        
        <hr><p>本文2026-03-15首发于<a href='https://cat.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-15</p>]]>
      </description>
      
    </item>
    
  </channel>
</rss>
