跟着看雪大牛的这篇文章:https://bbs.pediy.com/thread-258428.htm 分析完FSViewer的注册算法后就想靠自己分析一个程序,于是选择了010editor
010editor的注册算法比较简单,作者也没有进行防破解的任何操作,甚至可以直接用IDA静态分析出算法
分析的是最新版的64位便携版(010EditorWin64Portable10.0.2.exe)
注册机、伪造server和patch代码见附件
对于Qt程序,IDA的反编译效果非常好,虽然会有一些细小的反编译错误,但是不影响整体逻辑
一开始是判断Name是否为空,PassWord是否输入完整:
通过动态调试可以发现((QString)var + 4)是字符串长度:
之后会对输入的Name和PassWord进行一些判断和替换:
clearQuot函数是除去输入的Name中的引号,并赋值给arg1+8:
repalceOol函数是将PassWord中的O和o替换为0,l替换为1并赋值给arg1+16:
那么关键在于这个arg1,也就是qword_1406F01F8肯定是个结构体
这是分析后的结构体命名为stKey:
然后就是最关键的验证函数了:
一开始会将PassWord转成10组16进制数,比如 ABCD-1234-...
会转成 0xAB,0xCD,0x12,0x34...:暂且命名为数组str2Hex[]
并会对一些禁止掉的Name和PassWord进行判断
注册算法在之后的switch语句里,通过IDA可以看到返回值有231,78和45
231是验证失败,通过对验证函数之后函数的分析:
v11 == 219则弹出成功MessageBox,v11是sub_140009D77的返回值
sub_140009D77:又调用了v6 = VerifyNamePsw(), v6为45则返回219
所以注册算法一定要返回45,而switch判断str2Hex[3] (psw转为16进制数的数组),
str2Hex[3] 只能= 0x9C || 0xFC || 0xAC
case 0x9C or case 0xAC 都可以return 45, 但是0x9C这条分支没有对到期时间(stKey->dueTime)赋值,所以要分析case 0xAC.
这里贴出我分析的伪C代码:
vNum2必须整除0xB, vNum1必须整除0x11, 并把vNum1和vNum2作为参数传进sub_140006901和name一起计算一个32位数, 然后str2Hex的第4到7位等于这个数(BYTE)的0到3位
那么可以随机选取vNum1和vNum2, 通过sub_140006901计算出str2Hex的4到7位, 然后xor是可逆的,所以就可以生成剩下的5位16进制数。
关于到期时间的计算是通过stKey->dueTime*86400作为localtime函数的参数算出到期时间,stKey->dueTime被赋值为伪代码中的vNum1
因为一开始用插件查了一下程序用到的密码学算法,有CRC32和MD5,所以以为会有线程在进行完整性校验,就没有直接patch程序
通过抓包可以发现,程序会发送一个get请求,返回的内容是 invalid
那么可以修改host, 并伪造一个http_server,关键在于正确返回的数据应该是什么形式
再次分析HttpSrvVerify函数: 通过动态调试可以发现部分函数功能
在postRequestAndRecv函数里,下图部分代码用于接收数据:
setIdAndInvalidFlag函数是用于解析并验证接收到的数据,首先贴出再次分析后的stKey结构体:
验证第一部分::
验证第二部分:
所以说正确的数据格式应该是 <ss>valid</ss><id>1</id>
其中ss中间的内容除了invalid和error都可以, id中间的内容除了0都可以
那么就可以修改host为127.0.0.1 www.sweetscape.com
然后运行http_srv.py即可
我的方法是,在setIdAndInvalidFlag函数中:
直接jmp到invalidFlag赋值之前, mov ebx,0把invalidFlag值赋为0
然后再jmp到id赋值之前, mov eax,1把id值赋值为1
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2020-8-9 00:36
被0xEEEE编辑
,原因: 修改网络验证部分