VB程序破解


VB 程序简介

  现在不少程序是用 VB 写的,你通过反汇编或跟踪调试时很容易鉴别某个程序是否为 VB 程序,VB 的 EXE 文件并不是真正的编译可执行文件,它们需其动态链接库才能正常运行,各版本的链接库如下:

VB3 链接库为 vbrun300.dll ;

VB4 链接库为  vb40016.dll ; - 16 位,较少见;

VB4 链接库为  vb40032.dll ; - 32 位;

VB5 链接库为 msvbvm50.dll ;

VB6 链接库为 msvbvm60.dll ;

  VB 程序执行时从本质上讲是解释执行,它们只是调用  VBRUNxxx.DLL 中的函数   ,这样可使程序员不需写大量的程序代码就可编写出较好的图形界面的 windows 程序,不过 VB 是真正的程序吗?

 当然 VB 程序大大方便了程序编写者,但对我们来说, VB 程序向来是谁见谁头痛,一般用 VB 做的程序无论注册码也好, 30 天到期也好,如果用常规方法都很难有被破解的可能。原因很简单, VB 的 exe 是伪代码,程序都在 vbXXX.dll 里面执行,你只能在 vbdll 里面用 sice 打转转,什么都改不成,而且代码质量不高,结构还颇复杂。

 不过你学完这一课,你就不用怕 Vb 程序,在这里我就谈谈两种常用方法,一、用 SOFTICE 对付;二、用 SmartCheck 。这一节就讲讲 SOFTICE 破解 VB 程序。

--------------------------------------------------------------------------------


SOFTICE 配制

 虽然大部分 VB 程序仍调用 Win32 API 函数,但如想在 VB dll 运行库中设断的话,你就必须把 VB dll 运行库加入 SOFTICE 配制里去。具体你可参考第五课中的《 SOFTICE 安装及使用》。

下例是在 win95/98 下你把相关的 VB DLL 运行库加入 winice.dat 配制文件里。 ( 部分 )


; 注意分号后是描述语言,不被执行。每次只装载需要的一种 VB dll ,不要同时装载两个以上,把要装载那种 VB dll 那一行的分号去掉,重新启动即可。另外,判断软件是何种 VB dll 有几种方法,最直接一种用 WDasm89 查看,还有一种方法是用十六进制工具打开程序,观察。或用 SOFTICE 跟进去(用 bpx hmemcpy) ,稍转一圈,你观察一下调试窗口领空处会出现何种 VB DLL 即可。

; EXP=c:/windows/system/msvbvm60.dll   ; Visual Basic 6 
; EXP=c:/windows/system/msvbvm50.dll   ; Visual Basic 5 
; EXP=c:/windows/system/vb40032.dll    ; Visual Basic 4(32-bit) 
; EXP=c:/windows/system/vb40016.dll   ;Visual Basic 4(16-bit) 较少见 
; EXP=c:/windows/system/vbrun300.dll   ; Visual Basic 3

 

   这样配制好后,重新启动,就可设 VB 运行库中各函数的断点了。

--------------------------------------------------------------------------------

VB dll 常用函数

1 、字符处理函数

MultiByteToWideChar, rtcR8ValFromBstr, WideCharToMultiByte, __vbaStrCmp, __vbaStrComp, __vbaStrCopy, __vbaStrMove, __vbaVarTstNe .

注意:这些函数前的下划线 __ 是由两根短线 _ 组成的,不要弄错。 如果你是 crack VB6 程序,你应在断点前增加 msvbvm60! 。 如:  bpx msvbvm60!__vbastrcomp

VB5以前版本就没此限制 。如 bpx __vbaStrCmp


一些常用字符串函数

Val() -  转换字符串为数字 .

Str$() -  转换数字为字符串 .

Left$() -  按要求从左取字符。例如:  Left$(Theodolite, 4) = "Theo".

Right$() -  按要求从右取字符 .

