Chinaunix首页 | 论坛 | 博客
  • 博客访问: 381277
  • 博文数量: 67
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1741
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-21 22:46
文章分类
文章存档

2014年(22)

2013年(45)

分类: 网络与安全

2013-08-20 09:45:19

最近上网找到了一个小软件TextDraw,写了个注册机,后来觉得算法挺好,于是就写了这篇破文与大家一起学习学习。TextDraw是一个简单易用且功能非常强大的文本图形制作工具。你可以像使用一般作图工具一样,在作图区绘制直线、椭圆、矩形、多边形、曲线等图形,但你使用的是文本,得到的是可以在记事本上显示的文本图形!不多说了,它的功能挺好,大家自己试试吧。
现在进入正题。先用PEiD查壳,运气不错,程序没有加壳,使用Borland C++ 1999编写。运行一下程序,在注册的地方输入“zjjtr”和“1234567890”注册,出现了一些奇怪的字符,如图1所示,提示“不是有效的整数”,我数了下它的位数,有十位,极有可能是由“1234567890”计算而来的。看来,注册码计算后的结果是整数才行。不管了,把它放到OD中去吧。查找那些字符,没找到,却发现了“注册失败,请检查你的输入是否有误”,我想那些字符可能会在附近,于是双击“注册失败,请检查你的输入是否有误”,来到下面的地方。
 

view plainprint?

    00415829  |> \66:C745 A4 D4>MOV WORD PTR SS:[EBP-5C],0D4  
    0041582F  |.  BA ADEC4900   MOV EDX,TextDraw.0049ECAD  
    ; 注册失败,请检查你的输入是否有误  
    00415834  |.  8D45 B8  LEA EAX,DWORD PTR SS:[EBP-48]  

在00415829处,信息窗口显示“跳转来自004154ED”,那我们就到004154ED看看吧。
 
view plainprint?

    004154EA  |.  83F8 64  CMP EAX,64  
    004154ED  |.  0F85 36030000 JNZ TextDraw.00415829  
    004154F3  |.  66:C745 A4 44>MOV WORD PTR SS:[EBP-5C],44  
    004154F9  |.  BA 88EC4900   MOV EDX,TextDraw.0049EC88       
    ; 注册成功,谢谢您的支持  

将EAX与0x64比较,不等就跳向注册失败的地方。在这里应该就可以爆破了,将JNZ改为JE即可,但我们是分析算法,那就接着往下看。在后面的分析中可以看到,这里的爆破还不行,因为由注册码算出的结果不是整数,是不会运行到这里来的。我们往前看,来到算法的入口处,一般它的前面有一个 RETN。我们在004152B0出下断点,F9运行,填好注册码,确定,程序便停了下来。
 
