• 标 题:xyz计算机等级考试系统(二级c) vb编写
  • 作 者:mejy
  • 时 间:2003年10月25日 09:12
  • 链 接:http://bbs.pediy.com

一个vb软件的破解(新手请进)
软件名称:xyz计算机等级考试系统(二级c)   vb编写
难度系数: 容易
破解声明:  只为技术而破解!这个软件较为简单,主要介绍一下vb程序破解的基本知识
作者: mejy
工具: smartCheck  ,OD1.09汉化版   ,fi
第一   smartcheck的破解
首先我们看一下用smartCheck来对他进行破解,为什么呢?因为对vb的软件用smart分析一下有利于动态破解的思路?
可照看学第二版238页的方法进行。。。。。。先用smart载入xyz,点击run,然后在注册筐里输点什么?六位(分析后可知注册码为6位)
试练码  abcdef   我得序列号55555B
来到这:
__vbaStrVarMove(VARIANT:String:"ABCDEFGH...") returns DWORD:13406C
Arguments
--------------------
string (variant)
    unsigned short * .bstrVal = 0013406C
          = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789"
经过上面的计算得到了一劝字符串!记下他的地址,后面的计算注册码就是根据这个字符表得来得
WideCharToMultiByte(unsigned int:00000000, FLAGS:00000000, LPWSTR:0E2D1F44, int:1, PTR:0012EDAA, DWORD:00000002, LPSTR:00000000, PTR:00000000) returns INT:1
Arguments
--------------------
unsigned long CodePage = 0 0x00000000
unsigned long dwFlags = 0 0x00000000
unsigned short * lpWideCharStr = 0E2D1F44
      = "5"
signed long cchWideChar = 1 0x00000001
signed char * lpMultiByteStr = 0012EDAA
     = "-
signed long cchMultiByte = 2 0x00000002
signed char * lpDefaultChar = NULL
signed long * lpUsedDefaultChar = NULL

这一函数是将这个字符转化为十进制53
计算他在上面的表中对应的位置 然后
从内存中1340d8处取得字符3              正确注册码的第一位
一下与输入的假码的第一位进行比较
__vbaVarTstEq(VARIANT:String:"3", VARIANT:String:"a") returns DWORD:0
Arguments
--------------------
lhs (variant)
    unsigned short * .bstrVal = 001F6E94
          = "3"
rhs (variant)
    unsigned short * .bstrVal = 001B5DA4
          = "a"
SysAllocStringByteLen(char *:001340E4, DWORD:00000002) returns LPVOID:E2D1F44
经过计算取得注册码的第二位(他的位置与基址相差72)
Arguments
--------------------
signed char * psz = 001340E4
      = "9"
unsigned long len = 2 0x00000002
SysAllocStringByteLen(char *:001F6E6E, DWORD:00000002) returns LPVOID:1B5DA4
取得假码的第二位
Arguments
--------------------
signed char * psz = 001F6E6E
      = "b"
unsigned long len = 2 0x00000002
__vbaVarTstEq(VARIANT:String:"9", VARIANT:String:"b") returns DWORD:0

Arguments
--------------------
lhs (variant)
    unsigned short * .bstrVal = 0E2D1F44
          = "9"
rhs (variant)
    unsigned short * .bstrVal = 001B5DA4
          = "b"
进行比较
后面各位的比较方法类似这儿就不一一列出了
这儿我们能得出他的注册码,但是要明白他的算法


第二部分   od的动态分析
我们来动态调试一下,用od载入程序
载入后,先别急着运行,分析一下先,因为经过上面我们知道它采用的是变量比较的方法(见看学第二办231页)  断点函数为 vbavarTstEq;   点击右键  搜索――》当前模块中的名称――》找到vbavarTstEq――》右键,查找参考,看见调用的地方了美,在这可以设断点了,(你也可以在运行之后再设,应为这个程序启动是也进行了注册码的比较,会妨碍你的分析)。运行f9
程序运行有异常,shift+f9继续 (前面没设断点的话这就应该设了,如果设了的话f9键6次
每次你可分析仪下,程序其实就是进行6次比较)
 用d edx+8 来看看内存中有什么 -----172cdc中正确地注册码33
