1094483658 发表于 2015-7-17 16:16

一个VB程序的简单算法分析

本帖最后由 1094483658 于 2015-7-18 13:39 编辑

简单的程序,大牛就飞过吧

1.由于是VB程序,我们可以用vb decompiler这个工具帮助我们分析。

将程序拖入vb decompiler中,如下图


查找“确认”的按钮事件,如下图


找到按钮事件后 552770 ,OD载入


在此,先说明一下,程序有一个暗装,连续按3次确认键后,注册码都错误,第4次触发关机暗装。如下图


接着我们F8往下走,看代码注释
VB的代码就是长

005528AE   .8D85 68FFFFFF LEA   EAX, DWORD PTR SS:
005528B4   .50            PUSH    EAX
005528B5   .57            PUSH    EDI
005528B6   .8B17          MOV   EDX, DWORD PTR DS:
005528B8   .FF92 A0000000 CALL    NEAR DWORD PTR DS:                            ;获取id取反,并将ASCii转化为unicode
005528BE   .3BC6          CMP   EAX, ESI                                                ;我们将取反后的id命名为新id
005528C0   .DBE2          FCLEX
005528C2   .7D 12         JGE   SHORT fr2.005528D6
005528C4   .68 A0000000   PUSH    0xA0
005528C9   .68 2C524200   PUSH    fr2.0042522C
005528CE   .57            PUSH    EDI
005528CF   .50            PUSH    EAX
005528D0   .FF15 84104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaHresultCheckObj>]    ;msvbvm60.__vbaHresultCheckObj
005528D6   >8B8D 68FFFFFF MOV   ECX, DWORD PTR SS:
005528DC   .51            PUSH    ECX                                                   ; /String
005528DD   .FF15 38104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaLenBstr>]            ; \取新id的长度
005528E3   .8985 08FFFFFF MOV   DWORD PTR SS:, EAX
005528E9   .8D95 10FFFFFF LEA   EDX, DWORD PTR SS:
005528EF   .8D85 00FFFFFF LEA   EAX, DWORD PTR SS:
005528F5   .52            PUSH    EDX                                                   ; /Step8
005528F6   .8D8D F0FEFFFF LEA   ECX, DWORD PTR SS:                           ; |
005528FC   .50            PUSH    EAX                                                   ; |End8
005528FD   .8D95 C4FEFFFF LEA   EDX, DWORD PTR SS:                           ; |
00552903   .51            PUSH    ECX                                                   ; |Start8
00552904   .8D85 D4FEFFFF LEA   EAX, DWORD PTR SS:                           ; |
0055290A   .52            PUSH    EDX                                                   ; |TMPend8
0055290B   .8D8D 6CFFFFFF LEA   ECX, DWORD PTR SS:                            ; |
00552911   .50            PUSH    EAX                                                   ; |TMPstep8
00552912   .51            PUSH    ECX                                                   ; |Counter8
00552913   .C785 00FFFFFF>MOV   DWORD PTR SS:, 0x3                           ; |
0055291D   .C785 F8FEFFFF>MOV   DWORD PTR SS:, 0x1                           ; |
00552927   .C785 F0FEFFFF>MOV   DWORD PTR SS:, 0x2                           ; |
00552931   .FF15 AC104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaVarForInit>]         ; \__vbaVarForInit
00552937   .8D8D 68FFFFFF LEA   ECX, DWORD PTR SS:
0055293D   .8985 B8FEFFFF MOV   DWORD PTR SS:, EAX
00552943   .FF15 CC124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaFreeStr>]            ;msvbvm60.__vbaFreeStr
00552949   .8D8D 60FFFFFF LEA   ECX, DWORD PTR SS:
0055294F   .FF15 C8124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaFreeObj>]            ;msvbvm60.__vbaFreeObj
00552955   .8B3D 90124000 MOV   EDI, DWORD PTR DS:[<&MSVBVM60.__vbaStrMove>]            ;msvbvm60.__vbaStrMove
0055295B   >39B5 B8FEFFFF CMP   DWORD PTR SS:, ESI
00552961   .0F84 D5010000 JE      fr2.00552B3C
00552967   .8B13          MOV   EDX, DWORD PTR DS:
00552969   .53            PUSH    EBX
0055296A   .FF92 0C030000 CALL    NEAR DWORD PTR DS:
00552970   .50            PUSH    EAX
00552971   .8D85 60FFFFFF LEA   EAX, DWORD PTR SS:
00552977   .50            PUSH    EAX
00552978   .FF15 C8104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaObjSet>]             ;msvbvm60.__vbaObjSet
0055297E   .8BF0          MOV   ESI, EAX
00552980   .8D95 68FFFFFF LEA   EDX, DWORD PTR SS:
00552986   .52            PUSH    EDX
00552987   .56            PUSH    ESI
00552988   .8B0E          MOV   ECX, DWORD PTR DS:
0055298A   .FF91 A0000000 CALL    NEAR DWORD PTR DS:
00552990   .85C0          TEST    EAX, EAX
00552992   .DBE2          FCLEX
00552994   .7D 12         JGE   SHORT fr2.005529A8
00552996   .68 A0000000   PUSH    0xA0
0055299B   .68 2C524200   PUSH    fr2.0042522C
005529A0   .56            PUSH    ESI
005529A1   .50            PUSH    EAX
005529A2   .FF15 84104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaHresultCheckObj>]    ;msvbvm60.__vbaHresultCheckObj
005529A8   >8D85 50FFFFFF LEA   EAX, DWORD PTR SS:
005529AE   .8D8D 6CFFFFFF LEA   ECX, DWORD PTR SS:
005529B4   .BE 02000000   MOV   ESI, 0x2
005529B9   .50            PUSH    EAX
005529BA   .51            PUSH    ECX
005529BB   .C785 58FFFFFF>MOV   DWORD PTR SS:, 0x1
005529C5   .89B5 50FFFFFF MOV   DWORD PTR SS:, ESI
005529CB   .FF15 4C124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaI4Var>]            ;msvbvm60.__vbaI4Var
005529D1   .8B95 68FFFFFF MOV   EDX, DWORD PTR SS:
005529D7   .50            PUSH    EAX
005529D8   .52            PUSH    EDX
005529D9   .FF15 08114000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.#rtcMidCharBstr_631>]   ;取新id的第一位
005529DF   .8BD0          MOV   EDX, EAX
005529E1   .8D8D 64FFFFFF LEA   ECX, DWORD PTR SS:
005529E7   .FFD7          CALL    NEAR EDI
005529E9   .50            PUSH    EAX                                                   ; /String
005529EA   .FF15 5C104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.#rtcAnsiValueBstr_516>]   ; \取新id的第1位,转换成ASCii码
005529F0   .66:8985 48FFF>MOV   WORD PTR SS:, AX
005529F7   .8D85 40FFFFFF LEA   EAX, DWORD PTR SS:
005529FD   .8D8D 30FFFFFF LEA   ECX, DWORD PTR SS:
00552A03   .50            PUSH    EAX
00552A04   .51            PUSH    ECX
00552A05   .89B5 40FFFFFF MOV   DWORD PTR SS:, ESI
00552A0B   .FF15 6C124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.#rtcVarStrFromVar_613>]   ;msvbvm60.rtcVarStrFromVar
00552A11   .8D95 30FFFFFF LEA   EDX, DWORD PTR SS:
00552A17   .6A 01         PUSH    0x1
00552A19   .8D85 20FFFFFF LEA   EAX, DWORD PTR SS:
00552A1F   .52            PUSH    EDX
00552A20   .50            PUSH    EAX
00552A21   .FF15 A0124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.#rtcRightCharVar_619>]    ;msvbvm60.rtcRightCharVar
00552A27   .8B35 24104000 MOV   ESI, DWORD PTR DS:[<&MSVBVM60.__vbaVarMove>]            ;msvbvm60.__vbaVarMove
00552A2D   .8D95 20FFFFFF LEA   EDX, DWORD PTR SS:
00552A33   .8D4D A0       LEA   ECX, DWORD PTR SS:
00552A36   .FFD6          CALL    NEAR ESI                                                ;<&MSVBVM60.__vbaVarMove>
00552A38   .8D8D 64FFFFFF LEA   ECX, DWORD PTR SS:
00552A3E   .8D95 68FFFFFF LEA   EDX, DWORD PTR SS:
00552A44   .51            PUSH    ECX
00552A45   .52            PUSH    EDX
00552A46   .6A 02         PUSH    0x2
00552A48   .FF15 24124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaFreeStrList>]      ;msvbvm60.__vbaFreeStrList
00552A4E   .83C4 0C       ADD   ESP, 0xC
00552A51   .8D8D 60FFFFFF LEA   ECX, DWORD PTR SS:
00552A57   .FF15 C8124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaFreeObj>]            ;msvbvm60.__vbaFreeObj
00552A5D   .8D85 30FFFFFF LEA   EAX, DWORD PTR SS:
00552A63   .8D8D 40FFFFFF LEA   ECX, DWORD PTR SS:
00552A69   .50            PUSH    EAX
00552A6A   .8D95 50FFFFFF LEA   EDX, DWORD PTR SS:
00552A70   .51            PUSH    ECX
00552A71   .52            PUSH    EDX
00552A72   .6A 03         PUSH    0x3
00552A74   .FF15 48104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaFreeVarList>]      ;msvbvm60.__vbaFreeVarList
00552A7A   .83C4 10       ADD   ESP, 0x10
00552A7D   .8D45 A0       LEA   EAX, DWORD PTR SS:
00552A80   .8D8D 10FFFFFF LEA   ECX, DWORD PTR SS:
00552A86   .C785 18FFFFFF>MOV   DWORD PTR SS:, 0x1
00552A90   .50            PUSH    EAX                                                   ; /var18
00552A91   .51            PUSH    ECX                                                   ; |var28
00552A92   .C785 10FFFFFF>MOV   DWORD PTR SS:, 0x8002                         ; |
00552A9C   .FF15 F4104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaVarTstLt>]         ; \取字符的十进制的ASCii码的个位数,进行比较
00552AA2   .66:85C0       TEST    AX, AX                                                ;若个位数不为0,则触发跳转
00552AA5   .74 1F         JE      SHORT fr2.00552AC6                                    ;若个位数为0,则向赋值3
00552AA7   .8D95 10FFFFFF LEA   EDX, DWORD PTR SS:
00552AAD   .8D4D A0       LEA   ECX, DWORD PTR SS:
00552AB0   .C785 18FFFFFF>MOV   DWORD PTR SS:, 0x3
00552ABA   .C785 10FFFFFF>MOV   DWORD PTR SS:, 0x2
00552AC4   .FFD6          CALL    NEAR ESI
00552AC6   >DD45 C4       FLD   QWORD PTR SS:
00552AC9   .DC1D 583E4000 FCOMP   QWORD PTR DS:
00552ACF   .DFE0          FSTSW   AX
00552AD1   .F6C4 01       TEST    AH, 0x1                                                   ; /取新id的前11位,第12位之后的数字不参加下面的运算
00552AD4   .74 3E         JE      SHORT fr2.00552B14
00552AD6   .8B55 C4       MOV   EDX, DWORD PTR SS:
00552AD9   .8B45 C8       MOV   EAX, DWORD PTR SS:
00552ADC   .8995 18FFFFFF MOV   DWORD PTR SS:, EDX
00552AE2   .8D8D 10FFFFFF LEA   ECX, DWORD PTR SS:
00552AE8   .8985 1CFFFFFF MOV   DWORD PTR SS:, EAX
00552AEE   .8D55 A0       LEA   EDX, DWORD PTR SS:                            ;程序初始化的值为1
00552AF1   .51            PUSH    ECX                                                   ; /若个位数不为0,直接取个位数运算
00552AF2   .8D85 50FFFFFF LEA   EAX, DWORD PTR SS:                            ; |若个位数为0,取3作为它的个位数进行运算
00552AF8   .52            PUSH    EDX                                                   ; |
00552AF9   .50            PUSH    EAX                                                   ; |
00552AFA   .C785 10FFFFFF>MOV   DWORD PTR SS:, 0x5                            ; |
00552B04   .FF15 84114000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaVarMul>]             ; \乘法运算,循环相乘
00552B0A   .50            PUSH    EAX
00552B0B   .FF15 2C124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaR8Var>]            ;转化为浮点数
00552B11   .DD5D C4       FSTP    QWORD PTR SS:
00552B14   >8D8D C4FEFFFF LEA   ECX, DWORD PTR SS:
00552B1A   .8D95 D4FEFFFF LEA   EDX, DWORD PTR SS:
00552B20   .51            PUSH    ECX                                                   ; /TMPend8
00552B21   .8D85 6CFFFFFF LEA   EAX, DWORD PTR SS:                            ; |
00552B27   .52            PUSH    EDX                                                   ; |TMPstep8
00552B28   .50            PUSH    EAX                                                   ; |Counter8
00552B29   .FF15 C0124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaVarForNext>]         ; \__vbaVarForNext
00552B2F   .8985 B8FEFFFF MOV   DWORD PTR SS:, EAX
00552B35   .33F6          XOR   ESI, ESI
00552B37   .^ E9 1FFEFFFF   JMP   fr2.0055295B
00552B3C   >DD45 C4       FLD   QWORD PTR SS:
00552B3F   .DC1D 583E4000 FCOMP   QWORD PTR DS:
00552B45   .DFE0          FSTSW   AX
00552B47   .F6C4 41       TEST    AH, 0x41
00552B4A   .74 18         JE      SHORT fr2.00552B64
00552B4C   .DD45 C4       FLD   QWORD PTR SS:
00552B4F   .DC0D C0234000 FMUL    QWORD PTR DS:
00552B55   .DD5D C4       FSTP    QWORD PTR SS:
00552B58   .DFE0          FSTSW   AX
00552B5A   .A8 0D         TEST    AL, 0xD
00552B5C   .0F85 9A050000 JNZ   fr2.005530FC
00552B62   .^ EB D8         JMP   SHORT fr2.00552B3C
00552B64   >8B0B          MOV   ECX, DWORD PTR DS:
00552B66   .53            PUSH    EBX
00552B67   .FF91 24030000 CALL    NEAR DWORD PTR DS:
00552B6D   .8D95 60FFFFFF LEA   EDX, DWORD PTR SS:
00552B73   .50            PUSH    EAX
00552B74   .52            PUSH    EDX
00552B75   .FF15 C8104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaObjSet>]             ;msvbvm60.__vbaObjSet
00552B7B   .8B08          MOV   ECX, DWORD PTR DS:
00552B7D   .8D95 68FFFFFF LEA   EDX, DWORD PTR SS:
00552B83   .52            PUSH    EDX
00552B84   .50            PUSH    EAX
00552B85   .8985 ECFEFFFF MOV   DWORD PTR SS:, EAX
00552B8B   .FF91 A0000000 CALL    NEAR DWORD PTR DS:
00552B91   .3BC6          CMP   EAX, ESI
00552B93   .DBE2          FCLEX
00552B95   .7D 18         JGE   SHORT fr2.00552BAF
00552B97   .8B8D ECFEFFFF MOV   ECX, DWORD PTR SS:
00552B9D   .68 A0000000   PUSH    0xA0
00552BA2   .68 2C524200   PUSH    fr2.0042522C
00552BA7   .51            PUSH    ECX
00552BA8   .50            PUSH    EAX
00552BA9   .FF15 84104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaHresultCheckObj>]    ;msvbvm60.__vbaHresultCheckObj
00552BAF   >8B95 68FFFFFF MOV   EDX, DWORD PTR SS:
00552BB5   .52            PUSH    EDX
00552BB6   .FF15 D0124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.#rtcR8ValFromBstr_581>]   ;msvbvm60.rtcR8ValFromBstr
00552BBC   .FF15 FC104000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaFpR8>]               ;将输入的注册码转化为浮点数
00552BC2   .DC5D C4       FCOMP   QWORD PTR SS:
00552BC5   .DFE0          FSTSW   AX
00552BC7   .F6C4 40       TEST    AH, 0x40
00552BCA   .74 07         JE      SHORT fr2.00552BD3
00552BCC   .B8 01000000   MOV   EAX, 0x1
00552BD1   .EB 02         JMP   SHORT fr2.00552BD5
00552BD3   >33C0          XOR   EAX, EAX
00552BD5   >F7D8          NEG   EAX
00552BD7   .8D8D 68FFFFFF LEA   ECX, DWORD PTR SS:
00552BDD   .8985 E4FEFFFF MOV   DWORD PTR SS:, EAX
00552BE3   .FF15 CC124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaFreeStr>]            ;msvbvm60.__vbaFreeStr
00552BE9   .8D8D 60FFFFFF LEA   ECX, DWORD PTR SS:
00552BEF   .FF15 C8124000 CALL    NEAR DWORD PTR DS:[<&MSVBVM60.__vbaFreeObj>]            ;msvbvm60.__vbaFreeObj
00552BF5   .66:39B5 E4FEF>CMP   WORD PTR SS:, SI                           ;注册码比较
00552BFC   .0F84 3D040000 JE      fr2.0055303F                                          ;关键跳
00552C02   .DD45 C4       FLD   QWORD PTR SS:
00552C05   .DC0D C0234000 FMUL    QWORD PTR DS:
00552C0B   .DD5D C4       FSTP    QWORD PTR SS:
00552C0E   .DFE0          FSTSW   AX
00552C10   .A8 0D         TEST    AL, 0xD