view plainprint?

    004152B0  /.  55  PUSH EBP ;断在这里  
    004152B1  |.  8BEC  MOV EBP,ESP  
    004152B3  |.  81C4 6CF7FFFF ADD ESP,-894  
    004152B9  |.  53  PUSH EBX  
    004152BA  |.  8955 8C  MOV DWORD PTR SS:[EBP-74],EDX  
    004152BD  |.  8945 90  MOV DWORD PTR SS:[EBP-70],EAX  
    004152C0  |.  B8 14EE4900  MOV EAX,TextDraw.0049EE14  
    004152C5  |.  E8 864E0600  CALL TextDraw.0047A150  
    004152CA  |.  66:C745 A4 08>MOV WORD PTR SS:[EBP-5C],8  
    004152D0  |.  8D45 FC  LEA EAX,DWORD PTR SS:[EBP-4]  
    004152D3  |.  E8 44C4FEFF  CALL TextDraw.0040171C  
    004152D8  |.  FF45 B0  INC DWORD PTR SS:[EBP-50]  
    004152DB  |.  66:C745 A4 14>MOV WORD PTR SS:[EBP-5C],14  
    004152E1  |.  66:C745 A4 20>MOV WORD PTR SS:[EBP-5C],20  
    004152E7  |.  8D45 F8  LEA EAX,DWORD PTR SS:[EBP-8]  
    004152EA  |.  E8 2DC4FEFF  CALL TextDraw.0040171C  
    004152EF  |.  8BD0  MOV EDX,EAX  
    004152F1  |.  FF45 B0  INC DWORD PTR SS:[EBP-50]  
    004152F4  |.  8B4D 90  MOV ECX,DWORD PTR SS:[EBP-70]  
    004152F7  |.  8B81 DC020000 MOV EAX,DWORD PTR DS:[ECX+2DC]  
    004152FD  |.  E8 8A570300  CALL TextDraw.0044AA8C;用户名长度进入EAX  
    00415302  |.  8D45 F8  LEA EAX,DWORD PTR SS:[EBP-8]  
    00415305  |.  E8 A2D1FEFF  CALL TextDraw.004024AC;用户名进入EAX  
    0041530A  |.  50  PUSH EAX; /Arg2  
    0041530B  |.  8D95 74FBFFFF LEA EDX,DWORD PTR SS:[EBP-48C]; |  
    00415311  |.  52  PUSH EDX; |Arg1  
    00415312  |.  E8 CD4B0600  CALL TextDraw.00479EE4; \TextDraw.00479EE4  
    00415317  |.  83C4 08  ADD ESP,8  
    0041531A  |.  FF4D B0  DEC DWORD PTR SS:[EBP-50]  
    0041531D  |.  8D45 F8  LEA EAX,DWORD PTR SS:[EBP-8]  
    00415320  |.  BA 02000000  MOV EDX,2  
    00415325  |.  E8 12F70600  CALL TextDraw.00484A3C  
    0041532A  |.  8D8D 74FBFFFF LEA ECX,DWORD PTR SS:[EBP-48C]  
    00415330  |.  51  PUSH ECX  
    00415331  |.  E8 DE4B0600  CALL TextDraw.00479F14  
    00415336  |.  59  POP ECX  
    00415337  |.  8945 80  MOV DWORD PTR SS:[EBP-80],EAX  
    0041533A  |.  C785 7CFFFFFF>MOV DWORD PTR SS:[EBP-84],-64  
    ;寄存器EBP初始化存入-0x64  
    00415344  |.  33C0  XOR EAX,EAX  
    00415346  |.  8945 84  MOV DWORD PTR SS:[EBP-7C],EAX  
    00415349  |.  8B55 84  MOV EDX,DWORD PTR SS:[EBP-7C]  
    0041534C  |.  3B55 80  CMP EDX,DWORD PTR SS:[EBP-80]  
    0041534F  |.  7D 23   JGE SHORT TextDraw.00415374  
    00415351  |>  8B4D 84  /MOV ECX,DWORD PTR SS:[EBP-7C]  
    00415354  |.  8A840D 74FBFF>|MOV AL,BYTE PTR SS:[EBP+ECX-48C];用户名每一位进入AL  
    0041535B  |.  8845 8B  |MOV BYTE PTR SS:[EBP-75],AL  
    0041535E  |.  33D2  |XOR EDX,EDX  
    00415360  |.  8A55 8B  |MOV DL,BYTE PTR SS:[EBP-75]  
    00415363  |.  0195 7CFFFFFF |ADD DWORD PTR SS:[EBP-84],EDX;加到[EBP-84]中  
    00415369  |.  FF45 84  |INC DWORD PTR SS:[EBP-7C]  
    0041536C  |.  8B4D 84  |MOV ECX,DWORD PTR SS:[EBP-7C]  
    0041536F  |.  3B4D 80  |CMP ECX,DWORD PTR SS:[EBP-80]  
    00415372  |.^ 7C DD   \JL SHORT TextDraw.00415351;用户名没取完往回跳  

到这里将用户名的ASCII码相加减去十进制的100,有什么用呢?我们接着往下看。
 
