吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 64|回复: 5
上一主题 下一主题
收起左侧

[原创] 一次 .NET WPF 图片工具激活逻辑的逆向经验分享

[复制链接]
跳转到指定楼层
楼主
梁朝伟在线 发表于 2026-7-9 16:12 回帖奖励
本帖最后由 梁朝伟在线 于 2026-7-9 16:36 编辑

0. 样本与背景(简单带过)

手头是一款 Windows 图片拼接小工具(约 V1.x):多图导入、按行列分批出成片、水印与预览。启动先过激活页,也有试用入口。
下面进入正题:这次是怎么把激活链路摸清楚的。

1. 这次逆向想搞清什么

不是冲着「立刻免费用」,而是把问题拆开:

  1. 门闩卡在启动、主界面,还是导出?  
  2. 本地文件是「已授权凭证」还是「给服务器复核的缓存」?  
  3. 机器码怎么算?密钥是否在客户端?  
  4. 最小的控制流分叉在哪?(启动 URI?试用按钮?成功码分支?)
    带着问题做,比上来就搜 key、改字节更稳。

    2. 环境与切入:先定性,再动手

    样本目录很干净:主 exe + 各架构 WebView2Loader,体积约 2MB 量级。
    第一步做的不是上调试器,而是定性:
    观察 判断
    能读到程序集名、版本、大量托管元数据 .NET,优先托管逆向
    出现 Costura、HandyControl、MvvmLight、WPF 特征 依赖多半嵌进主程序
    字符串里已有 Activation / activate_verify / AES 相关符号 激活逻辑很可能 未深度混淆

    本机没有现成 ILSpy / dnSpy / dotnet 时,用 Mono.Cecil 写个小工具导 IL 也能读完全部关键方法。工具不够不是终点,.NET 静态分析路径很多
    经验 1: 对可疑桌面小工具,先 strings + 程序集信息;确认 .NET 后再谈反编译,别一上来当原生壳硬啃。

    3. 字符串扫描:一次锁定「战场地图」

    从 UTF-16 / ASCII 字符串里很快铺开一张图: 线索类型 例子(已脱敏) 用途
    类型/方法名 ActivationActivateAndVerifyWithServerReadAndSaveLocalActivationInfoMachineCodeStringEncryptor 直接当类清单
    资源 Activation.xaml、启动相关 URI 启动页入口
    网络 https://×××.×××.com/api/activation/activate_verifyactivate_software 服务端协议形态
    本地 %LocalAppData% 下带时间戳目录 + ×××_Activation×××.dat 落盘位置
    硬件 Win32_Processor / Win32_BaseBoard / UUID 机器码素材

    到这一步,还没看 IL,已经能写故事大纲:

    启动 → 激活窗 → 读本地加密文件 → 组 machineCode → POST 校验/激活 → 成功则进主窗

    经验 2: .NET 未混淆时,字符串阶段就能画出 70% 架构;后面反编译是在「填细节和验证假设」,不是从零猜。

    4. 按类拆读:别一把梭整个业务 VM

    主业务 ViewModel 的 IL 可以非常庞大,激活相关其实就那几个小类。这次刻意只深挖:

    • App:启动 URI  
    • Activation:Loaded / 校验 / 点激活 / 试用按钮  
    • ActivateAndVerifyWithServer:HTTP  
    • ReadAndSaveLocalActivationInfo + StringEncryptor:本地读写与加解密  
    • MachineCode:设备指纹  
    • GlobalConfig:常量静态构造
      经验 3: 先按「授权模块」收敛范围;业务巨类最后再碰,否则容易淹没在拼接/水印代码里。

      5. 还原出来的激活模型(本次结论)

      5.1 配置常量(GlobalConfig 静态构造)

      脱敏后形态:

    • 服务根:https://×××.×××.com  
    • 软件名 / 版本通道:用于拼进 URL 路径  
    • 本地目录名、激活文件名  
    • 更新 XML 地址(与激活并行存在,可忽略)

      5.2 本地文件

    • 路径:%LocalAppData%\×××_…\ + 固定 dat 名  
    • 内容:JSON 序列化的 { email, activationCode, … }  
    • 再经 AES-CBC,输出 Base64 写盘  
    • Key / IV 以字符串形式硬编码在客户端(具体值此处不公开)
      保存时甚至主要写邮箱和激活码;机器码更多是 运行时现算再塞进请求体

      5.3 机器码

      逻辑近似:

      partA = CpuId 优先,否则 Mac
      partB = 主板序列号 优先,否则 UUID
      machineCode = MD5( partA + partB + email ).ToHexUpper()

      邮箱会进哈希,所以「同一台机器、不同邮箱」机器码不同——和绑定策略一致。

      5.4 联网

      两条路径,同一套 POST JSON: request 语义 路径形态(脱敏) 场景
      启动复验 …/activate_verify/{edition} 本地已有档案时
      用户点激活 …/activate_software/{edition} 输入邮箱+激活码

      响应大致是 { code, message },客户端用业务码 switch:成功则 new MainWindow()Close 激活窗;客户端侧异常码(网络、JSON、超时等)也在同一套枚举里。

      5.5 试用

      存在单独按钮逻辑:置位试用标志 → 直接 Show 主窗
      试用在导出链路里可能再盖内置水印资源。说明产品把「能用」和「已授权」拆成了两条 UI 路径。

      5.6 信任根在哪?

      本地 dat  = 方便下次自动登录的缓存(可加密,但密钥在客户端)
      服务端    = 真正放行(activate_verify / activate_software)
      主窗      = 静态看未再强校验

      所以:只伪造本地文件不够——启动仍会带 machineCode 去复验。
      这是这次最重要的判断,避免后续在「改 dat / 怼 AES」上空耗时间。
      经验 4: 先回答「离线假文件能否过」,再决定是 mock 服务、改启动路径,还是研究算法。方向错了,细节再漂亮也白费。

      6. 启动流在 IL 里怎么读(经验细节)

      Activation 里异步状态机比较烦(d__3 / d__4),但模式固定:

  5. 显示 Loading / 遮罩  
  6. GetReadLocalActivationInfo()  
  7. 有数据则 set_machineCode + ActivateVerifyAsync(..., "activate_verify")  
  8. codeswitch(一截成功码、一截客户端错误码)  
  9. 成功分支:MessageBox(可选)→ MainWindow.Show()Close()  
  10. 无本地:提示输入激活码一类文案,停在激活页
    App.InitializeComponent 里则是一行很「诚实」的:
    StartupUri = "Activation.xaml"   // 资源名明文

    经验 5: WPF 激活样本优先看三处——StartupUri、激活窗 Loaded、试用/确定按钮。异步状态机吓人,但跳转目标往往就这几个。
    经验 6: Cecil 导 IL 时记得把 switch目标偏移表 打出来,否则只看到 switch Instruction[],成功码对应哪条分支会对不上。

    7. 控制流分叉:分析能走到哪一步

    从「理解程序」角度,门闩从早到晚大致是: 分叉点 含义 学习价值
    StartupUri 明文 是否先加载激活页 启动门闩是否脆弱
    试用按钮 是否允许无码进入 正式/试用状态机是否统一
    服务端成功码 是否信任远端 真授权点
    主窗 / 导出 是否二次校验 门闩是否只做在门口

    本次静态结论偏软的点:

    • 启动资源名明文、等长相近时可被讨论「字符串级修改」的理论空间  
    • 对称密钥硬编码  
    • 试用直达主窗  
    • 主业务侧未见二次强校验
      必须强调: 以上是 架构弱点分析,用于写防护建议和自己对照检查;不是教大家去改商业软件、也 不附带 任何补丁或成品。

      8. 若重来一遍,我会怎么排期

  11. 字符串 10 分钟画架构图  
  12. 只导激活相关类型 IL(半小时内)  
  13. 画启动时序:本地 → 机器码 → HTTP → 状态码  
  14. 明确信任根在服务端还是本地  
  15. 再决定:防护建议怎么写 / 自己产品怎么改
    工具链备选:ILSpy/dnSpy 优先;没有就 Mono.Cecil 自写导出;动态调试(dnSpy 下断、看 POST body)适合验证,不是第一步。

001.JPG (112.84 KB, 下载次数: 0)

001.JPG

PictureStitching_Standard.zip

1.8 MB, 下载次数: 0, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
1208nn + 1 + 1 用心讨论,共获提升!
junjia215 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
ergou11234 发表于 2026-7-9 16:23
虽不明但觉厉
3#
yingfengwuzhe 发表于 2026-7-9 16:29
4#
theoLoong 发表于 2026-7-9 16:30
5#
15531029916 发表于 2026-7-9 16:35
感谢博主分享
6#
whyzl20 发表于 2026-7-9 16:35
学习了。感谢楼主。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-7-10 15:05

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表