• 标 题:屏保自己做2.61版算法分析! (7千字)
  • 作 者:波导终结者
  • 时 间:2002-2-18 22:24:02
  • 链 接:http://bbs.pediy.com

屏保自己做2.61版算法分析:(请按照①②③的顺序来看破解过程)
下载地址:http://ln.skycn.net/down/ScreenSaver_DIY261.zip
工具:TRW(虽说高手们都说用SOFTICE好,但我是菜鸟,又懒,凑合凑合吧)
打开TRW,再右击桌面,调出属性对话框,选ScrnSaver_DIY,点设置,调出主程序,在注册处填入注册名和注册码,点“注册”,??????????没有提示?好,我用bpx hmemcpy拦,拦住后,按F10往前走(走了多少路就不说了,直接来到关键处):
:0048FC59 8B45F8                  mov eax, dword ptr [ebp-08]      ①取用户名
:0048FC5C E83343F7FF              call 00403F94                    取用户名长度
:0048FC61 8BF0                    mov esi, eax                      ESI=用户名长度
:0048FC63 85F6                    test esi, esi                    是否为空
:0048FC65 7E3C                    jle 0048FCA3                      为空跳,不为空继续走
:0048FC67 BF01000000              mov edi, 00000001                把EDI置为1,关于这一行的作用参见③和⑤

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048FCA1(C)
|
:0048FC6C 8B45F8                  mov eax, dword ptr [ebp-08]      ②取用户名
:0048FC6F 33DB                    xor ebx, ebx                      把EBX清0
:0048FC71 8A5C38FF                mov bl, byte ptr [eax+edi-01]    ③取第EDI位用户名的ACDSII十进制值给EBX(目前EDI为1,则取第1位)
:0048FC75 8BC3                    mov eax, ebx                      把EBX的值给EAX
:0048FC77 F7EB                    imul ebx                          EAX=EAX*EBX
:0048FC79 F7EB                    imul ebx                          再乘一次EBX,这样,EAX等于EBX的三次方
:0048FC7B 8945EC                  mov dword ptr [ebp-14], eax      [ebp-14]=EAX
:0048FC7E DB45EC                  fild dword ptr [ebp-14]          把[ebp-14]压栈(其实也就是用户名的三次方)
:0048FC81 D9FA                    fsqrt                            开平方(也就是用户名某一位的ASCII值的三次方的平方根)
:0048FC83 E80C2FF7FF              call 00402B94                    取出这个数
:0048FC88 8BD8                    mov ebx, eax                     
:0048FC8A 8D55E8                  lea edx, dword ptr [ebp-18]
:0048FC8D 8BC3                    mov eax, ebx
:0048FC8F E8588DF7FF              call 004089EC                    转换成十进制,设为CODEA
:0048FC94 8B55E8                  mov edx, dword ptr [ebp-18]
:0048FC97 8D45F4                  lea eax, dword ptr [ebp-0C]      ④把CODEA给EAX
:0048FC9A E8FD42F7FF              call 00403F9C                    这个CALL的作用是:把注册名每一位算出来的CODEA一个一个接起来,比如说,注册名算得的CODEA分别为1000、1001、1002,则接完之后,则变成100010011002,设累加完后的这个字符串为CODEB
:0048FC9F 47                      inc edi                          ⑤EDI加1,这样如果算没完的话,回到④处取下一位
:0048FCA0 4E                      dec esi                          ESI减1(ESI为用户名长度)
:0048FCA1 75C9                    jne 0048FC6C                      如果ESI不为0(没算完),则跳②回处算下一位,如果ESI为0(算完了),则不跳,往下走。

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048FC65(C)
|
:0048FCA3 8B45F4                  mov eax, dword ptr [ebp-0C]      ⑥取CODEB
:0048FCA6 E8E942F7FF              call 00403F94                    取CODEB的长度
:0048FCAB 83F80A                  cmp eax, 0000000A                是不是大于十位
:0048FCAE 7E26                    jle 0048FCD6                      是的话直接跳到48FCD6处,开始比较注册码,不是的话不跳,往下走
:0048FCB0 8D45E4                  lea eax, dword ptr [ebp-1C]
:0048FCB3 50                      push eax
:0048FCB4 B90A000000              mov ecx, 0000000A
:0048FCB9 BA01000000              mov edx, 00000001
:0048FCBE 8B45F4                  mov eax, dword ptr [ebp-0C]
:0048FCC1 E8D644F7FF              call 0040419C                    把CODEB截取前十位,设为CODEC,比如前面举的例子,CODEB为100010011002,则截完后,CODEC为1000100110
:0048FCC6 8B55E4                  mov edx, dword ptr [ebp-1C]
:0048FCC9 8D45F4                  lea eax, dword ptr [ebp-0C]