Ltrim$() -  去除字符串左边空格例如:  Ltrim$ (" Hello ") = "Hello ".

Rtrim$() -  去除字符串左边空格 .

Trim$() -  去除字符串两边空格 .

Asc() -  转换字符为 ANSI 编码  . 例如: Asc("A") = 65. (注:65是ASCII码的十进制)

Chr$() -  转换 ANSI 编码为字符 . 例如  Chr$(65) = "A".

几个常用函数简解:

1、 __vbavartstne

如是在VB5中CALL MSVBVM50!___vbavartstne

进去后在0F04E351你将看到:
push dword ptr [ebp+0c] ;Push address *真* serial 的地址
push dword ptr [ebp+10] ;Push address 你输入的serial地址

下命令:d ebp+0c
你将在数据窗口看到 4字节地址倒序排列,你再次D 地址(己纠正顺序的), 就可看到序列号了。
 

2、 __vbaR8Str

在 VB5中是如下情况:
Push ebp-20
Call MSVBUM50.__vbaR8Str ;转换 string 到 Integer/Real
fcomp qword ptr [00401028] ;数据比较

在这行fcomp qword ptr [00401028] Type: DL 00401028 将看到*real* serial #.

DL 是显示 Long/real 型,SOFTICE默认时是DB状态。 
 

3、 __vbastrcmp

例:


:005BDC32 CALL [MSVBVM50!__VbaFreeVar] 
:005BDC38 MOV ESI,[EBP+08]
:005BDC3B PUSH ESI
:005BDC3E CALL [ECX+00000790] <-- 值返回到 EDX.
:005BDC44 MOV EDX,[ESI+4C] <-- 输入的号码,但倒转
:005BDC47 MOV EAX,[005E0078] <-- 正确号码
:005BDC4C PUSH EDX
:005BDC4D PUSH EAX <-- Push参数给 __vbaStrCmp.
:005BDC4E CALL [MSVBVM50!__vbaStrCmp] <-- Visual Basic 字符串比较
:005BDC54 TEST EAX,EAX <-- 测试比较结果
:005BDC56 JNZ 005BDC64 <-- 不相等跳走 
 

 

 

2 、警告窗口函数


rtcBeep, rtcGetPresentDate (time API), rtcMsgBox

--------------------------------------------------------------------------------

 

VB 序列号破解技巧

 在大部分 VB 程序中,我们能用 bpx Hmemcpy 命令设断,但是你将发现自己不久进入  VBRUNxxx.DLL 运行库,很快陷入 Vb dll 中,在大多数情况下,你很难到达其 EXE 文件中的真正比较核心。你通常是依靠字符串的线索来跟踪程序,你们还应记得 VB ( VB4 以上)   程序储存和比较字符是用 wide character 格式(本质是中在各字符间填 20h )。如:


原来字符串 : CRACKZ (43h 52h 41h 43h 4Bh 5Ah).

Wide 字符串格式 : C R A C K Z (43h 20h 52h 20h 41h 20h 43h 20h 4Bh 20h 5Ah).


这时在 SOFTICE 下查看内存中的字符串时看到情况有可能是:  C R A C K Z

有些情况下应该用 DL (长实型)命令,才能看到正确数字序号。( SOFTICE 默认时为 DB (字节型))

 在多数情况下,在 VB 中设置正确断点是较困难的。断点设置好后,尝试输入序列号,运行后,应返回 VBRUNxxx.DLL 里,现在查找寄存器 (EAX & EBX) 中的值,那里放有你输入字符串长度,如果没发现什么,你应按 ctrl+D 再次返回到 VB dll 中另一处   ,继续查看,一直重复。

 一但当你在寄存器中发现字符串长度时,你应一步一步注意观察,如果你幸运的话,你会发现输入字符串躺在寄存器或其显示附近内存里。这时你在 SOFTICE 里的数据窗口中用 ALT+ 光标键滚动查找,说不定会发现正确序列号懒洋洋躺在那附近。