2.注册流程:
   首先,软件倒序取本机ID号,接着取每一个本机ID号的十进制ASCII码,然后挨个判断各ASCII码的个位数是否为0,如果为0,则将个位数赋值为3,如果不为0,直接跳过。最后就是将前11位(包括11第位)的每个个位数字相乘,这个结果就是软件的注册码了。
3.爆破的关键位置00552BFC   .0F84 3D040000 JE      fr2.0055303F
将JE改为NOP
4.注册成功后,就会在C\Windows下生成一个以这个“$$$$$$$$$$$$$$”命名的空文件(14个$,不包括引号),程序每次启动都会判断有无这个文件,来确定软件是否注册。
5.软件下载地址:
链接: http://pan.baidu.com/s/1kTCIEhT 密码: c76j



6.本人水平有限,软件分析的不是很好,肯定从在很多的疏漏,欢迎指正,共同学习。@谢鹰杰





谢鹰杰 发表于 2015-7-17 23:02

您好!非常感谢您的分析,图文并茂,让我受益匪浅!非常感谢!我还有些不太明白的地方想在请教您一下:

您提到的注册过程:

比如本机ID为:55602000FFBFBEFB
软件取反ID为:BFEBFBFF00020655
十进制ASCII码为:   66706966706670704848485048545353
赋值后的个位数字为:   6   3   9   6   3   6   3   3   8   8    83   8   4   3   3
每个个位的数字相乘:69657034752这一串数字就应该是注册码了对吗?但是我输入后怎么没用呢?

如果要写注册机改如何写呢?

谢鹰杰 发表于 2015-7-19 14:19

非常感谢您的不断指导,真的让我学到很多,比自己边看教程边摸索要来得直接,教程上有的我这种大白有时看不太明白。谢谢!另外:注册码的算法是否哪里有问题?怎么按照您的方法算出来的注册码都注册不了?用您写的注册机不同的ID计算的结果都一样哦!易语言我就更不会了,看来我还要下苦功学习哦!

黑山走天涯 发表于 2015-7-17 16:18

支持下!谢谢分享!!!

Keller 发表于 2015-7-17 16:19

高端霸气上档次

LaoJII 发表于 2015-7-17 16:40

谢谢分析。我懂

Hmily 发表于 2015-7-17 16:41

给你换了个代码的引用。

白熊 发表于 2015-7-17 17:26

感谢分享!{:301_1000:}

谢鹰杰 发表于 2015-7-17 22:51

非常感谢您的分析!看后收获不小!

whjddzyx 发表于 2015-7-17 23:10

逆向分析高手,学习了

幻想之夢 发表于 2015-7-17 23:24

等我上大学,我一定要学编程,即使变成单身狗,这又如何!
页: [1] 2
查看完整版本: 一个VB程序的简单算法分析