用d eax+8 因为刚启动什么也没有,下面我们继续
直到注册矿出现
然后输入假码abcdef 点注册,程序很快断在0045FF4E   . FF15 F0104000  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarTs>;  MSVBVM60.__vbaVarTstEq

再来看看 d eax+8中的地址  18ce24----61 a的ascii码
         d edx+8处的地址 18a97c ----33   3的ascii码

继续!下面进入分析过程
0045FDC5   > 66:3BC8        CMP CX,AX   //比较看看注册码的长度6结束否
0045FDC8   . 0F8F CD010000  JG XYZ_c271.0045FF9B如果比较结束跳出循环
0045FDCE   . 0FBFD9         MOVSX EBX,CX      将i赋值给ebx  第一次i=1,第二次i=2,第三次i=3,第四次i=4。。。。。
0045FDD1   . 8D55 D8  LEA EDX,DWORD PTR SS:[EBP-28]   ebp-28中保存的是序列号
0045FDD4   . 8D45 BC        LEA EAX,DWORD PTR SS:[EBP-44]
0045FDD7   . 8995 74FFFFFF  MOV DWORD PTR SS:[EBP-8C],EDX
0045FDDD   . 50             PUSH EAX
0045FDDE   . 8D8D 6CFFFFFF  LEA ECX,DWORD PTR SS:[EBP-94]  将4008--ecx中
0045FDE4   . 53               PUSH EBX
0045FDE5   . 8D55 AC        LEA EDX,DWORD PTR SS:[EBP-54]
0045FDE8   . 51             PUSH ECX
0045FDE9   . 52             PUSH EDX
0045FDEA   . C745 C4 010000>MOV DWORD PTR SS:[EBP-3C],1
0045FDF1   . C745 BC 020000>MOV DWORD PTR SS:[EBP-44],2
0045FDF8   . C785 6CFFFFFF >MOV DWORD PTR SS:[EBP-94],4008
0045FE02   . FF15 C4104000  CALL DWORD PTR DS:[<&MSVBVM60.#632>]     ;  MSVBVM60.rtcMidCharVar               //这个函数是取字符函数
0045FE08   . 8D45 AC       LEA EAX,DWORD PTR SS:[EBP-54]  这是取序列号的字符
0045FE0B   . 50             PUSH EAX
0045FE0C   . FF15 2C104000  CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrVa>;  MSVBVM60.__vbaStrVarMove移动字符可见是“5”
0045FE12   . 8BD0           MOV EDX,EAX
0045FE14   . 8D4D D0        LEA ECX,DWORD PTR SS:[EBP-30]
0045FE17   . FF15 FC114000  CALL DWORD PTR DS:[<&MSVBVM60.__vbaStrMo>;  MSVBVM60.__vbaStrMove
0045FE1D   . 8D4D AC        LEA ECX,DWORD PTR SS:[EBP-54]
0045FE20   . 8D55 BC        LEA EDX,DWORD PTR SS:[EBP-44]
0045FE23   . 51             PUSH ECX  //存的是ECX +8     35
0045FE24   . 52             PUSH EDX         2
0045FE25   . 6A 02          PUSH 2
0045FE27   . FFD7           CALL EDI
0045FE29   . 66:8B45 EC     MOV AX,WORD PTR SS:[EBP-14]    取位数i
0045FE2D   . 66:B9 0300     MOV CX,3            将3付给ecx的第位
0045FE31   . 66:99          CWD
0045FE33   . 66:F7F9        IDIV CX       //i%3     
0045FE36   . 83C4 0C        ADD ESP,0C      
0045FE39   . 66:85D2        TEST DX,DX 
0045FE3C   . 66:8995 12FFFF>MOV WORD PTR SS:[EBP-EE],DX   看看余数是否为零
0045FE43   . 75 2F     JNZ SHORT XYZ_c271.0045FE74  不为0跳  (有3种情况)    
分支1
0045FE45   . 8B55 D0        MOV EDX,DWORD PTR SS:[EBP-30]
0045FE48   . 52             PUSH EDX
0045FE49   . FF15 44104000  CALL DWORD PTR DS:[<&MSVBVM60.#516>]     ;  MSVBVM60.rtcAnsiValueBstr
0045FE4F   .8B0D 64A04600  MOV ECX,DWORD PTR DS:[46A064 //存的是58         ;  XYZ_c271.00460058              
0045FE55   . 33C1    XOR EAX,ECX    将序列号对应位上的字符的ascii码与之异或             
0045FE57   . 66:B9 3D00     MOV CX,3D
0045FE5B   . 66:99          CWD
0045FE5D   . 66:F7F9        IDIV CX
0045FE6066:8BF2     mOV SI,DX                    dx为余数    
0045FE63   . 66:8B95 12FFFF>MOV DX,WORD PTR SS:[EBP-EE]
0045FE6A. 66:83C6 01   ADD SI,1           0045FE6E   .    将余数加1 
0F80 90010000  JO XYZ_c271.00460004
分支2
0045FE74   > 66:83FA 01     CMP DX,1             dx为余数  和1比较
0045FE78   . 75 2E          JNZ SHORT XYZ_c271.0045FEA8
0045FE7A   . 8B55 D0        MOV EDX,DWORD PTR SS:[EBP-30]
0045FE7D   . 52             PUSH EDX
0045FE7E   . FF15 44104000  CALL DWORD PTR DS:[<&MSVBVM60.#516>]     ;  MSVBVM60.rtcAnsiValueBstr
0045FE84   . 66:3305 66A046>XOR AX,WORD PTR DS:[46A066] // [46A066 存的是 46
将序列号对应位上的字符的ascii码与之异或
0045FE8B   . 66:B9 3D00     MOV CX,3D        //将3d十六进制赋给ecx的低位
0045FE8F   . 66:99          CWD
0045FE91   . 66:F7F9        IDIV CX                              
0045FE94   . 66:8BF2        MOV SI,DX         求余后转移
0045FE97   . 66:8B9512FFFF>MOV DX,WORD PTR SS:[EBP-EE]
0045FE9E   . 66:83C6 01     ADD SI,1           余数加1
0045FEA2   . 0F80 5C010000  JO XYZ_c271.00460004  
分支3
0045FEA8   > 66:83FA 02     CMP DX,2                 和2比较
0045FEAC   . 75 27          JNZ SHORT XYZ_c271.0045FED5
0045FEAE   . 8B55 D0        MOV EDX,DWORD PTR SS:[EBP-30]   // 注册码的ascii
0045FEB1   . 52             PUSH EDX 
0045FEB2   . FF15 44104000  CALL DWORD PTR DS:[<&MSVBVM60.#516>]     ;  MSVBVM60.rtcAnsiValueBstr
0045FEB8   . 66:3305 68A046>XOR AX,WORD PTR DS:[46A068]    // [46A068]  中4c注册码的ascii异或
0045FEBF   . 66:B9 3D00     MOV CX,3D          
0045FEC3   . 66:99          CWD
0045FEC5   . 66:F7F9        IDIV CX
0045FEC8   . 66:8BF2        MOV SI,DX   dx中为余数   
0045FECB   . 66:83C6 01     ADD SI,1                si +1
0045FECF   . 0F80 2F010000  JO XYZ_c271.00460004
经过三个分之后来到这进行处理
0045FED5   > 8D55 E8       LEA EDX,DWORD PTR SS:[EBP-18]  //移入刚才的字符表
0045FED8   . 8D45 BC        LEA EAX,DWORD PTR SS:[EBP-44]
0045FEDB   . 0FBFCE         MOVSX ECX,SI
0045FEDE   . 8995 74FFFFFF  MOV DWORD PTR SS:[EBP-8C],EDX
0045FEE4   . 50             PUSH EAX
0045FEE5   . 8D95 6CFFFFFF  LEA EDX,DWORD PTR SS:[EBP-94]
0045FEEB   . 51             PUSH ECX
0045FEEC   . 8D45 AC        LEA EAX,DWORD PTR SS:[EBP-54]
0045FEEF   . 52             PUSH EDX
0045FEF0   . 50             PUSH EAX          //这些是一些处理
0045FEF1   . C745 C4 010000>MOV DWORD PTR SS:[EBP-3C],1
0045FEF8   . C745 BC 020000>MOV DWORD PTR SS:[EBP-44],2
0045FEFF   . C785 6CFFFFFF >MOV DWORD PTR SS:[EBP-94],4008
0045FF09   . FF15 C4104000  CALL DWORD PTR DS:[<&MSVBVM60.#632>]     ;  MSVBVM60.rtcMidCharVar   //这个是关键跟进********
这个函数就是在这个地址上加上si+1de十进制数 就是对应位的注册码,在这你就可以推出
注册码了,为了清楚我贴出了他的全部过程,没兴趣可以不看,不过想提高的话还是看下去
0017A504  UNICODE     别咱我
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789"
0045FF0F   . 8D4D D4        LEA ECX,DWORD PTR SS:[EBP-2C]
0045FF12   . 8D55 9C        LEA EDX,DWORD PTR SS:[EBP-64]
0045FF15   . 898D 54FFFFFF  MOV DWORD PTR SS:[EBP-AC],ECX
0045FF1B   . 52             PUSH EDX
0045FF1C   . 8D85 4CFFFFFF  LEA EAX,DWORD PTR SS:[EBP-B4]
0045FF22   . 53             PUSH EBX
0045FF23   . 8D4D 8C        LEA ECX,DWORD PTR SS:[EBP-74]
0045FF26   . 50             PUSH EAX
0045FF27   . 51             PUSH ECX
0045FF28   . C745 A4 010000>MOV DWORD PTR SS:[EBP-5C],1
0045FF2F   . C745 9C 020000>MOV DWORD PTR SS:[EBP-64],2
0045FF36   . C785 4CFFFFFF >MOV DWORD PTR SS:[EBP-B4],4008
0045FF40   . FF15 C4104000  CALL DWORD PTR DS:[<&MSVBVM60.#632>]     ;  MSVBVM60.rtcMidCharVar         //这个是取假注册码的函数
0045FF46   . 8D55 AC        LEA EDX,DWORD PTR SS:[EBP-54]
0045FF49   . 8D45 8C        LEA EAX,DWORD PTR SS:[EBP-74]
0045FF4C   . 52            PUSH EDX 用d edx+8 可看见真码的地址一次只能看见1位
0045FF4D   . 50            PUSH EAX用d eax+8 可看见真码的地址一次只能看见1位
因为vb程序的处理方式教特别所以用*+8
0045FF4E   . FF15 F0104000  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarTs>;  MSVBVM60.__vbaVarTstEq     //断点函数  关键比较

0045FF54   . 8D4D 8C        LEA ECX,DWORD PTR SS:[EBP-74]
0045FF57   . 8BD8           MOV EBX,EAX
0045FF59   . 8D55 AC        LEA EDX,DWORD PTR SS:[EBP-54]
0045FF5C   . 51             PUSH ECX
0045FF5D   . 8D45 9C        LEA EAX,DWORD PTR SS:[EBP-64]
0045FF60   . 52             PUSH EDX
0045FF61   . 8D4D BC        LEA ECX,DWORD PTR SS:[EBP-44]
0045FF64   . 50             PUSH EAX
0045FF65   . 51             PUSH ECX
0045FF66   . 6A 04          PUSH 4
0045FF68   . FFD7           CALL EDI
0045FF6A   . 83C4 14        ADD ESP,14
0045FF6D   . 66:85DB        TEST BX,BX
0045FF70   . 74 11          JE SHORT XYZ_c271.0045FF83
0045FF72   . 66:8B55 E4     MOV DX,WORD PTR SS:[EBP-1C]
0045FF76   . 66:83C2 01     ADD DX,1
0045FF7A   . 0F80 84000000  JO XYZ_c271.00460004
0045FF80   . 8955 E4        MOV DWORD PTR SS:[EBP-1C],EDX
0045FF83   > B8 01000000    MOV EAX,1
0045FF88   . 66:0345 EC     ADD AX,WORD PTR SS:[EBP-14]
0045FF8C   . 70 76          JO SHORT XYZ_c271.00460004
0045FF8E   . 8945 EC        MOV DWORD PTR SS:[EBP-14],EAX
0045FF91   . 8BC8           MOV ECX,EAX
0045FF93   . 8B45 E0        MOV EAX,DWORD PTR SS:[EBP-20]
0045FF96   .^E9 2AFEFFFF    JMP XYZ_c271.0045FDC5//结束没有没有的话跳
0045FF9B   > 66:3945 E4     CMP WORD PTR SS:[EBP-1C],AX
0045FF9F   . 75 07          JNZ SHORT XYZ_c271.0045FFA8    回去

上面那个Call
取内存中的序列号的第二位5计算正确地序列号
6A36B403 > 55               PUSH EBP
6A36B404   8BEC             MOV EBP,ESP
6A36B406   83EC 10          SUB ESP,10
6A36B409   56               PUSH ESI
6A36B40A   57               PUSH EDI
6A36B40B   FF35 C00E396A    PUSH DWORD PTR DS:[6A390EC0]
6A36B411   FF15 B810286A    CALL DWORD PTR DS:[<&KERNEL32.TlsGetValu>; KERNEL32.TlsGetValue
6A36B417   8D70 50          LEA ESI,DWORD PTR DS:[EAX+50]
6A36B41A   56               PUSH ESI
6A36B41B   FF75 0C          PUSH DWORD PTR SS:[EBP+C]
6A36B41E   E8 5096F3FF      CALL MSVBVM60.6A2A4A73
6A36B423   83F8 FF          CMP EAX,-1
6A36B426   74 3A            JE SHORT MSVBVM60.6A36B462
6A36B428   FF75 14          PUSH DWORD PTR SS:[EBP+14]       2
6A36B42B   FF75 10          PUSH DWORD PTR SS:[EBP+10]    31上面计算的结果       
6A36B42E   50               PUSH EAX                       
字符串 
 0012ED70   0017A504  UNICODE "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789"


6A36B42F   E8 AB94F3FF CALL MSVBVM60.rtcMidCharBstr //关键call2跟进
6A36B434   66:833E 08       CMP WORD PTR DS:[ESI],8
6A36B438   8945 F8          MOV DWORD PTR SS:[EBP-8],EAX
6A36B43B   66:C745 F0 0800  MOV WORD PTR SS:[EBP-10],8
6A36B441   75 0D            JNZ SHORT MSVBVM60.6A36B450
6A36B443   FF76 08          PUSH DWORD PTR DS:[ESI+8]
6A36B446   FF15 F019286A    CALL DWORD PTR DS:[<&OLEAUT32.#6>]       ; OLEAUT32.SysFreeString
6A36B44C   66:8326 00       AND WORD PTR DS:[ESI],0
6A36B450   8B45 08          MOV EAX,DWORD PTR SS:[EBP+8]
6A36B453   8D75 F0          LEA ESI,DWORD PTR SS:[EBP-10]
6A36B456   8BF8             MOV EDI,EAX
6A36B458   A5               MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES>
6A36B459   A5               MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES>
6A36B45A   A5               MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES>
6A36B45B   A5               MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ES>
6A36B45C   5F               POP EDI
6A36B45D   5E               POP ESI
6A36B45E   C9               LEAVE
6A36B45F   C2 1000          RETN 10
call2的代码
6A2A48DF > 55               PUSH EBP          
   6A2A48E0   8BEC          MOV EBP,ESP
6A2A48E2   83EC 10          SUB ESP,10
6A2A48E5   8B45 10          MOV EAX,DWORD PTR SS:[EBP+10]
6A2A48E8   66:8338 0A       CMP WORD PTR DS:[EAX],0A
6A2A48EC   75 26            JNZ SHORT MSVBVM60.6A2A4914
6A2A48EE   8178 08 04000280 CMP DWORD PTR DS:[EAX+8],80020004
6A2A48F5   75 1D            JNZ SHORT MSVBVM60.6A2A4914
6A2A48F7   83C9 FF          OR ECX,FFFFFFFF
6A2A48FA   66:85C9          TEST CX,CX
6A2A48FD   74 19            JE SHORT MSVBVM60.6A2A4918
6A2A48FF   50               PUSH EAX
6A2A4900   8B45 0C          MOV EAX,DWORD PTR SS:[EBP+C]   eax为余数
6A2A4903   8D4400 FF        LEA EAX,DWORD PTR DS:[EAX+EAX-1]    2×eax-1
6A2A4907   50               PUSH EAX                     字符串
6A2A4908   FF75 08          PUSH DWORD PTR SS:[EBP+8]      
6A2A490B   E8 1E000000      CALL MSVBVM60.rtcMidBstr   跟进call3 
6A2A4910   C9               LEAVE
6A2A4911   C2 0C00          RETN 0C

call3的代码
6A2A492E > 8B4424 08        MOV EAX,DWORD PTR SS:[ESP+8]  6A2A4932   53               PUSH EBX                       字符所在的    位置            123456
6A2A4933   56               PUSH ESI         
6A2A4934   57               PUSH EDI
6A2A4935   8D78 FF          LEA EDI,DWORD PTR DS:[EAX-1]   
6A2A4938   85FF             TEST EDI,EDI                    eax-1        78
6A2A493A   0F8C B6290200    JL MSVBVM60.6A2C72F6
6A2A4940   81FF FFFFFF7F    CMP EDI,7FFFFFFF
6A2A4946   0F8F AA290200    JG MSVBVM60.6A2C72F6
6A2A494C   8B4424 10        MOV EAX,DWORD PTR SS:[ESP+10]
6A2A4950   8BDF             MOV EBX,EDI             ebx=78         
6A2A4952   85C0             TEST EAX,EAX
6A2A4954   0F84 A3290200    JE MSVBVM60.6A2C72FD
6A2A495A   8B70 FC          MOV ESI,DWORD PTR DS:[EAX-4]
6A2A495D   3BFE             CMP EDI,ESI
6A2A495F   0F87 9F290200    JA MSVBVM60.6A2C7304
6A2A4965   8B4C24 18        MOV ECX,DWORD PTR SS:[ESP+18]
6A2A4969   66:8339 0A       CMP WORD PTR DS:[ECX],0A
6A2A496D   75 35            JNZ SHORT MSVBVM60.6A2A49A4
6A2A496F   8179 08 04000280 CMP DWORD PTR DS:[ECX+8],80020004
6A2A4976   75 2C            JNZ SHORT MSVBVM60.6A2A49A4
6A2A4978   83C8 FF          OR EAX,FFFFFFFF
6A2A497B   66:85C0          TEST AX,AX
6A2A497E   74 28            JE SHORT MSVBVM60.6A2A49A8
6A2A4980   2BF3             SUB ESI,EBX
6A2A4982   8BC6             MOV EAX,ESI
6A2A4984   50               PUSH EAX
6A2A4985   8B4424 14        MOV EAX,DWORD PTR SS:[ESP+14]
6A2A4989   03D8             ADD EBX,EAX
6A2A498B   53               PUSH EBX     这个是关键
6A2A498C   FF15 FC19286A    CALL DWORD PTR DS:[<&OLEAUT32.#150>]     ; OLEAUT32.SysAllocStringByteLen
6A2A4992   8BF0             MOV ESI,EAX
6A2A4994   85F6             TEST ESI,ESI
6A2A4996   0F84 76290200    JE MSVBVM60.6A2C7312
6A2A499C   8BC6             MOV EAX,ESI
6A2A499E   5F               POP EDI
6A2A499F   5E               POP ESI
6A2A49A0   5B               POP EBX
6A2A49A1   C2 0C00          RETN 0C
唉终于写完了!奋战了几个小时,写的不太好,凑或着看吧!呵呵!
这个软件很容易,大家拿来作为vb的练手吧,欢迎你的批评与指导!


_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
----------------******---------------
--------------"欢迎交流"------------------
----------------******---------------
【BCG】【FCG】【DFCG】【NUKE】【IPB】