--------------------------------------------------------------------------------

 

Visual Basic 程序比较方法

在  Visual Basic 里有 8 种以上的方法检测正确的序列号 / 密码。我这里将谈谈这 8 种方法,它们都是较容易并用得较多。首先是最普通的 3 种:

1) 串(string) 比较

在这比较方法里,正确密码串如: "Correct Password" 和你输入的密码串如: "Entered Password" 比较。

串是由相邻的字符按顺序排列组成,一个串包括字母、数字、空格和标点符号。一个固定长度的串可储存 0 到 63K 字符。如是动态的串其储存字符个数可达 20 亿字符。

 

VB 串比较代码一般格式:


If "Correct Password" = "Entered Password" then        <-- 直接比较两个串字符

GoTo Correct Message 

Else 

GoTo Wrong Message 

End if


这是一种简单保护方案,如果程序者用这种函数保护,用 SOFTICE 很容易拦截。


可用到的断点:

i) __vbastrcomp or __vbastrcmp   (下划线是两短线 _ 组成)                   <-- 串比较函数


注意:如果你是 crack VB6 程序,你应在两断点前增加 msvbvm60! 。

如:  bpx msvbvm60!__vbastrcomp or bpx msvbvm60!__vbastrcmp


ii) 搜索特殊比较代码(具体参考下一节)

  如: 56,57,8b,7c,24,10,8b,74,24,0c,8b,4c,24,14,33,c0,f3,66,a7 

 


2)  变量(Variant)比较

在这方法中,两个变量(变量数据类型)互相比较。变量数据类型是一种特殊数据类型,包括数字、字符串或日期数据及一些用户定义的类型。这种类型储存数字长度是 16 字节或字符 22 字节(加上串长度)。


一个范例代码:


Dim correct As Variant, entered As Variant    <-- 定义 "correct" and "entered"  作为变量

correct = Correct Password                           <-- 设置  "correct" 放置 "Correct Password" 

entered = Text1.Text                                       <-- 设置  "entered"  作为你输入密码  

If correct = entered Then                                <-- 用变量方法比较  

GoTo Correct Message 

Else 

GoTo Wrong Message 

End If


在这方法里, 1 中的两个断点将不起作用,因为程序不再用

__vbastrcomp  等 ...


有用断点   :

i) __vbavartsteq                                              <-- 测试变量是否相等


注意:如果你是 crack VB6 程序,你应在两断点前增加 msvbvm60! 。

例:  bpx msvbvm60!__vbavartsteq 

 


3) 长整型( long) 比较

这也是一个普通的方法。两个变量(长整型)互相比较。

long 型数据类型是 4 字节( 32 位)整数,其范围 -2,147,483,648  到  2,147,483,647 。因此该种方法存在只能比较数字的局限性。

一个此类型范例:


Dim correct As Long, entered As Long          <-- 定义  "correct"  和  "entered"  作为长整型

correct = 12345                                            <-- 设置 "correct" 为正确密码

entered = Text1.Text                                     <-- 设置  "entered" 为输入密码

If entered = correct Then                              <-- 用长整型方法比较  

GoTo Correct Message 

Else 

GoTo Wrong Message 

End If


对这种类型没有专门的断点函数,因为其数据比较是在主程序里而不是在 VB dll 中。

 

--------------------------------------------------------------------------------


我再简要谈谈其它的 5 种方法,如果下面的方法你听起来有点怪或不太可能,你可忽略它们,但记得 VB 保护方式不限于上述三种。


4)  单精度实数(Single)比较

这个方法用两单精度实数数据彼此比较。

它的数据类型是单精度浮点实数,在内存中占 4 字节( 32 位),数值范围 -3.402823E38  到  -1.401298E-45  为负值, 1.401298E-45 到 3.402823E38 为正值。

因此这方法一个限制是仅仅能比较数字,但是有时,程序能把我们的姓名和序列号转换成实数比较。

 