view plainprint?

    00415374  |>  8B85 7CFFFFFF MOV EAX,DWORD PTR SS:[EBP-84];结果放到EAX中,记为s1  
    0041537A  |.  8985 6CF7FFFF MOV DWORD PTR SS:[EBP-894],EAX  
    00415380  |.  33D2  XOR EDX,EDX  
    00415382  |.  8995 70F7FFFF MOV DWORD PTR SS:[EBP-890],EDX  
    00415388  |.  DFAD 6CF7FFFF FILD QWORD PTR SS:[EBP-894]    
    0041538E  |.  DB2D 80584100 FLD TBYTE PTR DS:[415880];浮点数“0.6480041472265422897”  
    00415394  |.  DEC9  FMULP ST(1),ST ;s1×0.6480041472265422897  
    00415396  |.  D805 8C584100 FADD DWORD PTR DS:[41588C] ;s1×0.6480041472265422897+1234,记为s2  
    0041539C  |.  E8 5F800600  CALL TextDraw.0047D400    
    ;这个call转化为十六进制,其实就是取整  
    004153A1  |.  8985 7CFFFFFF MOV DWORD PTR SS:[EBP-84],EAX  
    004153A7  |.  8B95 7CFFFFFF MOV EDX,DWORD PTR SS:[EBP-84]  
    004153AD  |.  8995 6CF7FFFF MOV DWORD PTR SS:[EBP-894],EDX  
    004153B3  |.  33C9  XOR ECX,ECX  
    004153B5  |.  898D 70F7FFFF MOV DWORD PTR SS:[EBP-890],ECX  
    004153BB  |.  DFAD 6CF7FFFF FILD QWORD PTR SS:[EBP-894]  
    004153C1  |.  DC0D 90584100 FMUL QWORD PTR DS:[415890] ;s2×3121.141592600000  
    004153C7  |.  E8 34800600  CALL TextDraw.0047D400;取整  
    004153CC  |.  8985 7CFFFFFF MOV DWORD PTR SS:[EBP-84],EAX  
    004153D2  |.  66:C745 A4 2C>MOV WORD PTR SS:[EBP-5C],2C  
    004153D8  |.  8D45 F4  LEA EAX,DWORD PTR SS:[EBP-C]  

到这里,用户名的计算告一段落,下面再看看用户名是怎么处理的。
 
view plainprint?

    004153DB  |.  E8 3CC3FEFF  CALL TextDraw.0040171C  
    004153E0  |.  8BD0  MOV EDX,EAX  
    004153E2  |.  FF45 B0  INC DWORD PTR SS:[EBP-50]  
    004153E5  |.  8B4D 90  MOV ECX,DWORD PTR SS:[EBP-70]  
    004153E8  |.  8B81 E4020000 MOV EAX,DWORD PTR DS:[ECX+2E4]  
    004153EE  |.  E8 99560300  CALL TextDraw.0044AA8C  
    004153F3  |.  8D45 F4  LEA EAX,DWORD PTR SS:[EBP-C]  
    004153F6  |.  E8 B1D0FEFF  CALL TextDraw.004024AC;注册码进入EAX  
    004153FB  |.  50  PUSH EAX ; /Arg2  
    004153FC  |.  8D95 74FBFFFF LEA EDX,DWORD PTR SS:[EBP-48C] ; |  
    00415402  |.  52  PUSH EDX; |Arg1  
    00415403  |.  E8 DC4A0600  CALL TextDraw.00479EE4; \TextDraw.00479EE4  
    00415408  |.  83C4 08  ADD ESP,8  
    0041540B  |.  FF4D B0  DEC DWORD PTR SS:[EBP-50]  
    0041540E  |.  8D45 F4  LEA EAX,DWORD PTR SS:[EBP-C]  
    00415411  |.  BA 02000000  MOV EDX,2  
    00415416  |.  E8 21F60600  CALL TextDraw.00484A3C  
    0041541B  |.  8D8D 74FBFFFF LEA ECX,DWORD PTR SS:[EBP-48C]  
    00415421  |.  51  PUSH ECX  
    00415422  |.  E8 ED4A0600  CALL TextDraw.00479F14  
    00415427  |.  59  POP ECX  
    00415428  |.  8945 80  MOV DWORD PTR SS:[EBP-80],EAX  
    0041542B  |.  33C0  XOR EAX,EAX  
    0041542D  |.  8945 84  MOV DWORD PTR SS:[EBP-7C],EAX  
    00415430  |.  8B55 84  MOV EDX,DWORD PTR SS:[EBP-7C]  
    00415433  |.  3B55 80  CMP EDX,DWORD PTR SS:[EBP-80]  
    00415436  |.  7D 46   JGE SHORT TextDraw.0041547E  
    00415438  |>  8B45 84  /MOV EAX,DWORD PTR SS:[EBP-7C]  
    0041543B  |.  B9 03000000  |MOV ECX,3  
    00415440  |.  99  |CDQ  
    00415441  |.  F7F9  |IDIV ECX;模3  
    00415443  |.  8B55 84  |MOV EDX,DWORD PTR SS:[EBP-7C]  
    00415446  |.  8A8C15 74FBFF>|MOV CL,BYTE PTR SS:[EBP+EDX-48C];注册码每一位进入CL  
    0041544D  |.  80C1 EC  |ADD CL,0EC;CL+0xEC  
    00415450  |.  8B55 84  |MOV EDX,DWORD PTR SS:[EBP-7C]  
    00415453  |.  81E2 01000080 |AND EDX,80000001;判断EDX奇偶性  
    00415459  |.  79 05   |JNS SHORT TextDraw.00415460;奇数跳转  
    0041545B  |.  4A  |DEC EDX  
    0041545C  |.  83CA FE  |OR EDX,FFFFFFFE  
    0041545F  |.  42  |INC EDX;EDX+1  
    00415460  |>  03D2  |ADD EDX,EDX;EDX×2  
    00415462  |.  8D1492  |LEA EDX,DWORD PTR DS:[EDX+EDX*4] ;EDX×5,始终为10  
    00415465  |.  2ACA  |SUB CL,DL;CL=CL-DL  
    00415467  |.  02C1  |ADD AL,CL;AL=AL+CL   
    00415469  |.  8B4D 84  |MOV ECX,DWORD PTR SS:[EBP-7C]  
    0041546C  |.  88840D 74FBFF>|MOV BYTE PTR SS:[EBP+ECX-48C],AL  
    00415473  |.  FF45 84  |INC DWORD PTR SS:[EBP-7C] ;计数器加1  
    00415476  |.  8B45 84  |MOV EAX,DWORD PTR SS:[EBP-7C]  
    00415479  |.  3B45 80  |CMP EAX,DWORD PTR SS:[EBP-80]  
    0041547C  |.^ 7C BA   \JL SHORT TextDraw.00415438;小于注册码长度,跳转   