* Possible StringData Ref from Code Obj ->"asd"
                                  |
:0048FCCC B970FE4800              mov ecx, 0048FE70
:0048FCD1 E80A43F7FF              call 00403FE0                    这个CALL的作用是:把CODEC的后面加上asd这三个字母,设为CODED,比如上面的例子,CODEC为1000100110,则过此处CODED为1000100110asd

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048FCAE(C)
|
:0048FCD6 8D55E0                  lea edx, dword ptr [ebp-20]
:0048FCD9 8B45FC                  mov eax, dword ptr [ebp-04]
:0048FCDC 8B8074030000            mov eax, dword ptr [eax+00000374]
:0048FCE2 E871FEF9FF              call 0042FB58                    ⑦取真注册码和假注册码
:0048FCE7 8B55E0                  mov edx, dword ptr [ebp-20]      EDX=假码
:0048FCEA 8B45F4                  mov eax, dword ptr [ebp-0C]      EAX=真码
:0048FCED E8B243F7FF              call 004040A4                    比较,按F8进入
:0048FCF2 0F8528010000            jne 0048FE20                      ⑨对就不跳,不对则跳
:0048FCF8 8B45FC                  mov eax, dword ptr [ebp-04]
:0048FCFB 8B8080030000            mov eax, dword ptr [eax+00000380]
*************************************************************************************************
48FCED处,进入:
:004040A4 53                      push ebx
:004040A5 56                      push esi
:004040A6 57                      push edi
:004040A7 89C6                    mov esi, eax
:004040A9 89D7                    mov edi, edx
:004040AB 39D0                    cmp eax, edx                      ⑧比较假码和真码
:004040AD 0F848F000000            je 00404142                      对就跳,不对不跳
:004040B3 85F6                    test esi, esi
:004040B5 7468                    je 0040411F
:004040B7 85FF                    test edi, edi
:004040B9 746B                    je 00404126
:004040BB 8B46FC                  mov eax, dword ptr [esi-04]
:004040BE 8B57FC                  mov edx, dword ptr [edi-04]
:004040C1 29D0                    sub eax, edx
:004040C3 7702                    ja 004040C7
:004040C5 01C2                    add edx, eax
*************************************************************************************************
总结:由以上分析可知,这个软件的算法是:
分别取出用户名的每一位的ASCII十进制值,三次方后平方根,把每一位的用户名这样运算之后,一个一个接起来,如果不大于十位的话,直接比较;如果大于十位的话,取前十位,再在后面接上“asd”这个字符串,再比较。
举例:我的用户名是alifriend的话,则a的ASCII十进制值是97,三次方的平方根是955……依此类推,每一位都这样算之后,串起来为95511221076103012171086101511541000,因为大于10位,取前十位为9551122107,在后面串上“asd”,所以我的注册码为9551122107asd。
*************************************************************************************************
外话:脱壳篇:
破这个东西其实不用脱壳的,但脱了壳抓代码比较方便,于是我就开始脱壳。用FI查出它是ASPACK加的壳,可是它是个SCR文件,我先用PROCDUMP脱,结果PROCDUMP罢工。自动脱壳不行我就用BW+TRW大法,运行它,用BW找到了入口为0049AFA4,我再用TRW载入,结果TRW也罢工。我倒,明明是可执行文件,装什么蒜啊?我把它的扩展名由SCR改成EXE,再用TRW载入,呵呵,OK了,g 0049AFA4,PEDUMP,OK,成功脱壳!
破解:波导终结者[BCG][CNCG]