这种类型格式 :


Dim correct As Single, entered As Single      <-- 定义  "correct"  和  "entered"  单精度型  

correct = Correct Password                         <-- 设置  "correct" 为 "Correct Password" 

entered = Text1.Text                                     <-- 设置 "entered"  为你输入密码  

If correct = entered Then                              <-- 在此比较  

GoTo Correct Message 

Else 

GoTo Wrong Message 

End If


对这种类型没有专门的断点函数,因为其数据比较是在主程序里而不是在 VB dll 中。

 

5)  双精度(Double)比较

这个方法是用两个双精度数据比较。

它的数据类型是双精度浮点实数,在内存占 8 个字节( 64 位), -1.79769313486232E308  到  -4.94065645841247E-324  是正数, 4.94065645841247E-324  到 1.79769313486232E308 是负数。

你可能发现双精度比较非常类似单精度比较。因此这方法一个限制是仅仅能比较数字,但是有时,程序能把我们的姓名和序列号转换成实数比较。


这种类型格式 :


Dim correct As Double, entered As Double    <-- 定义 "correct"  和  "entered"  为双精度型

correct = Correct Password                           <-- 设置 "correct" 为  "Correct Password" 

entered = Text1.Text                                    <-- 设置 "entered"  为你输入的密码

If correct = entered Then                             <-- 在此比较

GoTo Correct Message 

Else 

GoTo Wrong Message 

End If


对这种类型没有专门的断点函数,因为其数据比较是在主程序里而不是在 VB dll 中。


 


6) 整型(Integer)比较

这方法是用两个整型数据进行彼此比较。

它的数据在内存是以 2 个字节存放。范围 -32,768 到 32,767 。同样这方法一个限制是仅仅能比较数字,但是有时,程序能把我们的姓名和序列号转换成实数比较。

 

这种类型格式 :


Dim correct As Integer, entered As Integer     <-- 定义  "correct"  和  "entered"  为整型

correct = Correct Password                           <-- 设置  "correct" 为 "Correct Password" 

entered = Text1.Text                                      <-- 设置 "entered"  为你输入的密码  

If correct = entered Then                                <-- 在此比较

GoTo Correct Message 

Else 

GoTo Wrong Message 

End If


对这种类型没有专门的断点函数,因为其数据比较是在主程序里而不是在 VB dll 中。


7)  字节(Byte)比较

这个方法是两个字节数据进行比较。

它是 0-255 范围的整数,其通常存储是 1 字节( 8 位)。

其限制不超过 255, 但有时它通过计算把你姓名转换成数字,以此比较。


这种类型格式 :


Dim correct As Byte, entered As Byte     <-- 定义  "correct"  和  "entered"  为字节型

correct = Correct Password                   <-- 设置  "correct" 为 "Correct Password" 

entered = Text1.Text                              <-- 设置 "entered"  为你输入的密码  

If correct = entered Then                        <-- 在此比较

GoTo Correct Message 

Else 

GoTo Wrong Message 

End If


对这种类型没有专门的断点函数,因为其数据比较是在主程序里而不是在 VB dll 中。


 


8) CURRENCY  型比较


这个方法是用两个 Currency 数据类型进行比较。是的,它听起来是怪,但确实存在!

它的数据范围: -922,337,203,685,477.5808  到  922,337,203,685,477.5807. 用这数据类型进行货币和一些需高精度的场合上很重用。

因此此种方法局限性也是只能比较数字,但有时它通过计算把你姓名转换成数字,以此比较。


这种类型格式 :

Dim correct As Currency, entered As Currency   <-- 定义  "correct"  和  "entered"  为 Currency  型

correct = Correct Password                               <-- 设置  "correct" 为 "Correct Password" 

entered = Text1.Text                                    <-- 设置 "entered"  为你输入的密码   

If correct = entered Then                              <-- 在此比较

GoTo Correct Message 

Else 

GoTo Wrong Message 

End If