大家可能看得一头雾水,这里在干什么呢?我来小结一下,这里的循环就是把每一位注册码变成另外的字符,从开头的错误信息推测,只有当这些字符是数字时,才有可能注册成功。
那么它是怎样计算的呢?首先取得一位注册码,加上0xEC,再加上(它的位数-1)mod 3,若是偶数为还得加上0xA,然后求得对应的ASCII码,组合在一起,这样就将注册码计算好了。我们继续往下看。
 
view plainprint?

    0041547E  |>  8D85 74FBFFFF LEA EAX,DWORD PTR SS:[EBP-48C]  
    00415484  |.  50  PUSH EAX; /Arg2  
    00415485  |.  8D95 74F7FFFF LEA EDX,DWORD PTR SS:[EBP-88C]; |  
    0041548B  |.  52  PUSH EDX; |Arg1  
    0041548C  |.  E8 534A0600  CALL TextDraw.00479EE4; \TextDraw.00479EE4  
    00415491  |.  83C4 08  ADD ESP,8  
    00415494  |.  66:C745 A4 38>MOV WORD PTR SS:[EBP-5C],38  
    0041549A  |.  8D95 74F7FFFF LEA EDX,DWORD PTR SS:[EBP-88C]  
    004154A0  |.  8D45 F0  LEA EAX,DWORD PTR SS:[EBP-10]  
    004154A3  |.  E8 DCF40600  CALL TextDraw.00484984  
    004154A8  |.  8BD0  MOV EDX,EAX  
    004154AA  |.  FF45 B0  INC DWORD PTR SS:[EBP-50]  
    004154AD  |.  8D45 FC  LEA EAX,DWORD PTR SS:[EBP-4]  
    004154B0  |.  E8 B7F50600  CALL TextDraw.00484A6C  
    004154B5  |.  FF4D B0  DEC DWORD PTR SS:[EBP-50]  
    004154B8  |.  8D45 F0  LEA EAX,DWORD PTR SS:[EBP-10]  
    004154BB  |.  BA 02000000  MOV EDX,2  
    004154C0  |.  E8 77F50600  CALL TextDraw.00484A3C  
    004154C5  |.  8D45 FC  LEA EAX,DWORD PTR SS:[EBP-4]  
    004154C8  |.  E8 E7F60600  CALL TextDraw.00484BB4    

