WinCHM Pro v4.45 算法分析
本帖最后由 goushibee 于 2014-8-5 18:01 编辑搜索字符串很快定位到下面位置,。。
00553FA3|.8B4D F0 mov ecx,dword ptr ss:
00553FA6|.BA AC405500 mov edx,winchm.005540AC ;RegCode
00553FAB|.8BC3 mov eax,ebx
00553FAD|.E8 3AE5EFFF call winchm.004524EC
00553FB2|.8BC3 mov eax,ebx
00553FB4|.E8 270FEBFF call winchm.00404EE0
00553FB9|.E8 D2F8FFFF call winchm.00553890 ;关键函数
00553FBE|.A1 E0F55C00 mov eax,dword ptr ds:
00553FC3|.8338 00 cmp dword ptr ds:,0x0
00553FC6|.74 57 je Xwinchm.0055401F
00553FC8|.8B0D E0F55C00 mov ecx,dword ptr ds: ;winchm.005D5484
00553FCE|.8B09 mov ecx,dword ptr ds:
00553FD0|.8D45 FC lea eax,dword ptr ss:
00553FD3|.BA C8405500 mov edx,winchm.005540C8 ;Thank you for purchasing our product!\r\n\r\nLicense type:
00553FD8|.E8 0B32EBFF call winchm.004071E8
00553FDD|.A1 FCF95C00 mov eax,dword ptr ds:[0x5CF9FC] ;很明显这个全局变量要等于1才是 pro版本
00553FE2|.8338 01 cmp dword ptr ds:,0x1
00553FE5|.75 1C jnz Xwinchm.00554003 ;!!
00553FE7|.FF75 FC push dword ptr ss:
00553FEA|.68 44415500 push winchm.00554144 ;\r\n
00553FEF|.68 58415500 push winchm.00554158 ;Version: WinCHM Pro
00553FF4|.8D45 FC lea eax,dword ptr ss:
00553FF7|.BA 03000000 mov edx,0x3
00553FFC|.E8 CB32EBFF call winchm.004072CC
00554001|.EB 29 jmp Xwinchm.0055402C
00554003|>FF75 FC push dword ptr ss:
00554006|.68 44415500 push winchm.00554144 ;\r\n
0055400B|.68 8C415500 push winchm.0055418C ;Version: WinCHM (Standard)
关键函数call winchm.00553890 中:
0055399E .8B00 mov eax,dword ptr ds:
005539A0 .E8 77F6FFFF call winchm.0055301C ;返回值要等于270e +1pro版本
005539A5 .8BD8 mov ebx,eax
005539A7 .8BC3 mov eax,ebx
005539A9 .83E8 01 sub eax,0x1 ;
005539AC .72 0B jb Xwinchm.005539B9
005539AE .74 17 je Xwinchm.005539C7
005539B0 .2D 0E270000 sub eax,0x270E ;这里可以看到eax要等于0x270E 之前eax已经-1了
005539B5 .74 21 je Xwinchm.005539D8 ; // 跳到Unlimited-user
005539B7 .EB 30 jmp Xwinchm.005539E9
005539B9 >A1 E0F55C00 mov eax,dword ptr ds: ;
005539BE .33D2 xor edx,edx
005539C0 .E8 6733EBFF call winchm.00406D2C
005539C5 .EB 3E jmp Xwinchm.00553A05
005539C7 >A1 E0F55C00 mov eax,dword ptr ds: ;
005539CC .BA 9C3A5500 mov edx,winchm.00553A9C ;Single-user License
005539D1 .E8 5633EBFF call winchm.00406D2C
005539D6 .EB 2D jmp Xwinchm.00553A05
005539D8 >A1 E0F55C00 mov eax,dword ptr ds: ;
005539DD .BA D03A5500 mov edx,winchm.00553AD0 ;Unlimited-user License
005539E2 .E8 4533EBFF call winchm.00406D2C
005539E7 .EB 1C jmp Xwinchm.00553A05
关键计算位置call winchm.0055301C
刚进入函数
00553090|.C700 FFFFFFFF mov dword ptr ds:,-0x1
00553096|.8B45 F4 mov eax,dword ptr ss:
00553099|.E8 FEF6FFFF call winchm.0055279C ;serial*n 求和 结果要等于2BD2
0055309E|.8945 D8 mov dword ptr ss:,eax
005530A1|.8955 DC mov dword ptr ss:,edx
……
00553159 817D D8 D22B0>cmp dword ptr ss:,0x2BD2 ;所以值要等于0x2BD2
00553160|.75 0A jnz Xwinchm.0055316C
00553162|.BB 0F270000 mov ebx,0x270F ;上一层call已经知道要返回0x270F
00553167|.E9 EE040000 jmp winchm.0055365A ;!!
0055316C|>A1 FCF95C00 mov eax,dword ptr ds:
00553171|.C700 FFFFFFFF mov dword ptr ds:,-0x1 ;可以看到直接给这个全局赋值了-1
所以这里得到的码也不是Pro版本。。。。继续向下看
00553177|.83FB 14 cmp ebx,0x14 ;Switch (cases 14..22)
0055317A|.0F85 09010000 jnz winchm.00553289 ;注册码长度0x14的话
00553180|.A1 FCF95C00 mov eax,dword ptr ds: ;Case 14 of switch 00553177
00553185|.33D2 xor edx,edx
00553187|.8910 mov dword ptr ds:,edx
00553189|.8B45 F4 mov eax,dword ptr ss:
0055318C|.E8 9FFDFFFF call winchm.00552F30 ;结果要 7ED2A128
00553191|.8945 D8 mov dword ptr ss:,eax
……
00553264|.817D D8 28A1D>cmp dword ptr ss:,0x7ED2A128
0055326B|.75 0A jnz Xwinchm.00553277
0055326D|.BB 0F270000 mov ebx,0x270F ;!!
00553272|.E9 E3030000 jmp winchm.0055365A
00553277|>33DB xor ebx,ebx
00553279|.A1 FCF95C00 mov eax,dword ptr ds:
0055327E|.C700 FFFFFFFF mov dword ptr ds:,-0x1 ; 可以看到全局变量还是给了-1
00553284|.E9 D1030000 jmp winchm.0055365A
这里也不是Pro版本 。。。 继续
密码长度为0x19情况下
005532B9|.E8 7EB5EBFF call winchm.0040E83C ;0x16位开始取4位
005532BE|.8B45 EC mov eax,dword ptr ss:
005532C1|.E8 6AFCFFFF call winchm.00552F30 ;可以看到结果要等于 2797
005532C6|.83FA 00 cmp edx,0x0
005532C9|.75 14 jnz Xwinchm.005532DF
005532CB|.3D 97270000 cmp eax,0x2797 ; // !!
005532D0|.75 0D jnz Xwinchm.005532DF
005532D2|.A1 FCF95C00 mov eax,dword ptr ds:[0x5CF9FC]
005532D7|.C700 01000000 mov dword ptr ds:,0x1 ;赋值1
005532DD|.EB 09 jmp Xwinchm.005532E8
005532DF|>A1 FCF95C00 mov eax,dword ptr ds:
005532E4|.33D2 xor edx,edx ;赋值0
005532E6|.8910 mov dword ptr ds:,edx
……
00553292|.8D45 F0 lea eax,dword ptr ss: ;Case 19 of switch 00553177
00553295|.50 push eax
00553296|.B9 14000000 mov ecx,0x14
0055329B|.BA 01000000 mov edx,0x1
005532A0|.8B45 F4 mov eax,dword ptr ss:
005532A3|.E8 94B5EBFF call winchm.0040E83C ;0x1开始取14位
。。。。
005532E8|> \8B45 F0 mov eax,dword ptr ss:
005532EB|.E8 40FCFFFF call winchm.00552F30 ; 高32位267低32位7ED2A128
005532F0|.8945 D8 mov dword ptr ss:,eax
……
005533BA|> \817D DC 67020>cmp dword ptr ss:,0x267
005533C1|.75 13 jnz Xwinchm.005533D6
005533C3|.817D D8 28A1D>cmp dword ptr ss:,0x7ED2A128
005533CA|.75 0A jnz Xwinchm.005533D6
005533CC|.BB 0F270000 mov ebx,0x270F ;!!
调用都是同一个函数。。call winchm.00552F30 。。
00552F9E|> /68 00400000 /push 0x4000
00552FA3|. |68 3D0AD7D3 |push 0xD3D70A3D
00552FA8|. |68 0AD7A370 |push 0x70A3D70A ;=3.3099999999999999990
00552FAD|. |895D DC |mov dword ptr ss:,ebx
00552FB0|. |DB45 DC |fild dword ptr ss: ;将整数转化为长双精FP80压栈
00552FB3|. |83C4 F4 |add esp,-0xC
00552FB6|. |DB3C24 |fstp tbyte ptr ss: ;fstp是将弹栈指令,将st0弹出
00552FB9|. |9B |wait
00552FBA|. |E8 1DB2EBFF |call winchm.0040E1DC ;f(n) =3.3099999999999999990 ^n
00552FBF|. |8B45 F8 |mov eax,dword ptr ss:
00552FC2|. |0FB74458 FE |movzx eax,word ptr ds:
00552FC7|. |0FB7C0 |movzx eax,ax
00552FCA|. |8945 DC |mov dword ptr ss:,eax
00552FCD|. |DB45 DC |fild dword ptr ss:
00552FD0|. |DEC9 |fmulp st(1),st ;f(n)* 每个码的ascii值
00552FD2|. |DB6D E0 |fld tbyte ptr ss:
00552FD5|. |DEC1 |faddp st(1),st ; 求和
00552FD7|. |DB7D E0 |fstp tbyte ptr ss:
00552FDA|. |9B |wait
00552FDB|. |43 |inc ebx
00552FDC|. |4E |dec esi
00552FDD|.^\75 BF \jnz Xwinchm.00552F9E
00552FDF|>DB6D E0 fld tbyte ptr ss:
00552FE2 E8 ED16EBFF call winchm.004046D4 ;取整数部分
00552FE7 8945 F0 mov dword ptr ss:,eax ;低32位
00552FEA|.8955 F4 mov dword ptr ss:,edx ;高32位
第一次看浮点运算。。还好比较简单
call winchm.0040E1DC中
0040E212 DB6D 14 fld tbyte ptr ss: ;=3.3099999999999999990
0040E215|.EB 02 jmp Xwinchm.0040E219
0040E217|>D8C8 /fmul st,st
0040E219|>D1E8 shr eax,1 ;eax 是传进来的n
0040E21B|.^ 73 FA |jnb Xwinchm.0040E217 ;这里就是进行3.3099999999999999990 n次方
0040E21D|.DCC9 |fmul st(1),st
0040E21F|.^ 75 F6 \jnz Xwinchm.0040E217
后面还有注册码为0x1D、0x22、0x18的情况。。用到的函数都一样的 不分析了。。。
总结下:
密码长度为25位时候要求:
1.注册码的最后4位的计算结果要等于0x 2797
2.注册码前20位的计算结果要等于0x2677ED2A128
用户名不参与验证,随便填
最后提供一组可用的注册码:TKYZ0001021012603ZOHXIGB8
感谢分享,学习一下。 评不了分,只能顶一下,抱歉 这也算算法分析?
{:tongue:}吓唬我。 本帖最后由 goushibee 于 2014-8-5 16:42 编辑
DaShanRen 发表于 2014-8-5 16:21
这也算算法分析?
吓唬我。
献丑了
感谢分享,我也来学习一下。 学习一下{:2_148:} 只有膜拜! 感谢分享了,不错,学习了 感谢楼主的分享,学习了!
页:
[1]
2