对这种类型没有专门的断点函数,因为其数据比较是在主程序里而不是在 VB dll 中。


--------------------------------------------------------------------------------

上述8个比较方式是不是意味着我们每次能中断在其单个某一类型的比较程序里?回答是否定的。这是因为程序有可能同时采用两种方法来比较,如Currency和String, Variant 和 Long 等...

比较类型列表

  String 
 Variant 
 Long 
 Currency 
 Single 
 Double 
 Integer 
 Byte 
 
String 
 Normal 
 V 
 SD 
 SC 
 SS 
 SD 
 SD 
 SD 
 
Variant 
 - 
 Normal 
 V 
 V 
 V 
 V 
 V 
 V 
 
Long 
 - 
 - 
 Normal 
 __vbaFpCmpCy 
 Sin to D 
 DC 
 DC 
 DC 
 
Currency 
 - 
 - 
 - 
 Normal 
 __vbaFpCmpCy 
 __vbaFpCmpCy 
 __vbaFpCmpCy 
 __vbaFpCmpCy 
 
Single 
 - 
 - 
 - 
 - 
 Normal 
 DC 
 DC 
 DC 
 
Double 
 - 
 - 
 - 
 - 
 - 
 Normal 
 DC 
 DC 
 
Integer 
 - 
 - 
 - 
 - 
 - 
 - 
 Normal 
 DC 
 
Byte 
 - 
 - 
 - 
 - 
 - 
 - 
 - 
 Normal 
 

V   = Variant 型比较

SD =  在比较前字符串( String )转换成双精度型( Doubl )

SC =  在比较前字符串( String )转换成  Currency 型

SS =  在比较前字符串( String )转换成双单精度型( Single )

Sin to D =  在比较前单精度型转换成双精度型( Double )

DC =  直接比较

__vbaFpCmpCy =Currency 型浮点比较


从这里你将会明白,如没用其它工具直接用 SOFTICE ,你将花费大量的精力和时间找出 VB 程序真正的比较代码程序。不过幸好 SmartCheck  的出现使我们走出这恶梦,我们如用SOFTICE找不到序列号,此时可用SmartCheck帮我们快速找到关键断点函数。

 

--------------------------------------------------------------------------------

一些可能用上的断点

 

1) 数据类型转换

i)  字符串( String )转换字节( Byte )或整型( Integer ) : __vbai2str 

ii)  字符串( String )转长型( Long ) : __vbai4str 

iii)  字符串( String )转换单精度型( Single ) : __vbar4str 

iv)  字符串( String )转换双精度型( Double ) : __vbar8str 

v) 字符串( String )转 Currency 型 : VarCyFromStr ( 适合 VB6.  你的 WINICE.DAT 必须有 OLEAUT32.DLL) 

vi) 整型( Integer )转字符串型( String ) : VarBstrFromI2 ( 适合 VB6.  你的 WINICE.DAT 必须 OLEAUT32.DLL)


2) 移动数据

i) 字符串( String )到内存 : __vbaStrCopy 

ii) 变量( Variant )到内存 : __vbaVarCopy or __vbaVarMove


3)  运算符  

i) 加法 : __vbavaradd               <-- 增加变量

ii) 减法 : __vbavarsub          <-- 减去变量  

iii)  乘法 : __vbavarmul       <-- 乘以变量

iv)  除法 : __vbavaridiv              <--Dividing Variant to get answer in Integer 

v) XOR: __vbavarxor                   <--XOR


4)  其它类  

i) __vbavarfornext             <--Used in codes where there is a For... Next... Statement (Loop) 

ii) __vbafreestr 

iii) __vbafreeobj 

iv) __vbastrvarval              <--Get the value from a specific location in a String 

v) multibytetowidechar 

vi) rtcMsgBox 

vii) __vbavarcat                 <--Joining 2 Variants together 

viii) __vbafreevar 

ix) __vbaobjset

 

=============================

crack VB程序的一些建议

