DeTitle V1.33简单算法分析
软件名称:DeTitle V1.33
软件介绍:在很多影片的开头与结尾处都会播放标题或说明性字幕,不过一般的录放影设备是无法产生这些字幕的,必须要和其它的字幕来源合成才可以。DeTitle
是一套专业的标题字幕产生程序,可以使用各种方式与效果制作标题字幕,使影片更完美。
破解人:BurSH (于2003.8.6)
所属组织:FCG-BCG-OCN-DFCG
破解工具:Trw2000 1.23
///////////////////////
/ 寻找正确的注册码……/
///////////////////////
软件是分别用八个文本框来让我们输入注册码的,用一个Label框来提示注册失败,较有意思:P
但还是用老办法来搞定---万能断点~~~^^.任意输入用户名和注册码后,CTRL-N呼出Trw2000,下断点"bpx hmemcpy",点击软件的Register按钮trw立刻就拦住了!用Pmodule命令回到软件领空,按F12七八次,再换F10就走到下面这里了------
016F:004752A2 FFB5F8FEFFFF
PUSH DWORD [EBP+FFFFFEF8] //我们在这里……
016F:004752A8 8D95F4FEFFFF LEA EDX,[EBP+FFFFFEF4]
//F10慢慢往下走...过Call后随便D一D寄存器的值看看:P
016F:004752AE 8B83E0020000 MOV EAX,[EBX+02E0]
016F:004752B4 E8BB80FBFF CALL 0042D374
016F:004752B9 FFB5F4FEFFFF PUSH DWORD [EBP+FFFFFEF4]
016F:004752BF 8D95F0FEFFFF LEA EDX,[EBP+FFFFFEF0]
016F:004752C5 8B83E4020000 MOV EAX,[EBX+02E4]
016F:004752CB E8A480FBFF CALL 0042D374
016F:004752D0 FFB5F0FEFFFF PUSH DWORD [EBP+FFFFFEF0]
016F:004752D6 8D95ECFEFFFF LEA EDX,[EBP+FFFFFEEC]
016F:004752DC 8B83E8020000 MOV EAX,[EBX+02E8]
016F:004752E2 E88D80FBFF CALL 0042D374
016F:004752E7 FFB5ECFEFFFF PUSH DWORD [EBP+FFFFFEEC]
016F:004752ED 8D95E8FEFFFF LEA EDX,[EBP+FFFFFEE8]
016F:004752F3 8B83EC020000 MOV EAX,[EBX+02EC]
016F:004752F9 E87680FBFF CALL 0042D374
016F:004752FE FFB5E8FEFFFF PUSH DWORD [EBP+FFFFFEE8]
016F:00475304 8D95E4FEFFFF LEA EDX,[EBP+FFFFFEE4]
016F:0047530A 8B83F0020000 MOV EAX,[EBX+02F0]
016F:00475310 E85F80FBFF CALL 0042D374
016F:00475315 FFB5E4FEFFFF PUSH DWORD [EBP+FFFFFEE4]
016F:0047531B 8D95E0FEFFFF LEA EDX,[EBP+FFFFFEE0]
016F:00475321 8B83F4020000 MOV EAX,[EBX+02F4]
016F:00475327 E84880FBFF CALL 0042D374
016F:0047532C FFB5E0FEFFFF PUSH DWORD [EBP+FFFFFEE0]
016F:00475332 8D95DCFEFFFF LEA EDX,[EBP+FFFFFEDC]
016F:00475338 8B83F8020000 MOV EAX,[EBX+02F8]
016F:0047533E E83180FBFF CALL 0042D374
//上面这8个call是依次取出8个注册框中的字符
016F:00475343 FFB5DCFEFFFF PUSH DWORD [EBP+FFFFFEDC]
016F:00475349 8D85FCFEFFFF LEA EAX,[EBP+FFFFFEFC]
016F:0047534F BA08000000 MOV EDX,08
016F:00475354 E863ECF8FF CALL 00403FBC
//将输入的8位注册码连起来
016F:00475359 8B95FCFEFFFF MOV EDX,[EBP+FFFFFEFC]
//放到EDX
016F:0047535F 8D8500FFFFFF LEA EAX,[EBP+FFFFFF00]
016F:00475365 B9FF000000 MOV ECX,FF
016F:0047536A E869EBF8FF CALL 00403ED8
//取注册码位数,一定是08乐:P
016F:0047536F 8D9500FFFFFF LEA EDX,[EBP+FFFFFF00]
016F:00475375 8D8304030000 LEA EAX,[EBX+0304]
016F:0047537B B108 MOV
CL,08
016F:0047537D E8EED8F8FF CALL 00402C70
016F:00475382 8D85D4FEFFFF LEA EAX,[EBP+FFFFFED4]
//将位数"08"与注册码连起来
016F:00475388 8D9304030000 LEA EDX,[EBX+0304]
//放到EDX
016F:0047538E E80DEBF8FF CALL 00403EA0
016F:00475393 8B85D4FEFFFF MOV EAX,[EBP+FFFFFED4]
…………
016F:004753E4 8BC6
MOV EAX,ESI
016F:004753E6 E801E1FEFF CALL 004634EC
016F:004753EB BA1C574700 MOV EDX,0047571C
//EDX="detitle.key"
016F:004753F0 8B83FC020000 MOV EAX,[EBX+02FC]
016F:004753F6 E811E1FEFF CALL 0046350C
//读取注册文件里的内容并解码(重启校验用的,这里不管它)
016F:004753FB 33D2 XOR
EDX,EDX
016F:004753FD 8B83C8020000 MOV EAX,[EBX+02C8]
016F:00475403 E89C7FFBFF CALL 0042D3A4
016F:00475408 33D2 XOR
EDX,EDX
016F:0047540A 8B83D8020000 MOV EAX,[EBX+02D8]
016F:00475410 E88F7FFBFF CALL 0042D3A4
016F:00475415 BA28574700 MOV EDX,00475728
016F:0047541A 8B83FC020000 MOV EAX,[EBX+02FC]
016F:00475420 E8E3DFFEFF CALL 00463408
016F:00475425 C783000300000350+MOV DWORD [EBX+0300],4F525003
016F:0047542F 8D85C8FEFFFF LEA EAX,[EBP+FFFFFEC8]
016F:00475435 50 PUSH
EAX
016F:00475436 8D95FCFEFFFF LEA EDX,[EBP+FFFFFEFC]
016F:0047543C 8B83C4020000 MOV EAX,[EBX+02C4]
016F:00475442 E82D7FFBFF CALL 0042D374
//取出用户名
016F:00475447 8B85FCFEFFFF MOV EAX,[EBP+FFFFFEFC]
//放入EAX
016F:0047544D 8D95D4FEFFFF LEA EDX,[EBP+FFFFFED4]
016F:00475453 E8882CF9FF CALL 004080E0
016F:00475458 FFB5D4FEFFFF PUSH DWORD [EBP+FFFFFED4]
//用户名入栈
016F:0047545E 6834574700 PUSH DWORD 00475734
016F:00475463 8D85C4FEFFFF LEA EAX,[EBP+FFFFFEC4]
016F:00475469 8D9300030000 LEA EDX,[EBX+0300]
016F:0047546F E82CEAF8FF CALL 00403EA0
016F:00475474 FFB5C4FEFFFF PUSH DWORD [EBP+FFFFFEC4]
016F:0047547A 8D85D8FEFFFF LEA EAX,[EBP+FFFFFED8]
016F:00475480 BA03000000 MOV EDX,03
016F:00475485 E832EBF8FF CALL 00403FBC
//将用户名和字符" PRO"连起来
016F:0047548A 8B95D8FEFFFF MOV EDX,[EBP+FFFFFED8]
//放入EDX
016F:00475490 8D8500FFFFFF LEA EAX,[EBP+FFFFFF00]
016F:00475496 B9FF000000 MOV ECX,FF
016F:0047549B E838EAF8FF CALL 00403ED8
016F:004754A0 8D9500FFFFFF LEA EDX,[EBP+FFFFFF00]
//EDX=后面连上" PRO"的用户名
016F:004754A6 8B83FC020000 MOV EAX,[EBX+02FC]
016F:004754AC 8A8875030000 MOV CL,[EAX+0375]
016F:004754B2 8B83FC020000 MOV EAX,[EBX+02FC]
016F:004754B8 E83FE2FEFF CALL 004636FC
//关键Call!!!!F8跟进~~~~~
016F:004754BD 8D95FCFEFFFF LEA EDX,[EBP+FFFFFEFC]
016F:004754C3 8B83C4020000 MOV EAX,[EBX+02C4]
016F:004754C9 E8A67EFBFF CALL 0042D374
016F:004754CE 8B85FCFEFFFF MOV EAX,[EBP+FFFFFEFC]
016F:004754D4 8D95D4FEFFFF LEA EDX,[EBP+FFFFFED4]
016F:004754DA E8012CF9FF CALL 004080E0
016F:004754DF FFB5D4FEFFFF PUSH DWORD [EBP+FFFFFED4]
016F:004754E5 6834574700 PUSH DWORD 00475734
016F:004754EA 8D85C4FEFFFF LEA EAX,[EBP+FFFFFEC4]
016F:004754F0 8D9300030000 LEA EDX,[EBX+0300]
016F:004754F6 E8A5E9F8FF CALL 00403EA0
016F:004754FB FFB5C4FEFFFF PUSH DWORD [EBP+FFFFFEC4]
016F:00475501 8D85D8FEFFFF LEA EAX,[EBP+FFFFFED8]
016F:00475507 BA03000000 MOV EDX,03
016F:0047550C E8ABEAF8FF CALL 00403FBC
016F:00475511 8B95D8FEFFFF MOV EDX,[EBP+FFFFFED8]
016F:00475517 8D8500FFFFFF LEA EAX,[EBP+FFFFFF00]
016F:0047551D B9FF000000 MOV ECX,FF
016F:00475522 E8B1E9F8FF CALL 00403ED8
016F:00475527 8D8500FFFFFF LEA EAX,[EBP+FFFFFF00]
016F:0047552D 50 PUSH
EAX
016F:0047552E BA38574700 MOV EDX,00475738
016F:00475533 8D85C8FEFFFF LEA EAX,[EBP+FFFFFEC8]
//EAX=前面连着"$"的正确注册码!
016F:00475539 E816D7F8FF CALL 00402C54
016F:0047553E 8D9304030000 LEA EDX,[EBX+0304]
016F:00475544 8D85C8FEFFFF LEA EAX,[EBP+FFFFFEC8]
016F:0047554A B109 MOV
CL,09
016F:0047554C E8D3D6F8FF CALL 00402C24
//将字符"$"与输入的注册码连起来
016F:00475551 8D8DC8FEFFFF LEA ECX,[EBP+FFFFFEC8]
016F:00475557 8B83FC020000 MOV EAX,[EBX+02FC]
016F:0047555D 5A POP
EDX
016F:0047555E E845E3FEFF CALL 004638A8
//比较Call,有兴趣的进去看看,是逐位比较的.
016F:00475563 84C0 TEST
AL,AL
016F:00475565 0F8423010000 JZ NEAR 0047568E
//注册码正确的话就继续往下走...然后它会告诉你注册成功乐!^^
016F:0047556B 8D95F8FEFFFF LEA EDX,[EBP+FFFFFEF8]
016F:00475571 8B83C4020000 MOV EAX,[EBX+02C4]
016F:00475577 E8F87DFBFF CALL 0042D374
016F:0047557C FFB5F8FEFFFF PUSH DWORD [EBP+FFFFFEF8]
016F:00475582 6834574700 PUSH DWORD 00475734
016F:00475587 8D85D8FEFFFF LEA EAX,[EBP+FFFFFED8]
016F:0047558D 8D9300030000 LEA EDX,[EBX+0300]
016F:00475593 E808E9F8FF CALL 00403EA0
016F:00475621 E8A624FAFF CALL 00417ACC
////////////////////////////////////////////
/ 在4754B8用F8跟入关键Call,我们来到这里……/
////////////////////////////////////////////
016F:004636FC 55
PUSH EBP
016F:004636FD 8BEC MOV
EBP,ESP
016F:004636FF 81C46CFFFFFF ADD ESP,FFFFFF6C
016F:00463705 53 PUSH
EBX
016F:00463706 56 PUSH
ESI
016F:00463707 57 PUSH
EDI
016F:00463708 8BF2 MOV
ESI,EDX
016F:0046370A 8D7DC2 LEA
EDI,[EBP-3E]
016F:0046370D 51 PUSH
ECX
016F:0046370E 33C9 XOR
ECX,ECX
016F:00463710 8A0E MOV
CL,[ESI]
016F:00463712 80F932 CMP
CL,32
016F:00463715 7202 JC
00463719
016F:00463717 B132 MOV
CL,32
016F:00463719 880F MOV
[EDI],CL
016F:0046371B 46 INC
ESI
016F:0046371C 47 INC
EDI
016F:0046371D F3A4 REP MOVSB
016F:0046371F 59 POP
ECX
016F:00463720 884DFF MOV
[EBP-01],CL
016F:00463723 8BD8 MOV
EBX,EAX
016F:00463725 33C0 XOR
EAX,EAX
016F:00463727 8A45C2 MOV
AL,[EBP-3E]
016F:0046372A 40 INC
EAX
016F:0046372B 83F832 CMP
EAX,BYTE +32
016F:0046372E 7F0E JG
0046373E
016F:00463730 8D5405C2 LEA EDX,[EBP+EAX-3E]
016F:00463734 C6020E MOV
BYTE [EDX],0E //将十六进制E,用户名连上" PRO"的后面!!
016F:00463737 40 INC
EAX
016F:00463738 42 INC
EDX
016F:00463739 83F833 CMP
EAX,BYTE +33 //表示将要给用户名后面连上33H个E!
016F:0046373C 75F6 JNZ
00463734 //向上构成一个小循环
//小结:上面这段代码对用户名的处理,得到了形如下面这样的形式:
07 61 61 61 20 50 52 4F 0E 0E 0E 0E 0E 0E 0E 0E ☆XXX PRO........
0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E ................
0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E ................
我们把这段设为Name_temp!
(注: XXX=用户名 , ☆=用户名+" PRO"的长度 , 总共有33H个"0E"
)
016F:0046373E 8D8D6CFFFFFF LEA ECX,[EBP+FFFFFF6C]
016F:00463744 8B9324020000 MOV EDX,[EBX+0224]
016F:0046374A 8BC3 MOV
EAX,EBX
016F:0046374C E853FEFFFF CALL 004635A4
//得到一个固定字符串"$8181404F"
016F:00463751 8D956CFFFFFF LEA EDX,[EBP+FFFFFF6C]
016F:00463757 8D45F5 LEA
EAX,[EBP-0B]
016F:0046375A B109 MOV
CL,09
016F:0046375C E80FF5F9FF CALL 00402C70
016F:00463761 B80A000000 MOV EAX,0A
016F:00463766 8D55F5 LEA
EDX,[EBP-0B] //EDX=固定字符串"$8181404F"
016F:00463769 8DB57BFFFFFF LEA ESI,[EBP+FFFFFF7B]
016F:0046376F 8A0A MOV
CL,[EDX] //逐位取出"$8181404F"
016F:00463771 880E MOV
[ESI],CL //放入ESI
016F:00463773 46 INC
ESI
016F:00463774 42 INC
EDX
016F:00463775 48 DEC
EAX
016F:00463776 75F7 JNZ
0046376F
016F:00463778 B833000000 MOV EAX,33
016F:0046377D 8D55C2 LEA
EDX,[EBP-3E] //将Name_temp放入EDX!
016F:00463780 8D7585 LEA
ESI,[EBP-7B]
016F:00463783 8A0A MOV
CL,[EDX] //依次取出Name_temp的值
016F:00463785 880E MOV
[ESI],CL //放在固定字符串"$8181404F"的后面
016F:00463787 46 INC
ESI
016F:00463788 42 INC
EDX
016F:00463789 48 DEC
EAX
//循环33H次
016F:0046378A 75F7 JNZ
00463783 //向上构成一个循环
//小结:上面这段代码对用户名的处理,得到了形如下面这样的形式:
09 24 38 31 38 31 34 30 34 46 07 61 61 61 20 50 .$8181404F☆XXX P
52 4F 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E RO..............
0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E ................
0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E
.............
我们把这段设为Name_temp1!
016F:0046378C 8D8D6CFFFFFF LEA ECX,[EBP+FFFFFF6C]
016F:00463792 8B9328020000 MOV EDX,[EBX+0228]
016F:00463798 8BC3 MOV
EAX,EBX
016F:0046379A E805FEFFFF CALL 004635A4
//得到另一个固定字符串"$81B41717"
016F:0046379F 8D956CFFFFFF LEA EDX,[EBP+FFFFFF6C]
016F:004637A5 8D45F5 LEA
EAX,[EBP-0B]
016F:004637A8 B109 MOV
CL,09
016F:004637AA E8C1F4F9FF CALL 00402C70
016F:004637AF 807DFF00 CMP BYTE
[EBP-01],00
016F:004637B3 7417 JZ
004637CC
016F:004637B5 B80A000000 MOV EAX,0A
016F:004637BA 8D55F5 LEA
EDX,[EBP-0B] //EDX=固定字符串"$81B41717"
016F:004637BD 8D75B8 LEA
ESI,[EBP-48]
016F:004637C0 8A0A MOV
CL,[EDX] //逐位取出固定字符串"$81B41717"
016F:004637C2 49 DEC
ECX
//逐位减一
016F:004637C3 880E MOV
[ESI],CL //放到Name_temp1的后面!
016F:004637C5 46 INC
ESI
016F:004637C6 42 INC
EDX
016F:004637C7 48 DEC
EAX
//循环10次
016F:004637C8 75F6 JNZ
004637C0 //向上构成循环
016F:004637CA EB14 JMP
SHORT 004637E0
//小结:到次我们得到了对用户名处理后的最终结果:
09 24 38 31 38 31 34 30 34 46 07 61 61 61 20 50 .$8181404F☆XXX P
52 4F 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E RO..............
0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E ................
0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 08 23 37 ..............#7
30 41 33 30 36 30 36 07 61 61 61 20 50 52 4F 0E 0A30606☆XXX PRO.
0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E ................
0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E ................
0E 0E 0E 0E 0E 0E 0E 0E 0E 0E
..........
除了☆XXX,其他都是固定的!这最终结果设为Name_result!
016F:004637CC B80A000000
MOV EAX,0A
016F:004637D1 8D55F5 LEA
EDX,[EBP-0B]
016F:004637D4 8D75B8 LEA
ESI,[EBP-48]
016F:004637D7 8A0A MOV
CL,[EDX]
016F:004637D9 880E MOV
[ESI],CL
016F:004637DB 46 INC
ESI
016F:004637DC 42 INC
EDX
016F:004637DD 48 DEC
EAX
016F:004637DE 75F7 JNZ
004637D7
016F:004637E0 8B9334030000 MOV EDX,[EBX+0334]
//EDX=110FAF,这是计算注册码的一个参数!设为sn_temp!
016F:004637E6 8D8D7BFFFFFF LEA ECX,[EBP+FFFFFF7B]
//ECX=Name_result!注意了!
016F:004637EC 8BC3 MOV
EAX,EBX
016F:004637EE E869FDFFFF CALL 0046355C
//里面是注册码的算法,关键!!跟入!
016F:004637F3 8BD0 MOV
EDX,EAX
016F:004637F5 8D8D6CFFFFFF LEA ECX,[EBP+FFFFFF6C]
//这里? EDX,十六进制的值就是注册码!!!!
016F:004637FB 8BC3 MOV
EAX,EBX
016F:004637FD E8A2FDFFFF CALL 004635A4
016F:00463802 8D956CFFFFFF LEA EDX,[EBP+FFFFFF6C]
016F:00463808 8B4508 MOV
EAX,[EBP+08]
016F:0046380B B109 MOV
CL,09
016F:0046380D E85EF4F9FF CALL 00402C70
016F:00463812 5F POP
EDI
016F:00463813 5E POP
ESI
016F:00463814 5B POP
EBX
016F:00463815 8BE5 MOV
ESP,EBP
016F:00463817 5D POP
EBP
016F:00463818 C20400 RET
04
////////////////////////////////////////////////
/ 在4637EE用F8跟入关键算法Call,我们来到看到……/
////////////////////////////////////////////////
016F:0046355C 53
PUSH EBX
016F:0046355D 56 PUSH
ESI
016F:0046355E 57 PUSH
EDI
016F:0046355F 83C4B8 ADD
ESP,BYTE -48
016F:00463562 8BF1 MOV
ESI,ECX
016F:00463564 8D3C24 LEA
EDI,[ESP]
016F:00463567 B911000000 MOV ECX,11
016F:0046356C F3A5 REP MOVSD
016F:0046356E 66A5 MOVSW
016F:00463570 A4 MOVSB
016F:00463571 B147 MOV
CL,47
016F:00463573 8BC4 MOV
EAX,ESP //EAX=Name_result!
016F:00463575 8BDA MOV
EBX,EDX //EBX=sn_temp!
016F:00463577 C1EB08 SHR
EBX,08 //EBX=EBX/(2^8)
016F:0046357A 81E3FFFFFF00 AND EBX,00FFFFFF
//EBX= and FFFFFF
016F:00463580 0FB630 MOVZX ESI,BYTE
[EAX] //依次取出Name_result的值放入ESI!
016F:00463583 33D6 XOR
EDX,ESI //sn_temp=sn_temp
xor ESI
016F:00463585 81E2FF000000 AND EDX,FF
//sn_temp=sn_temp and FF(即取低二位)
016F:0046358B 8B1495F05C4800 MOV EDX,[EDX*4+00485CF0]
//查表!4个字节4个字节的从密码表中取值,放入sn_temp……
//00485CF0处的密码表好长,有1kb(1024=256*4)狂晕,这里就不copy来了……-_-0
016F:00463592 33DA
XOR EBX,EDX
//ebx=sn_temp xor ebx
016F:00463594 8BD3 MOV
EDX,EBX //sn_temp=ebx
016F:00463596 40 INC
EAX
016F:00463597 FEC9 DEC
CL //循环47H次!
016F:00463599 75DA JNZ
00463575 //向上构成循环
016F:0046359B 8BC2 MOV
EAX,EDX //这里? EDX,得到的十六进制值就是最终正确的注册码!!!
016F:0046359D 83C448 ADD
ESP,BYTE +48
016F:004635A0 5F POP
EDI
016F:004635A1 5E POP
ESI
016F:004635A2 5B POP
EBX
016F:004635A3 C3 RET
算法小结:
⑴将用户名和字符串" PRO"和33H个十六进制数E连起来,设为name_temp.
⑵9(后面字符的长度)和固定字符串$8181404F连起来,再放到name_temp的前面,结果设为name_temp1.
⑶9(后面字符的长度)和固定字符串$81B41717连起来,再放到name_temp的前面,结果设为name_temp2.
⑷将name_temp1和name_temp2连起来,得到对用户名处理的最终结果,设为Name_result.
⑸将Name_result依次取出,计算得到一个两位的数,设为ebx~:P
⑹根据ebx的值在密码表(在485CF0处,长度为1k)中查表得一值,再将这个值异或ebx,结果放入sn_temp
⑺再跳回⑸,循环47H次后,sn_temp的十六进制值就是最终正确的注册码!
That's all~~Thank you for your attention!;-)