一个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.本人水平有限,软件分析的不是很好,肯定从在很多的疏漏,欢迎指正,共同学习。@谢鹰杰
您好!非常感谢您的分析,图文并茂,让我受益匪浅!非常感谢!我还有些不太明白的地方想在请教您一下:
您提到的注册过程:
比如本机ID为:55602000FFBFBEFB
软件取反ID为:BFEBFBFF00020655
十进制ASCII码为: 66706966706670704848485048545353
赋值后的个位数字为: 6 3 9 6 3 6 3 3 8 8 83 8 4 3 3
每个个位的数字相乘:69657034752这一串数字就应该是注册码了对吗?但是我输入后怎么没用呢?
如果要写注册机改如何写呢? 非常感谢您的不断指导,真的让我学到很多,比自己边看教程边摸索要来得直接,教程上有的我这种大白有时看不太明白。谢谢!另外:注册码的算法是否哪里有问题?怎么按照您的方法算出来的注册码都注册不了?用您写的注册机不同的ID计算的结果都一样哦!易语言我就更不会了,看来我还要下苦功学习哦! 支持下!谢谢分享!!! 高端霸气上档次 谢谢分析。我懂 给你换了个代码的引用。 感谢分享!{:301_1000:} 非常感谢您的分析!看后收获不小! 逆向分析高手,学习了 等我上大学,我一定要学编程,即使变成单身狗,这又如何!
页:
[1]
2