某影音软件的注册解码分析
本帖最后由 GGLHY 于 2010-10-15 17:31 编辑某影音软件的注册解码分析
直奔主题吧,来到这:
00CC0563 55 push ebp
00CC0564 68 B80ACC00 push 00CC0AB8
00CC0569 64:FF30 push dword ptr fs:
00CC056C 64:8920 mov dword ptr fs:, esp
00CC056F 8D55 F8 lea edx, dword ptr
00CC0572 8BB3 98030000 mov esi, dword ptr
00CC0578 8BC6 mov eax, esi
00CC057A E8 05DDF9FF call 00C5E284
00CC057F 8B45 F8 mov eax, dword ptr ; S1
00CC0582 8D55 FC lea edx, dword ptr
00CC0585 E8 5A90F5FF call 00C195E4 ; 此CALL是对注册码空格的检验及去除,下同
///////////////////////////////////////////////////////////////////////////////////////
00C195E4 53 push ebx
...省略部分代码...
00C195EE 85C0 test eax, eax ; 当前段的注册码
00C195F0 74 05 je short 00C195F7
00C195F2 83E8 04 sub eax, 4
00C195F5 8B00 mov eax, dword ptr
00C195F7 8BF0 mov esi, eax ; 当前段注册码长度
00C195F9 BB 01000000 mov ebx, 1
00C195FE EB 01 jmp short 00C19601
00C19600 43 inc ebx
00C19601 3BF3 cmp esi, ebx
00C19603 7C 07 jl short 00C1960C
00C19605 807C1F FF 20 cmp byte ptr , 20 ; 比较当前段注册码中有无空格
00C1960A^ 76 F4 jbe short 00C19600
00C1960C 3BF3 cmp esi, ebx
00C1960E 7D 0A jge short 00C1961A
00C19610 8BC5 mov eax, ebp
00C19612 E8 F9B9FFFF call 00C15010
00C19617 EB 17 jmp short 00C19630
00C19619 4E dec esi
00C1961A 807C37 FF 20 cmp byte ptr , 20 ; 倒取当前段注册码检测是否是空格
00C1961F^ 76 F8 jbe short 00C19619
...省略部分代码...
00C19634 C3 retn ;得到当前段注册码中的非空格字符长度
////////////////////////////////////////////////////////////////////////////////////////
00CC058A 8B55 FC mov edx, dword ptr
00CC058D 8BC6 mov eax, esi
...省略部分代码...
00CC0631 E8 4EDCF9FF call 00C5E284
00CC0636 8B45 D4 mov eax, dword ptr ; S1
00CC0639 E8 964EF5FF call 00C154D4
00CC063E E8 3D98F5FF call 00C19E80
00CC0643 83F8 05 cmp eax, 5 ; S1(去掉空格后)长度与5比较!不等就挂!下同。
00CC0646 0F85 80000000 jnz 00CC06CC
00CC064C 8D55 D0 lea edx, dword ptr
00CC064F 8B83 9C030000 mov eax, dword ptr
00CC0655 E8 2ADCF9FF call 00C5E284
00CC065A 8B45 D0 mov eax, dword ptr ; S2
00CC065D E8 724EF5FF call 00C154D4
00CC0662 E8 1998F5FF call 00C19E80
00CC0667 83F8 05 cmp eax, 5
00CC066A 75 60 jnz short 00CC06CC
00CC066C 8D55 CC lea edx, dword ptr
00CC066F 8B83 A0030000 mov eax, dword ptr
00CC0675 E8 0ADCF9FF call 00C5E284
00CC067A 8B45 CC mov eax, dword ptr ; S3
00CC067D E8 524EF5FF call 00C154D4
00CC0682 E8 F997F5FF call 00C19E80
00CC0687 83F8 05 cmp eax, 5
00CC068A 75 40 jnz short 00CC06CC
00CC068C 8D55 C8 lea edx, dword ptr
00CC068F 8B83 A4030000 mov eax, dword ptr
00CC0695 E8 EADBF9FF call 00C5E284
00CC069A 8B45 C8 mov eax, dword ptr ; S4
00CC069D E8 324EF5FF call 00C154D4
00CC06A2 E8 D997F5FF call 00C19E80
00CC06A7 83F8 05 cmp eax, 5
00CC06AA 75 20 jnz short 00CC06CC
00CC06AC 8D55 C4 lea edx, dword ptr
00CC06AF 8B83 A8030000 mov eax, dword ptr
00CC06B5 E8 CADBF9FF call 00C5E284
00CC06BA 8B45 C4 mov eax, dword ptr ; S5
00CC06BD E8 124EF5FF call 00C154D4
00CC06C2 E8 B997F5FF call 00C19E80
00CC06C7 83F8 05 cmp eax, 5
00CC06CA 74 2A je short 00CC06F6
00CC06CC 6A 40 push 40
00CC06CE A1 1C07CD00 mov eax, dword ptr
00CC06D3 E8 FC4DF5FF call 00C154D4
00CC06D8 50 push eax
00CC06D9 A1 2407CD00 mov eax, dword ptr
00CC06DE E8 F14DF5FF call 00C154D4
00CC06E3 50 push eax
00CC06E4 8BC3 mov eax, ebx
00CC06E6 E8 D156FAFF call 00C65DBC
00CC06EB 50 push eax
00CC06EC E8 B37AF5FF call <jmp.&user32.MessageBoxA>;出错!“注册失败!”
00CC06F1 E9 37030000 jmp 00CC0A2D
00CC06F6 8D55 C0 lea edx, dword ptr
00CC06F9 8B83 98030000 mov eax, dword ptr
00CC06FF E8 80DBF9FF call 00C5E284
00CC0704 837D C0 00 cmp dword ptr , 0 ; S1,
00CC0708 74 3C je short 00CC0746
00CC070A 8D55 BC lea edx, dword ptr
00CC070D 8B83 9C030000 mov eax, dword ptr
00CC0713 E8 6CDBF9FF call 00C5E284
00CC0718 837D BC 00 cmp dword ptr , 0 ; S2,
00CC071C 74 28 je short 00CC0746
00CC071E 8D55 B8 lea edx, dword ptr
00CC0721 8B83 A0030000 mov eax, dword ptr
00CC0727 E8 58DBF9FF call 00C5E284
00CC072C 837D B8 00 cmp dword ptr , 0 ; S3
00CC0730 74 14 je short 00CC0746
00CC0732 8D55 B4 lea edx, dword ptr
00CC0735 8B83 A4030000 mov eax, dword ptr
00CC073B E8 44DBF9FF call 00C5E284
00CC0740 837D B4 00 cmp dword ptr , 0 ; S4
00CC0744 75 2A jnz short 00CC0770
00CC0746 6A 40 push 40
00CC0748 A1 1C07CD00 mov eax, dword ptr
00CC074D E8 824DF5FF call 00C154D4
00CC0752 50 push eax
00CC0753 A1 2407CD00 mov eax, dword ptr
00CC0758 E8 774DF5FF call 00C154D4
00CC075D 50 push eax
00CC075E 8BC3 mov eax, ebx
00CC0760 E8 5756FAFF call 00C65DBC
00CC0765 50 push eax
00CC0766 E8 397AF5FF call <jmp.&user32.MessageBoxA>
00CC076B E9 BD020000 jmp 00CC0A2D
00CC0770 8D55 B0 lea edx, dword ptr
00CC0773 8B83 A0030000 mov eax, dword ptr
00CC0779 E8 06DBF9FF call 00C5E284
00CC077E 8B45 B0 mov eax, dword ptr ; S3
00CC0781 E8 3691F5FF call 00C198BC ;注册码格式检测2
///////////////////////////////////////////////////////////////////////////////////////
00C198BC 53 push ebx
...省略部分代码...
00C198C5 8BC3 mov eax, ebx
00C198C7 E8 B0A1FFFF call 00C13A7C ; F7,注册码格式检测2
///////////////////////////////////////////////////////////////////////////
00C13A7C 53 push ebx
...省略部分代码...
00C13A88 31DB xor ebx, ebx
00C13A8A BF CCCCCC0C mov edi, 0CCCCCCC ; 214748364
00C13A8F 8A1E mov bl, byte ptr ; 当前段的注册码
00C13A91 46 inc esi
00C13A92 80FB 20 cmp bl, 20 ; 检查当前段注册码是都为空格
00C13A95^ 74 F8 je short 00C13A8F
00C13A97 B5 00 mov ch, 0
00C13A99 80FB 2D cmp bl, 2D ; 检查当前段注册码是否为“-”
00C13A9C 74 62 je short 00C13B00
00C13A9E 80FB 2B cmp bl, 2B ; 检查当前段注册码是否为“+”
00C13AA1 74 5F je short 00C13B02
00C13AA3 80FB 24 cmp bl, 24 ; 检查当前段注册码是否为$
00C13AA6 74 5F je short 00C13B07
00C13AA8 80FB 78 cmp bl, 78 ; 检查当前段注册码是否为x
00C13AAB 74 5A je short 00C13B07
00C13AAD 80FB 58 cmp bl, 58 ; 检查当前段注册码是否为X
00C13AB0 74 55 je short 00C13B07
00C13AB2 80FB 30 cmp bl, 30 ; 检查当前段注册码是否为0
00C13AB5 75 13 jnz short 00C13ACA
00C13AB7 8A1E mov bl, byte ptr
00C13AB9 46 inc esi
00C13ABA 80FB 78 cmp bl, 78 ;与x比较
00C13ABD 74 48 je short 00C13B07
00C13ABF 80FB 58 cmp bl, 58 ;与X比较
00C13AC2 74 43 je short 00C13B07
00C13AC4 84DB test bl, bl
00C13AC6 74 20 je short 00C13AE8
00C13AC8 EB 04 jmp short 00C13ACE
00C13ACA 84DB test bl, bl
00C13ACC 74 2D je short 00C13AFB
00C13ACE 80EB 30 sub bl, 30 ; ASC-30
00C13AD1 80FB 09 cmp bl, 9 ; 检查当前段注册码的每一位是否不大于9
00C13AD4 77 25 ja short 00C13AFB ; 大就跳,跳就就挂了。因此注册码应该是0-9的数字
00C13AD6 39F8 cmp eax, edi
00C13AD8 77 21 ja short 00C13AFB
00C13ADA 8D0480 lea eax, dword ptr
...省略部分代码...
00C13B05^ EB 9C jmp short 00C13AA3
00C13B07 BF FFFFFF0F mov edi, 0FFFFFFF
00C13B0C 8A1E mov bl, byte ptr ; 当前段注册码的下一位
00C13B0E 46 inc esi
00C13B0F 84DB test bl, bl
00C13B11^ 74 DF je short 00C13AF2
00C13B13 80FB 61 cmp bl, 61 ; 下1位与“a”比较
00C13B16 72 03 jb short 00C13B1B
00C13B18 80EB 20 sub bl, 20 ; ASC-20
00C13B1B 80EB 30 sub bl, 30 ; (ASC-20)-30
00C13B1E 80FB 09 cmp bl, 9 ; 相减后于9比较
00C13B21 76 0B jbe short 00C13B2E ; 不高于则跳
00C13B23 80EB 11 sub bl, 11 ; 再-11
00C13B26 80FB 05 cmp bl, 5 ; (再-11)后与5比较
00C13B29^ 77 D0 ja short 00C13AFB ; 大于则跳
00C13B2B 80C3 0A add bl, 0A
00C13B2E 39F8 cmp eax, edi
00C13B30^ 77 C9 ja short 00C13AFB
...省略部分代码...
00C13B4C C3 retn
/////////////////////////////////////////////////////////////////////////
00C198CC 8BF0 mov esi, eax ; 分取的各段注册码
00C198CE 833C24 00 cmp dword ptr , 0
00C198D2 74 19 je short 00C198ED
...省略部分代码...
00C198F4 C3 retn
//////////////////////////////////////////////////////////////////////////////////////
00CC0786 8BF0 mov esi, eax
00CC0788 8D45 AC lea eax, dword ptr
00CC078B E8 7C84FCFF call 00C88C0C ;
00CC0790 8B45 AC mov eax, dword ptr
00CC0793 E8 2491F5FF call 00C198BC
00CC0798 8BC8 mov ecx, eax ; EAX=80000的16进制
00CC079A 8BC6 mov eax, esi ; S3
00CC079C BF 10270000 mov edi, 2710 ; 10000
00CC07A1 33D2 xor edx, edx
00CC07A3 F7F7 div edi ; S3/10000
00CC07A5 8BF8 mov edi, eax ; 商;
00CC07A7 8BC1 mov eax, ecx ; 80000
00CC07A9 B9 10270000 mov ecx, 2710
00CC07AE 33D2 xor edx, edx
00CC07B0 F7F1 div ecx ; /10000
00CC07B2 3BF8 cmp edi, eax ; 呵呵,S3开头应该是8
00CC07B4 74 2F je short 00CC07E5 ; 不等就挂了!
00CC07B6 83FF 01 cmp edi, 1
00CC07B9 74 2A je short 00CC07E5
00CC07BB 6A 40 push 40
00CC07BD A1 1C07CD00 mov eax, dword ptr
00CC07C2 E8 0D4DF5FF call 00C154D4
00CC07C7 50 push eax
00CC07C8 A1 2407CD00 mov eax, dword ptr
00CC07CD E8 024DF5FF call 00C154D4
00CC07D2 50 push eax
00CC07D3 8BC3 mov eax, ebx
00CC07D5 E8 E255FAFF call 00C65DBC
00CC07DA 50 push eax
00CC07DB E8 C479F5FF call <jmp.&user32.MessageBoxA>
00CC07E0 E9 48020000 jmp 00CC0A2D
00CC07E5 8D55 A8 lea edx, dword ptr
00CC07E8 8B83 98030000 mov eax, dword ptr
00CC07EE E8 91DAF9FF call 00C5E284
00CC07F3 8B45 A8 mov eax, dword ptr
00CC07F6 E8 C190F5FF call 00C198BC
00CC07FB E8 6C8AFCFF call 00C8926C ;F7(核心算法1)
/////////////////////////////////////////////////////////////////////////////////
00CC07FB的call 00C8926C F7后:
00C8926C 8BC8 mov ecx, eax ; s1的16进制
00C8926E 8D81 D3750100 lea eax, dword ptr ; s1的16进制+175d3
00C89274 B9 0D000000 mov ecx, 0D
00C89279 33D2 xor edx, edx
00C8927B F7F1 div ecx ; s1的16进制+175d3/0d
00C8927D 05 80000000 add eax, 80 ; 商+80H
00C89282 C3 retn
//////////////////////////////////////////////////////////////////////////////////
00CC0800 8BF0 mov esi, eax ; S1的运算结果,设为K1
00CC0802 8D55 A4 lea edx, dword ptr
00CC0805 8B83 9C030000 mov eax, dword ptr
00CC080B E8 74DAF9FF call 00C5E284
00CC0810 8B45 A4 mov eax, dword ptr ; S2
00CC0813 E8 A490F5FF call 00C198BC
00CC0818 E8 678AFCFF call 00C89284 ;F7(核心算法2)
/////////////////////////////////////////////////////////////////////////////////
00CC0818 的call 00C89284 F7后:
00C89284 8BC8 mov ecx, eax ; S2的16进制
00C89286 8BC1 mov eax, ecx
00C89288 B9 13000000 mov ecx, 13 ; ECX=13
00C8928D 33D2 xor edx, edx
00C8928F F7F1 div ecx ; S2/13(19)
00C89291 8BD0 mov edx, eax ; 商
00C89293 C1E0 04 shl eax, 4 ; 商*16
00C89296 03C2 add eax, edx ; 商*16的结果+商,设为QQ
00C89298 50 push eax
00C89299 B8 92740100 mov eax, 17492 ; 17492=95378
00C8929E 5A pop edx ; QQ
00C8929F 2BC2 sub eax, edx ; 17492(95378)-QQ
00C892A1 C3 retn
/////////////////////////////////////////////////////////////////////////////////
00CC081D 8BF8 mov edi, eax ; S2的运算结果。K2
00CC081F 8D55 A0 lea edx, dword ptr
00CC0822 8B83 A4030000 mov eax, dword ptr
00CC0828 E8 57DAF9FF call 00C5E284
00CC082D 8B45 A0 mov eax, dword ptr ; s4
00CC0830 E8 8790F5FF call 00C198BC
00CC0835 99 cdq
00CC0836 52 push edx
00CC0837 50 push eax
00CC0838 8BC6 mov eax, esi ; k1
00CC083A 33D2 xor edx, edx
00CC083C 3B5424 04 cmp edx, dword ptr
00CC0840 75 03 jnz short 00CC0845
00CC0842 3B0424 cmp eax, dword ptr ; K1是否等于S4,不等就挂!
00CC0845 5A pop edx ; S4
00CC0846 58 pop eax ; K1
00CC0847 0F85 BB010000 jnz 00CC0A08 ; 要注册成功,则S4应该等于S1运算的结果K1
00CC084D 8D55 9C lea edx, dword ptr
00CC0850 8B83 A8030000 mov eax, dword ptr
00CC0856 E8 29DAF9FF call 00C5E284
00CC085B 8B45 9C mov eax, dword ptr
00CC085E E8 5990F5FF call 00C198BC
00CC0863 99 cdq ; S5
00CC0864 52 push edx
00CC0865 50 push eax
00CC0866 8BC7 mov eax, edi ; K2
00CC0868 33D2 xor edx, edx
00CC086A 3B5424 04 cmp edx, dword ptr
00CC086E 75 03 jnz short 00CC0873
00CC0870 3B0424 cmp eax, dword ptr
00CC0873 5A pop edx ; S5
00CC0874 58 pop eax ; k2
00CC0875 0F85 8D010000 jnz 00CC0A08 ; S5=K2?不等就挂!
...省略部分代码...
***************************************************************************************************
算法总结:
1.5个部分的注册码均为5位数字。分设为S1、S2、S3、S4、S5。即注册码长度要25位。(不得包含空格、$、-、+、X、x等字符,否则注册时会产生异常而不是注册失败)
2.第1和第4部分注册码相关联,即:
第1部分注册码+常数55632的和除以13,得到的商+128,其和即为第4部分注册码。
(S1+55632)/13的商 + 128= S4
因为每部分注册码要为5位,则第4部分最少应该为10000。所以,S1不得小于32637。
同理,
第2和第5相关联;
常数95378-【第2部分注册码除以19,得到的商*17的积(QQ)】=第5部分注册码
因为每部分注册码要为5位,则第5部分最少应该为10000,所以S2不得大于95422.
3.第3部分注册码以8开头,其余4位不限;
***************************************************************************************************
注册信息以非明码的形式保存在文件夹内的setup.dll里。删除第二部分等号后的内容则变回试用版。
初涉算法,如有错误,还望大牛指正!
写破文比破它还累~~~,呵呵!排版排得好好的,结果复制上来,有些格式对不齐了,大家凑合着看吧,/:018
前排学习,谢谢分享 好强大,膜拜keygen/:013 是不是超级转换秀啊? 本帖最后由 GGLHY 于 2010-10-15 19:34 编辑
前排学习,谢谢分享
月之精灵 发表于 2010-10-15 18:34 https://www.chinapyg.com/images/common/back.gif
多谢月大捧场!
回复2# echo: 算法我也只是初涉,这里借毛爷爷说的一句话共勉:一切反动派都是纸老虎。算法嘛,呵呵我们要从战略上藐视它,战术上重视它。只要敢去、肯去碰它,我们终会有所收获的!
回复3# foxjinlin 不是转换秀,/:018 学习一下,好像只是常数有变了?记得之前这个算法只与软件版本号有关,全系列
好像是第三段是软件号 80000=影音80001=视 等待 写的非常详细~学习一下 是篇好文章 支持!! 不错,呵呵。得好好学习下 清晰、条理
学习了。。
页:
[1]
2