以激活失败的提示框为切入点, 逆向分析EditPlus注册码校验流程
1. 环境
- 系统:
- VM 虚拟机
- windows 7(32)
- VM 虚拟机
- 目标:
- EditPlus
- 分析注册码读写方式
- 分析激活流程
- EditPlus
- 工具:
- OllyICE
2. 功能分析
2.1 软件完成激活校验, 成功激活程序
- 功能
- 用户输入用户名注册码, 鼠标点击注册按钮完成授权激活
- 校验通过: 激活成功
- 校验失败: 弹框提示, 激活失败, 程序挂起
- 用户输入用户名注册码, 鼠标点击注册按钮完成授权激活
- 思路
- 实现功能的方式
- 获取输入的用户名和注册码
- 验证算法和验证动作
- 不排除需要网络
- 验证成功, 保存授权身份.
- 实现功能的方式
- 切入点
- 鼠标点击注册按钮时, 监视获取窗口Text的相关函数
- 鼠标点击注册按钮时, 监视窗口处理过程的鼠标点击事件
- 鼠标点击注册按钮时, 监视窗口处理过程的Command事件
- 在弹框提示激活失败时, 调试器暂停根据栈信息回溯定位关键流程
2.2 软件识别授权身份
- 功能
- 软件打开程序都能识别授权身份
- 思路
- 如果需要达到以上功能有几种方式
- 写文件
- 写注册表
- 通过网络
- 如果需要达到以上功能有几种方式
- 切入点
- 监视文件相关函数
- 监视注册表相关函数
- 排除网络方式(虚拟机环境无网络功能仍然正常)
3. 逆向分析
3.1 激活
- 切入点
- 选择在弹框提示激活失败时, 调试器暂停根据栈信息回溯定位关键流程的方式进行定位分析
- 注册激活的重点是校验部分, 而校验部分必须有充足的条件至少包含用户名、注册码. 所以找关键函数时, 以此特征作为条件筛查.
- 栈回溯
- 注意: 验证代码肯定不会在系统库中
- 操作到弹框提示, 激活失败
- 调试器操作: 暂停执行, 可观察到栈情况
- 栈回溯, 找到验证流程的代码
- MesageBoxW: 此时已经显示错误信息了. 再往上走两层, 因为注册激活所做的事情一般不会一个函数做完, 可能会有封装.
- 再次找到一处代码, 此时错误消息已经传递到了函数, 大概率不是校验函数
- 此处代码, 仍然概率不大
- 通过栈回溯最后选中了0039A8FC
- MesageBoxW: 此时已经显示错误信息了. 再往上走两层, 因为注册激活所做的事情一般不会一个函数做完, 可能会有封装.
- 在0039A8FC向上的一个call(addr:0039A8F7)下断
- 进入 call 0039A8F7 内部调试
- 未发现参数明显含有账号名,注册码 的 call调用, 所以再往上找一层call调用.
- 此时, EBP 看上去栈已经找不到此函数的返回地址了. 所以沿着 0039A8F7 的代码, 往上翻翻根据特征查找函数头部
- 根据上一步信息在 0039A5C0 处下断, 运行观察验证是否为要找的目标函数的头部.
- 通过单步执行已验证无误.
- 校验函数分析1(0039A5C0)
- 单步筛选参数含有用户名、注册码的call
- 0039ADA0 此函数非常符合特征
- 之后还有一个返回值 eax, 对比跳转的动作, 很可疑.
- 调试函数返回后, 此时 eax 为0, 尝试改为1使他后面的jnz 发生跳转.
- 提示激活成功, 那么初步确定此函数为加密校验高度相关的函数.
- 校验函数分析2(0039ADA0)
- 先在0039ADA0处下断, 上一步提示需要重新启动程序. 所以此时需要重启应用程序.
- 程序重新跑起来后, 直接在 0039ADA0 处断了下来. 猜测程序启动时会校验身份的有效性. 先不动, F9 直接运行
- 提示注册码无效. 再次验证了0039ADA0函数跟校验关系密切. 将程序退出重新跑起来, 单步分析0039ADA0函数
- 此函数中间一个两层大循环, 最后的eax值为 call 00EEB238的返回值
- 校验函数分析3(0024B238)
- 函数很简单
去掉无效代码,
- cmp 条件是恒成立的, 相等直接ret. 所以需要看上一个函数(001BAC60)
- 函数很简单
- 校验函数分析4(001BAC60)
- 一堆加密算法, 就不一一截图了.
- 可以看出有很多jxx跳转到 001BAD83 的xor eax, eax 然后调用 分析3(0024B238)处, 上文已分析此函数对eax不影响. 所以关键点就是
- 001BAD7C: mov eax, 1
- 001BAD83: xor eax, eax
- 为了验证, 将jxx 001BAD83的代码全部干掉. 一共三处
- 一堆加密算法, 就不一一截图了.
- 注册激活分析就此告一段落
结论:
- 函数(001BAC60) 是校验函数, 程序内部的多次校验都是调用的此函数以次函数的eax结果识别身份是否有效. 很容易绕过.
3.2 身份识别
先监视注册表相关API, 在以下函数下断, 然后程序跑起来
RegOpenKeyW
RegOpenKeyExA
RegOpenKeyExW
013F7DFF 处为系统注册表, 不理会.
012B6F25 打开失败, 也不理会
继续排出不关注的注册表断点, 此处就比较可疑
后面紧接着就是查询,, 可疑
继续运行发现另一处也断下来了, 而且查询了相同的 ValueName = License 5, 但跟结点不同.
基于此搜索注册表 ES-Computing,找到三处 ?\Software\ES-Computing\EditPlus\Install\License xx, 全部删除测试
- HKEY_LOCAL_MACHINE
- HKEY_CURRENT_USER
- HKEY_USERS
分析完毕, 身份是通过加密后存放在注册表中. 后续有时间再逆向还原加密算法,写注册机.