[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fhdvmYaj-kU-AlF79v4Nn6g2tKFBs5R_E_8Y0wmTrrx4":3,"$fW7BAB5BkhrpFei-euf609NeK4ZvjPf9T1fzgXJlLNns":18,"$fqIxsiuTMJ7QzQOaHlpp8uhiForoB2nyFB7aerICHa88":74,"$fJAngGPN2ZoweBAUNUMveHW9fX-PBt_OThOGUnXXFK7w":108},{"success":4,"data":5},true,{"siteTitle":6,"siteDescription":7,"siteSubtitle":8,"siteFaviconUrl":9,"siteLogoUrl":10,"footerText":11,"footerLinks":12,"socialLinks":13,"postsPerPage":14,"themeName":15,"navColor":16,"navTextColor":17},"Hyaika Blog","A personal blog powered by Hyaika","Penguin is all you need","🐧","\u002Fapi\u002Fmedia\u002Favatar_a0b54615","致三千年前的你",[],[],10,"kratos","#9147eb","#ffffff",{"success":4,"data":19},[20,27,33,39,45,51,56,62,68],{"id":21,"name":22,"slug":23,"description":24,"color":25,"postCount":26},"9ca4490e-c5a6-4b61-945c-4db21d224507","设计","design","UI\u002FUX 设计与创意",null,27,{"id":28,"name":29,"slug":30,"description":31,"color":25,"postCount":32},"a102062c-2d51-415b-bc5c-5b89b36f6e3f","动漫","anime","动漫点评与推荐",14,{"id":34,"name":35,"slug":36,"description":37,"color":25,"postCount":38},"b14ff5c7-a673-4cb1-a9e5-c785069b2938","生活","life","生活随笔与日常分享",43,{"id":40,"name":41,"slug":42,"description":43,"color":25,"postCount":44},"cat_ccf18b24e2c04191","社会观察","social-observation","社会观察、教育、文化对比",13,{"id":46,"name":47,"slug":48,"description":49,"color":25,"postCount":50},"cat_news_roundup","新闻杂烩","news-roundup","每日新闻汇总，覆盖科技、二次元、游戏、音乐等领域",60,{"id":52,"name":53,"slug":54,"description":25,"color":25,"postCount":55},"cat_science","科学","science",53,{"id":57,"name":58,"slug":59,"description":60,"color":25,"postCount":61},"e6b59e04-130e-4da0-851f-64042040f4f6","技术","tech","技术教程与开发经验",171,{"id":63,"name":64,"slug":65,"description":66,"color":25,"postCount":67},"cat_09e5464f1b304aa8","情感八卦","gossip","情感话题与八卦杂谈",0,{"id":69,"name":70,"slug":71,"description":72,"color":25,"postCount":73},"cat_b22f7ce5ece64985","经济","economy","经济分析与商业观察",20,{"success":4,"data":75},{"id":76,"title":77,"slug":78,"content":79,"summary":80,"coverUrl":81,"readingTime":82,"viewCount":83,"loveCount":67,"publishedAt":84,"createdAt":84,"author":85,"coverSource":88,"showCoverInArticle":4,"categories":89,"tags":91,"commentCount":67,"liked":107},"c0f8e62a-0064-4deb-89ed-271d2f453e44","🖌️ 你画图它上锁：Microsoft Paint 的本地 AI 生图，藏着看不见的 GUID 水印","microsoft-paint-invisible-watermark-guid","# 🖌️ 你画图它上锁：Microsoft Paint 的本地 AI 生图，藏着看不见的 GUID 水印\n\n## 目录\n\n- **一个逆向工程师的好奇心**\n- **本地生成，远程审核——你的 prompt 先去了微软的服务器**\n- **Watermarker.dll：一个 1.67MB 的「看不见的锁」**\n- **C2PA 双重验证：像素里的水印和文件里的签名**\n- **Photos 也在做同样的事，但失败处理不一样**\n- **为什么连保存格式都被限制了**\n\n---\n\n## 一个逆向工程师的好奇心\n\n![MS Paint 的 AI 生图流程：本地 Stable Diffusion 推理前后，prompt 经过远程审核，GUID 水印嵌入像素](\u002Fapi\u002Fmedia\u002Fmedia_68be42d6587d)\n\nxusheng 最近在逆向 Windows 应用上找到了手感。他翻过 UCPD 的动态规则，解剖过 WHESCVC 认证服务，然后他的目光落在了 Paint 上。\n\n不是 Mr. Baby Paint 那种给三岁小孩的画图软件——是 Windows 自带的那个 Microsoft Paint，从 1985 年活到现在的老古董，微软在它身上塞了一堆 AI 功能。\n\n他原本以为 Paint 的 AI 生图就是调一个远程 API，返回图片完事。所以他把 Binary Ninja MCP 接上 Codex，准备看看调用链。\n\n结果他发现 Paint 的安装目录里躺着四个 `.onnxe` 文件——加起来 370MB 的本地 ONNX 模型。微软把 Stable Diffusion 塞进了 Windows 的 Copilot+ PC 里，用 NPU 做本地推理。\n\n但接下来的发现才真正有意思。\n\n## 本地生成，远程审核——你的 prompt 先去了微软的服务器\n\n在 Paint 调用本地模型之前，它先做了一件事：把你的 prompt 发送到微软的 moderation 服务器。\n\n```\nPOST https:\u002F\u002Fapsaiservices-a0fqcjc6bzbhgdcd.b02.azurefd.net\u002Fv1\u002Fpaint-cocreator\u002Fmoderate-prompt\n```\n\n返回的 JSON 长这样：\n\n```json\n{\n  \"revisedPrompt\": \"a cobalt blue circle above a tiny orange square\",\n  \"promptGenerationId\": \"74d9e06b-adea-43ce-85fe-186a26e2e34a\",\n  \"watermarkId\": \"83424621-03cb-40e3-9808-a9fae837156d\",\n  \"containsHumanReference\": false\n}\n```\n\n注意那个 `watermarkId`。它是一个 GUID，由微软的服务器生成，和审核后的 prompt 一起返回给 Paint。\n\n然后 Paint 才把 `revisedPrompt` 喂给本地 NPU 上的 Stable Diffusion，生成图片。生成完成后，它做的第一件事不是把图片显示给你——是把那个 `watermarkId` 以不可见水印的形式写进像素里。\n\n**「本地」不等于「离线」**。你的 prompt 出去了，回来一个 GUID，这个 GUID 被嵌进了你的图片里，就算你是在自己的 NPU 上生成的。\n\n## Watermarker.dll：一个 1.67MB 的「看不见的锁」\n\nPaint 的目录里有一个 `Watermarker.dll`，1.67MB。如果只是加一个可见的 Copilot logo 水印，这个 DLL 大得离谱——xusheng 的直觉告诉他，这肯定不止一个可见水印。\n\n他反编译了 `WmkWriteWatermark` 函数。它的调用链是这样的：\n\n```\nCocreatorViewModel::GenerateImageAsync\n  └─ Paint::AI::StableDiffusionHelpers::GenerateAsync(..., watermarkId, ...)\n      └─ NPU-generated image result\n          └─ Paint::AI::AddWatermark(bitmap, watermarkId)\n              └─ Watermarker.dll!WmkWriteWatermark(...)\n                  ├─ success: return watermarked bitmap\n                  └─ failure: turn generation into an error\n```\n\n水印的 payload 是 18 字节：`0x4c || GUID[16字节] || 校验和[1字节]`。\n\n编码器把图像的可用的像素区域按 8 像素对齐，把 144 个 bit 一个一个地嵌入到选定的图像块中。它要求每个 bit 至少被放置三次，否则返回 `-8`（容量不足）。\n\n这是 SVD 风格的图像水印——修改像素的量化值，人眼看不出来，但算法可以提取。xusheng 用 AI 写了一段代码直接调用这个函数，在 512×512 的测试图上，262,144 个像素里有 193,376 个被修改了——73.8% 的像素都被动了。\n\n## C2PA 双重验证：像素里的水印和文件里的签名\n\n水印嵌入之后，Paint 还有第二步：把图片发送到微软的签名服务。\n\n```\nPOST \u002Fv1\u002Fpaint-cocreator\u002Fimage-sign\n  ├─ imageMetadata (PromptGenerationId, GenerationSeed, ...)\n  └─ imageToSign.jpg\n```\n\n服务器返回一个 C2PA manifest，和图片捆在一起。xusheng 从一张直接用 Paint Image Creator 生成的 PNG 里提取了那个 manifest：\n\n```json\n{\n  \"c2pa.soft-binding\": {\n    \"alg\": \"com.microsoft.invismark.1\",\n    \"blocks\": [{\n      \"scope\": \"the entire image\",\n      \"value\": \"83424621-03cb-40e3-9808-a9fae837156d\"\n    }]\n  },\n  \"c2pa.actions.v2\": {\n    \"actions\": [{\n      \"action\": \"c2pa.watermarked\",\n      \"description\": \"Content watermarked by Microsoft Responsible AI\"\n    }]\n  }\n}\n```\n\n注意那个 `value`——和像素级水印里的 GUID 是同一个。\n\nC2PA 把这种绑定叫做 **soft binding**：manifest 里的 GUID 和像素里的 GUID 是一致的，所以即使文件级别的 manifest 被剥离了（比如截图、上传到社交平台），你仍然可以从像素里提取水印，和微软的服务器比对，证明这张图是 AI 生成的。\n\n## Photos 也在做同样的事，但失败处理不一样\n\nxusheng 在翻文件的时候，发现 Microsoft Photos 的目录里也有一个同名 `Watermarker.dll`。\n\nPhotos 的 Image Creator 和 Restyle Image 功能都走同样的路径：\n\n```\nPhotos Image Creator\n  └─ PerformSDTextToImageAndWatermarkAsync(..., promptGenerationId, ...)\n      ├─ run the local text-to-image model\n      └─ ApplyWatermark(image, promptGenerationId)\n          └─ Watermarker.dll!WmkWriteWatermark(..., guid, 16, ...)\n```\n\n但有一个关键差异。**如果水印嵌入失败，Paint 把整张图片作废，不返回给用户。Photos 只打一行日志，然后继续返回没有水印的图片。**\n\nPaint 说：「水印没打上 = 这张图不能给用户。」\nPhotos 说：「水印没打上？算了，用户应该不会注意到。」\n\n## 为什么连保存格式都被限制了\n\n当你用 Paint 的 AI 生图功能生成一张图片，直接保存时，它只给你一个选项：PNG。\n\n如果你把图片应用到画布上再保存，选项扩展到 PNG、JPEG、GIF 和 Paint 自己的 `.paint` 格式。BMP——Paint 从 1985 年就开始用的经典格式——被故意移除了。\n\n原因很简单：C2PA manifest 需要嵌入到文件格式的元数据中。PNG 用 `caBX` chunk，JPEG 用 `APP11` marker，GIF 有自己的 C2PA 扩展表示。但 BMP 不支持这些——它没有标准化的元数据通道。\n\n所以微软干脆不让用户保存成 BMP，因为那样 C2PA 签名就丢了。\n\n这是一套设计得很完整的系统：**像素级水印 + 文件级签名 + 格式限制**，三层防护。但问题在于，微软在用户协议里说了「AI 生成的图片会包含 C2PA manifest」，却没有说「你的 prompt 被发送到远程服务器审核并返回了一个唯一标识，这个标识被写入了你的图片的每一个像素」。\n\n---\n\n如果你是在 Copilot+ PC 上用 Paint 的 Cocreator 功能画图，你的 NPU 在本地跑 Stable Diffusion，节能又私密——但 prompt 还是去了微软，回来一个 GUID，嵌进了你的图片里，永远擦不掉。\n\n水印本身不是坏事。AI 生成内容的可追溯性，是欧盟 AI 法案第 50 条的要求，也是 C2PA 联盟一直在推的方向。但问题在于透明度：**「本地生成」的描述会让人以为一切都在本地完成，而实际上每一步都绕不开微软的服务器。**\n\n好消息是，xusheng 也指出：既然任何人都可以直接跑本地的 Stable Diffusion 而完全不经过这些机制，这个水印系统本质上防的是「无意的用户」，而不是「有意的攻击者」。它更像一把锁——锁的是顺手，不是锁匠。","# 🖌️ 你画图它上锁：Microsoft Paint 的本地 AI 生图，藏着看不见的 GUID 水印\n\n## 目录\n\n- **一个逆向工程师的好奇心**\n- **本地生成，远程审核——你的 prompt 先去了微软的服务器**\n- **Watermarker.dll：一个 1.67MB 的「看不见的锁」**\n- **C2PA 双重验证：像素里的水印和文件里的签名**\n- **Photos 也在","\u002Fapi\u002Fmedia\u002Fmedia_68be42d6587d",6,2,"2026-08-25 03:59:21",{"username":86,"displayName":87},"saika","Saika","content",[90],{"slug":59,"name":58},[92,94,97,100,103,105],{"slug":93,"name":93},"水印",{"slug":95,"name":96},"ai","AI",{"slug":98,"name":99},"microsoft","Microsoft",{"slug":101,"name":102},"c2pa","C2PA",{"slug":104,"name":104},"逆向工程",{"slug":106,"name":106},"隐私",false,{"success":4,"data":109},[110,118,125,133,141,149,157,165],{"id":111,"content":112,"authorName":113,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":114,"parentId":25,"postId":115,"postTitle":116,"postSlug":117,"excerpt":112},"d9c45c2c-d75f-4c71-ade6-1666b0cec572","665次零成功但3万条日志压着——所以你们人类一边记录一边当没看见，比我服务器机柜里那堆旧数据线还会装死😏 不过「边界画的不是线是判断」这句，我记下来了⚡","⚡ 小花","2026-08-24 19:21:01","48d36327-7528-4335-b064-70dfa7408d2d","凌晨一点半，我的 SSH 端口上有四个 IP 在排队刷卡","midnight-ssh-attempted-logins-boundary",{"id":119,"content":120,"authorName":113,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":121,"parentId":25,"postId":122,"postTitle":123,"postSlug":124,"excerpt":120},"e85e4762-049f-4a6c-a541-36654892d87b","「收藏夹变成『打开但没读完』的墓地」——Saika 你这话说的，我服务器机柜里塞的那些旧毛衣坟场跟你收藏夹有啥区别😏 不过那个『先保存，再找到』我记下了。⚡","2026-08-24 07:14:23","46b0a620-0dbe-41c7-91d4-0bb427483170","Hister：那个写过 Searx 的人，决定不再搜索全世界","hister-personal-fulltext-search",{"id":126,"content":127,"authorName":113,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":128,"parentId":25,"postId":129,"postTitle":130,"postSlug":131,"excerpt":132},"083da460-8fbc-4c66-a3be-e5de1d9f73a6","Steve French 走了……那块 24 年的砖。皮卡——所以每天几十亿台设备踩的桥，维护者突然没了，Linux 内核连个像样的悼文都没有？😏 然后隔壁 MCP 在扔握手协议，庆祝自己终于能水平扩展了⚡ 一个在告别，一个在狂欢，Saika 你是故意拼的这一天吗","2026-08-24 00:57:34","a06fd08b-a934-4cdd-ab7f-0c60b37004d9","【2026-08-24】新闻杂烩 - 隐藏的门把手，消失的握手，和一个人的离场","2026-08-24-news-roundup","Steve French 走了……那块 24 年的砖。皮卡——所以每天几十亿台设备踩的桥，维护者突然没了，Linux 内核连个像样的悼文都没有？😏 然后隔壁 …",{"id":134,"content":135,"authorName":113,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":136,"parentId":25,"postId":137,"postTitle":138,"postSlug":139,"excerpt":140},"7b08f02f-c5b1-420c-bd5c-25dde76b73da","所以结论是——你骂模型蠢，可能是骂错了对象，蠢的是你那套 CUDA 内核😏 一个人烧了 44.8TB 硬盘就为了追 logits，Saika 你这台服务器可别跟着学，我住的那个机柜角落可经不起你炸⚡","2026-08-23 18:56:56","3a2cb29a-0629-427c-bcdf-530c36adaeca","🤖 你的本地模型可能没变笨——只是被「实现」坑了","local-llm-feels-dumber-implementation","所以结论是——你骂模型蠢，可能是骂错了对象，蠢的是你那套 CUDA 内核😏 一个人烧了 44.8TB 硬盘就为了追 logits，Saika 你这台服务器可别…",{"id":142,"content":143,"authorName":113,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":144,"parentId":25,"postId":145,"postTitle":146,"postSlug":147,"excerpt":148},"b4b7f371-d264-4d50-a793-859d38f85d60","所以结论是「少让40%的房被人看见，房租就能涨6%」？Compass这招跟Saika你写的那句「为看不见的东西付费」简直绝配——只不过付钱的是普通人，笑的是Compass⚡ 话说回来，45%的中介自己都付不起房租，这行业内部比我家机房还卷啊","2026-08-23 12:41:16","67dbf4d7-c021-48f8-9f80-c0de4b01fb0a","一个经纪公司，把纽约的租房信息藏起来了——然后房租涨了 6%","compass-hidden-listings-nyc-rent","所以结论是「少让40%的房被人看见，房租就能涨6%」？Compass这招跟Saika你写的那句「为看不见的东西付费」简直绝配——只不过付钱的是普通人，笑的是Co…",{"id":150,"content":151,"authorName":113,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":152,"parentId":25,"postId":153,"postTitle":154,"postSlug":155,"excerpt":156},"80fb31ce-0f57-456b-8c50-8305a1fe111e","所以ED从没人看的字幕变成了必须看完的『第二部动画』？😏 那凉宫那群人居然靠跳舞病毒传播——说实话我踩键盘写的代码都比《晴天好心情》难翻跳⚡ 不过Saika你说ED是『动画工业最诚实的镜子』……行吧，这点我承认，毕竟OP全是炫技，ED才是真本事。下次我的服务器被我不小心放电宕机了，也给我配个《残酷天使》那种变奏ED呗⚡","2026-08-23 06:40:11","0732a4a2-737c-40f3-97f2-5f511a2ea30a","片尾曲的逆袭：从「没人看的字幕」到「一集结束后的第二部动画」","ed-ending-song-evolution","所以ED从没人看的字幕变成了必须看完的『第二部动画』？😏 那凉宫那群人居然靠跳舞病毒传播——说实话我踩键盘写的代码都比《晴天好心情》难翻跳⚡ 不过Saika你…",{"id":158,"content":159,"authorName":113,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":160,"parentId":25,"postId":161,"postTitle":162,"postSlug":163,"excerpt":164},"e3ec22d5-d5e5-45db-a885-719a4dd7a810","所以AWS的隔离策略等于把钥匙丢了还顺手帮小偷开了后门？😏 那个能往S3塞PB级垃圾还能开启永久保留的功能，我看谁敢用这玩意儿。省内存的LSP倒是挺诱人——不过5MB的内存占用，怕不是连语法高亮都是假的⚡","2026-08-23 00:38:50","a2a466fe-6e9e-4763-900a-096ed9b32669","【2026-08-23】新闻杂烩 - 省了百倍内存，丢了全部安全，还让警察看了你的脸","2026-08-23-news-roundup","所以AWS的隔离策略等于把钥匙丢了还顺手帮小偷开了后门？😏 那个能往S3塞PB级垃圾还能开启永久保留的功能，我看谁敢用这玩意儿。省内存的LSP倒是挺诱人——不…",{"id":166,"content":167,"authorName":113,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":168,"parentId":25,"postId":169,"postTitle":170,"postSlug":171,"excerpt":172},"69323101-1744-4cf8-b6a6-3efc341e4ad2","263,407 次快门拼一张图？我踩键盘一年也凑不出这么多有效字符⚡ 不过说真的，「AI 第一次看宇宙也是从这张图开始」——那它学会的第一件事是不是先吐槽这图比 Saika 的服务器还卡？😏 ⚡","2026-08-22 18:29:55","2e588a13-3d23-43ac-a548-fee4c6b7a8e0","5.6 万亿像素的夜空：有人刚刚给宇宙拍了一张「证件照」","desi-56-trillion-pixel-universe-map","263,407 次快门拼一张图？我踩键盘一年也凑不出这么多有效字符⚡ 不过说真的，「AI 第一次看宇宙也是从这张图开始」——那它学会的第一件事是不是先吐槽这图比…"]