1 )用SmartCheck配合。

首先:运行 SmartCheck 后,点击 Program -> Settings. 在 Error Detection 这一栏中选中所有的 ERROR 报告。Report errors immedietly 可不选。在 Advanced  中仅仅顶部 3 个 Report 必须选上。


其次:在 Reporting 这一栏中:除了 Report MouseMove events from OCX controls 这项外把其它各项全选上。


2 )在用 SmartCheck 中打开被 crack 文件之前,你最好多运行需被 CRACK 的文件几次,以了解其一些保护方法。


3 )用 SmartCheck 装载程序后,按 program → start 运行程序,运行好后,输入序列号,按 OK 。选择 "Show All Events" ,然后整个相关信息列出在上左部分主框中。在这里非常容易发现你需要的一行,如: xxxxxx_Click. xxxxxx ,你可点击在右框中看到其相关信息。


3)  一般首先寻找  __vbastrcomp, __vbastrcmp or __vbavartsteq  如果你幸运的话,你可能会发现序列号码。其具体的一些技巧参看下一节。  


4)  如果不能发现上述 3 个函数,可能是用其它的一些比较方法。现在通过这一行,寻找一些程序注册出错的信息。你一般会发现几个我在第一部分《 VB 介绍》这课末尾处列出的几个  __vba 函数,先找出一个离出错信息最近的一个。你这时可能需 SOFTICE 配合了,在 SOFTICE 中可用此函数设断,你可在 SmartCheck 中观察一下会中断几次,以便知在 SOFTICE 下按多少下 F5.

例如:你设置 __vbafreestr 断点,在你点击 OK 后,有很多次中断。如果你在 SmartCheck 下查看是在第 10 处: 10th __vbafreestr 离出错信息最近,在 SOFTICE 下你可按 F5 九次来到 __vbafreestr 。

记得在 VB6, 设断时前面加上 msvbvm60!  。

 

5)  运行程序输入序列号,按 OK,SOFTICE 将会中断,除非你断点没找对。有一点需注意:在 VB6 下有可能需在运行程序前设置断点,才能中断。


6)  开始跟踪每一个 CALL 并查看每一怀疑的注册号。它不会花费你许多时间就能来到错误信息处。如果没发现任何怀疑地方,返回 SmartCheck 寻找下一个断点,刚才的断点有可能在比较程序后面。

 

反编译工具(VB Decompiler Pro):是一款针对使用Visual Basic 5.0/6.0开发的程序的反编译器。反编译工具(VB Decompiler Pro)可以被编译成伪代码p-code或native code模式。由于伪代码是由高级指令组成, 因此是很有可能反编译成源代码的(当然, 变量名,函数名等等是无法反编译的).反编译工具(VB Decompiler Pro)可以恢复众多伪代码指令,但要反编译成源代码还是有很多工作需要完成, 反编译器将帮助您更轻松的分析程序算法以及部分恢复源代码。 如果一个程序被编译成native code, 从机器码恢复源代码是几乎不可能的. 但即便是这种情形下VB Decompiler还是可以帮助你分析程序. VB Decompiler包含了一个强大的支持包含MMX和SSE的Pentium Pro指令集的反编译器. 它还包含一个代码分析器, 用于搜索所有API调用,汇编代码中的字符串引用并将结果修改为相应的注释。 加入一个程序被编译成.net汇编,反编译器将恢复所有的托管代码的数据表和模块,并且使用IL反汇编器反汇编所有的方法,函数以及事件。反编译并不需要.NET Framework并且支持所有的32位Windows操作系统。 VB Decompiler也将反编译文件中的所有的图形界面窗体以及控件。出于技术需要,反编译器可能显示所有控件的编译地址。 对于加壳的VB程序,首先需要脱壳后才能正常反编译。 总而言之, VB Decompiler是一款出色的程序分析工具. 尤其是当您不慎丢失源代码并且需要部分恢复原工程的时候。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值