qqc 发表于 2011-3-8 14:16

iTutor口语小教练详细算法破解与Delphi注册机(图)

【文章作者】: 海浪轻风(黄仁来)
【下载地址】: http://ha.newhua.com/down/iTutorSetup.zip
【操作平台】: 盗版XP
【软件介绍】: 一个高效的口语练习辅导工具
【作者声明】: 本文原创于看雪技术论坛
【详细过程】
   最近很忙,但再忙也要继续学算法分析,趁现在兴趣正浓~~~
   网上又抓到一个感觉不错的英语软件,提供丰富的听力教材,对练习口语和听力很有用。里面还有在线英文电台等,感觉也不错。
   软件说需要注册,但发现不注册和注册没有很大不同。没什么时间测试它的功能了,开工!
   OD载入,运行注册输入假码9876543210,弹出“注册失败”提示,查找超级字符串,很快定位到算法主过程大致如下:
   0045E420    .   6A FF         PUSH -1
   0045E422    .   68 68E14900   PUSH iTutor.0049E168                     ;   膏-k; SE 处理程序安装
   0045E427    .   64:A1 0000000>MOV EAX,DWORD PTR FS:
……中间省略N多代码……
0045E454    .   8D8E 28010000 LEA ECX,DWORD PTR DS:[ESI+128]
   0045E45A    .   E8 8C490200   CALL iTutor.00482DEB                     ;   读取假码
   0045E45F    .   8B5424 04   MOV EDX,DWORD PTR SS:[ESP+4]
   0045E463    .   52            PUSH EDX
   0045E464    .   E8 CD330000   CALL <JMP.&SAEGNR.#23>                   ;   不知干什么,懒得理
   0045E469    .   83C4 04       ADD ESP,4
   0045E46C    .   E8 B9330000   CALL <JMP.&SAEGNR.#21>                   ;   关键算法,F7进入
   0045E471    .   5E            POP ESI
   0045E472    .   83F8 01       CMP EAX,1
   0045E475    .   6A 00         PUSH 0                                 ; /Arg3 = 00000000
   0045E477    .   75 2C         JNZ SHORT iTutor.0045E4A5                ; |
   0045E479    .   6A 40         PUSH 40                                  ; |Arg2 = 00000040
   0045E47B    .   68 C43A4C00   PUSH iTutor.004C3AC4                     ; |注册成功!
   0045E480    .   E8 E3C60200   CALL iTutor.0048AB68                     ; \iTutor.0048AB68
   0045E485    .   E8 E8650300   CALL iTutor.00494A72
   0045E48A    .   8B4C24 00   MOV ECX,DWORD PTR SS:[ESP]
   0045E48E    .   8B40 04       MOV EAX,DWORD PTR DS:[EAX+4]
   0045E491    .   51            PUSH ECX                                 ; /Arg3
   0045E492    .   68 78354C00   PUSH iTutor.004C3578                     ; |regcode
   0045E497    .   68 6C354C00   PUSH iTutor.004C356C                     ; |settings
   0045E49C    .   8BC8          MOV ECX,EAX                              ; |
   0045E49E    .   E8 2EE80200   CALL iTutor.0048CCD1                     ; \iTutor.0048CCD1
   0045E4A3    .   EB 0C         JMP SHORT iTutor.0045E4B1
   0045E4A5    >   6A 30         PUSH 30                                  ; |Arg2 = 00000030
   0045E4A7    .   68 B83A4C00   PUSH iTutor.004C3AB8                     ; |注册失败!
   0045E4AC    .   E8 B7C60200   CALL iTutor.0048AB68                     ; \iTutor.0048AB68
   ……中间省略N多代码……
   0045E4D0    .   C3            RETN

   0045E46C处为关键算法过程,按一次F7,来到
   0046182A    $- FF25 00054A00 JMP DWORD PTR DS:[<&SAEGNR.#21>]         ;   SAEGNR.#21
   明显,这里程序调用了外部DLL(文件名是SAEGNR.dll)进行算法加密,这是个非常重要的提示!!
   赶快用PEid的Krypto ANALyzer插件查一下,发现有MD5和BASE64加密算法,思路顿时清晰~~~~

   继续F7吧,进入算法过程
   003A1480 >   81EC 00030000   SUB ESP,300
   003A1486   B9 40000000   MOV ECX,40
……中间省略N多代码……
   003A14A2   BE E0D83B00   MOV ESI,SAEGNR.003BD8E0                  ; 假码
   003A14A7   8D7C24 0C       LEA EDI,DWORD PTR SS:[ESP+C]
   003A14AB   C705 E0DE3B00 0>MOV DWORD PTR DS:,0
   003A14B5   F3:A5         REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
   003A14B7   BF E0DB3B00   MOV EDI,SAEGNR.003BDBE0                  ; 机器码
   003A14BC   83C9 FF         OR ECX,FFFFFFFF
……中间省略N多代码……
   003A14D7   8D8C24 0C010000 LEA ECX,DWORD PTR SS:[ESP+10C]
   003A14DE   51            PUSH ECX
   003A14DF   E8 7CFDFFFF   CALL SAEGNR.#11                        ; 关键算法过程,F7进入
   003A14E4   8BF8            MOV EDI,EAX                              ; 到这一步,寄存器EAX已经出现真正注册码了
   003A14E6   83C9 FF         OR ECX,FFFFFFFF                        ; 可以制作内存注册机
   003A14E9   33C0            XOR EAX,EAX
   …… 以下省略N多代码……
   003A1555   5B            POP EBX
   003A1556   81C4 00030000   ADD ESP,300

   明显003A14DF处继续调用外部dll序号为11的函数了。
   而这个函数F8步过后,寄存器EAX已经出现真正注册码了,可以制作内存注册机。但本人对内存注册机不感兴趣。   继续F7单步进入关键算法过程吧,看看 #11 函数,来到真正注册码算法核心部分,激动人心的时刻即将来临 ~~~~

   003A1260 >   6A FF         PUSH -1
   003A1262   68 61593B00   PUSH SAEGNR.003B5961
……中间省略N多代码……
003A12CB   8D4C24 28       LEA ECX,DWORD PTR SS:[ESP+28]
   003A12CF   51            PUSH ECX
   003A12D0   52            PUSH EDX
   003A12D1   E8 BA150000   CALL SAEGNR.003A2890            ; 把机器码进行标准MD5加密,结果记为M1(小写状态)
   003A12D6   83C4 0C         ADD ESP,0C
   003A12D9   50            PUSH EAX
……中间省略N多代码……
    003A1339   E8 52150000   CALL SAEGNR.003A2890            ; 把M1再进行MD5加密,结果记为M2
   003A133E   83C4 0C         ADD ESP,0C
   003A1341   50            PUSH EAX
   003A1342   8D4C24 14       LEA ECX,DWORD PTR SS:[ESP+14]
   ……中间省略N多代码……
   003A13A3   3BFB            CMP EDI,EBX
   003A13A5   8D4C3C 24       LEA ECX,DWORD PTR SS:[ESP+EDI+2>; 截M2后16位字符串,记为S2
   003A13A9   894C24 1C       MOV DWORD PTR SS:[ESP+1C],ECX   ; (则M2前16位字符串,记为S1)
   003A13AD   7E 76         JLE SHORT SAEGNR.003A1425       ; 循环↓ for i:=1 to 16 do begin
   003A13AF   55            PUSH EBP
   003A13B0   897C24 18       MOV DWORD PTR SS:[ESP+18],EDI
   003A13B4   8A16            MOV DL,BYTE PTR DS:[ESI]
   003A13B6   8D4424 24       LEA EAX,DWORD PTR SS:[ESP+24]
   003A13BA   6A 10         PUSH 10
   003A13BC   8D4C24 16       LEA ECX,DWORD PTR SS:[ESP+16]
   003A13C0   50            PUSH EAX
   003A13C1   51            PUSH ECX
   003A13C2   885424 1E       MOV BYTE PTR SS:[ESP+1E],DL   ; 取S1第i位ASCII值,记为S1
   003A13C6   885C24 1F       MOV BYTE PTR SS:[ESP+1F],BL   ; BL=0
   003A13CA   E8 BF330000   CALL SAEGNR.003A478E            ; 把S1转化为数值型,记为T1
   003A13CF   8A1437          MOV DL,BYTE PTR DS:[EDI+ESI]
   003A13D2   8BE8            MOV EBP,EAX
   003A13D4   8D4424 30       LEA EAX,DWORD PTR SS:[ESP+30]
   003A13D8   6A 10         PUSH 10
   003A13DA   8D4C24 22       LEA ECX,DWORD PTR SS:[ESP+22]
   003A13DE   50            PUSH EAX
   003A13DF   51            PUSH ECX
   003A13E0   885424 2A       MOV BYTE PTR SS:[ESP+2A],DL   ; 取S2第i位ASCII值,记为S2
   003A13E4   885C24 2B       MOV BYTE PTR SS:[ESP+2B],BL   ; BL=0
   003A13E8   E8 A1330000   CALL SAEGNR.003A478E            ; 把S2转化为数值型,记为T2
   003A13ED   03C5            ADD EAX,EBP                     ; T1 + T2,结果记为T3
   003A13EF   25 0F000080   AND EAX,8000000F                ; T3:=T3 and $8000000F(相当于取计算结果的最后一位)
   003A13F4   79 05         JNS SHORT SAEGNR.003A13FB
   003A13F6   48            DEC EAX
   003A13F7   83C8 F0         OR EAX,FFFFFFF0
   003A13FA   40            INC EAX
   003A13FB   8D5424 2A       LEA EDX,DWORD PTR SS:[ESP+2A]
   003A13FF   6A 10         PUSH 10
   003A1401   52            PUSH EDX
   003A1402   50            PUSH EAX
   003A1403   E8 A7C50000   CALL SAEGNR.003AD9AF            ; 再转换为字符串
   003A1408   0FBE4424 36   MOVSX EAX,BYTE PTR SS:[ESP+36]
   003A140D   50            PUSH EAX
   003A140E   E8 6B390000   CALL SAEGNR.003A4D7E            ; 变大写,记为T4,累加结果为真正注册码
   003A1413   8806            MOV BYTE PTR DS:[ESI],AL
   003A1415   8B4424 40       MOV EAX,DWORD PTR SS:[ESP+40]
   003A1419   83C4 28         ADD ESP,28
   003A141C   46            INC ESI
   003A141D   48            DEC EAX
   003A141E   894424 18       MOV DWORD PTR SS:[ESP+18],EAX
   003A1422   ^ 75 90         JNZ SHORT SAEGNR.003A13B4       ; 循环↑
   003A1424   5D            POP EBP
   003A1425   8B4C24 1C       MOV ECX,DWORD PTR SS:[ESP+1C]
   003A1429   8D7C24 24       LEA EDI,DWORD PTR SS:[ESP+24]
   003A142D   33C0            XOR EAX,EAX
   003A142F   C78424 2C010000>MOV DWORD PTR SS:[ESP+12C],-1
   003A143A   8819            MOV BYTE PTR DS:[ECX],BL
   003A143C   83C9 FF         OR ECX,FFFFFFFF
   003A143F   F2:AE         REPNE SCAS BYTE PTR ES:[EDI]
   003A1441   F7D1            NOT ECX
   003A1443   2BF9            SUB EDI,ECX
   003A1445   8BD1            MOV EDX,ECX
   003A1447   8BF7            MOV ESI,EDI
   003A1449   BF E0DC3B00   MOV EDI,SAEGNR.003BDCE0         ; ASCII "364B1B71E950FDDE"
   003A144E   C1E9 02         SHR ECX,2                     ; 以上OD自动的“注释”即真正注册码
……中间省略N多代码……
   003A147F   C3            RETN

【算法总结】
    Step1: 两次MD5加密机器码,结果保存为M1 (注意是小写状态)
    Step2: 把M1截分为两段,前16位记为S1,后16位记为S2
    Step3: 循环开始→ 取M1的第i位记为T1,取M2的第i位记为T2,将T1和T2转换为十六进制后相加,结果记为T3
    Step4: 运算 T3 AND $8000000F 结果转换成字符串,并转换成大写,记为T4
    Step5: 累加T4为真正注册码 ←循环结束

【Delphi重现算法过程】
uses MD5;//自己查找MD5标准加密算法单元
{$R *.dfm}

function TransChar(AChar: Char): Integer;
begin
    if AChar in ['0'..'9'] then
      Result := Ord(AChar) - Ord('0')
    else
      Result := 10 + Ord(AChar) - Ord('A');
end;
function GetSN(MachineCode:string):string;
var
    R: string;
    S1, S2: string;
    T1 : Integer;
    T2:string;
    I: Integer;
    Reg: string;
begin
    R := MD5Print(MD5String(MachineCode)); //第一次MD5加密;
    R := UpperCase(MD5Print(MD5String(R))); //第二次MD5加密
    S1 := Copy(R, 1, 16); //取前16位;
    S2 := Copy(R, 17, 16); //取后16位;
    for I := 1 to 16 do
    begin
      T1:=TransChar(S1)+TransChar(S2) ; //分别取第i位ASCII值相加
      T2:=IntToHex(T1 and $8000000F,1); //如果T1为双位,则取后一位变字符串;
      Reg:=Reg+T2;
      //以上两步,可以表达为:
      //T2:=IntToHex(T1,1); //转化为十六进制字符;
      //Reg:=Reg+ Copy(T2,Length(T2),1); //取取最后一位字符串,累加;
    end;
    Result:=Reg;
end;

--------------------------------------------------------------------------------
【经验总结】
   本人在一个非常简单的过程差点弄晕,就是在Delphi中如何实现字符串、十六进制以及ASCII码三者之间的相互转换问题。
   现在还有有点晕。不知哪位高人能提供完整的源代码关于以上三者的相互转换的函数??

http://www.anqn.com/pic/3/66c6331350afd6916438dbdf.jpg

532098613 发表于 2011-3-13 08:26

lovektm 发表于 2011-3-18 21:31

好东西。。。
那个下载地址是破解了的么

zhaoyafei19 发表于 2011-3-19 07:56

学习了
谢谢楼主

gsj6200 发表于 2012-3-16 14:13

这个我收藏了.!!

yang511021 发表于 2013-1-6 20:53

注册机在哪呢

五菱 发表于 2013-1-13 10:24

算法让人看得郁闷,很复杂呀,收藏以后慢慢看
页: [1]
查看完整版本: iTutor口语小教练详细算法破解与Delphi注册机(图)