;这里就是出错的地方,后来跟踪发现就是将上面得到的一串字符转化成十六进制,如果不是数字,当然是异常了。于是我不断试验,发现每一位的“0123456789”分别对应“DEFGHIJKLM”,我输了个E,经过上面的计算结果为整数1,接着调试下去
view plainprint?

    004154CD  |.  B9 7B000000  MOV ECX,7B   
    004154D2  |.  99  CDQ  
    004154D3  |.  F7F9  IDIV ECX;整数部分进入EAX  
    004154D5  |.  83C0 64  ADD EAX,64  
    004154D8  |.  8985 78FFFFFF MOV DWORD PTR SS:[EBP-88],EAX  
    004154DE  |.  8B85 78FFFFFF MOV EAX,DWORD PTR SS:[EBP-88]   
    004154E4  |.  2B85 7CFFFFFF SUB EAX,DWORD PTR SS:[EBP-84]    
    ;[EBP-84]中存放的是用户名计算结果  
    004154EA  |.  83F8 64  CMP EAX,64    
    004154ED  |.  0F85 36030000 JNZ TextDraw.00415829  
    004154F3  |.  66:C745 A4 44>MOV WORD PTR SS:[EBP-5C],44  
    004154F9  |.  BA 88EC4900  MOV EDX,TextDraw.0049EC88; 注册成功,谢谢您的支持  
    004154FE  |.  8D45 EC  LEA EAX,DWORD PTR SS:[EBP-14]  
    00415501  |.  E8 7EF40600  CALL TextDraw.00484984  

注册码转换后的结果除以0x7B得到的整数部分,如果和用户名计算的结果相等,就注册成功。
到这里就分析完了,我们再总结一下。算法主要用了F(用户名)?=G(注册码)的思路。F的过程为用户名的ASCII码求和-0x64,记为 s1,s1*0.6480041472265422897+1234取整得s2,s2×3121.141592600000取整得s3。G的过程为首先取得一位注册码,加上0xEC,再加上(它的位数-1)mod 3,若是偶数为还得加上0xA,然后求得对应的ASCII码,组合在一起,得到t1,t1除以0x7B得到t2。若s3=t2,则注册成功。
这个软件不能做内存注册机,但我写了一个VB注册机,源码如下。
 
view plainprint?

    Private Sub Command1_Click()  
    t = Text1.Text  
    For i = 1 To Len(t) Step 1  
    a = a + Asc(Mid(t, i, 1))  ‘用户名ASCII码求和  
    Next i  
    a = a - 100  
    b = Int(Int(a * 0.648004147226542 + 1234) * 3121.1415926)  
    b = b * 123  
    c = ""  
    Do While (b > 0)  
    c = Chr(b Mod 10 + 48) & c  
    b = Int(b / 10)  
    Loop  ‘转化为字符串,当然这里可以直接用VB的函数Cstr()  
    d = ""   
    For j = 1 To Len(c) Step 1  
    If j Mod 2 = 1 Then  
    d = d & Chr(Asc(Mid(c, j, 1)) + 20 - Int((j - 1) / 3))  
    Else  
    d = d & Chr(Asc(Mid(c, j, 1)) + 30 - Int((j - 1) / 3))  
    End If  ‘上面的逆运算  
    Next j  
    Text2.Text = d  
    End Sub  

用这个注册机注册成功的界面如图2所示。到这里,细心的读者可能看出来了,如果用户名ASCII码和小于100,会不会有问题呢?的确,如果用户名ASCII码和小于100,用这个注册机注册是不会成功的,我后来又跟了一遍,发现当s1为十六进制负数时,转化为十进制时会变成一个大的正数,然后相乘时会溢出,在VB中就运行不下去了。
 
图2
这个软件的算法还可以,但是留了太多的错误信息,也许作者想到给用户方便,但同样给Crack找到了破解的机会,建议最好不要留错误信息,或者将信息加密,也许能更好的保护软件。
阅读(1471) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~