二、VB dll 常用函数
1 、字符处理函数
2 、警告窗口函数
三、VB字串格式
四、oleaut32.dll 简介
五、Visual Basic 程序比较方法
一、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 |
这样配制好后,重新启动,就可设 VB 运行库中各函数的断点了。
-----------------------------------------------------------------
二、VB dll 常用函数
1 、字符处理函数
MultiByteToWideChar, rtcR8ValFromBstr, WideCharToMultiByte, __vbaStrCmp, __vbaStrComp, __vbaStrCopy, __vbaStrMove, __vbaVarTstNe .
注意:这些函数前的下划线 __ 是由两根短线 _ 组成的,不要弄错。 如果你是 crack VB6 程序,你应在断点前增加 msvbvm60! 。 如: bpx msvbvm60!__vbastrcomp
一些常用字符串函数:
| Val() | 转换字符串为数字 | Rtrim$() | 去除字符串左边空格 |
| Str$() | 转换数字为字符串 | Trim$() | 去除字符串两边空格 |
| Left$() | 按要求从左取字符。例如: Left$(Theodolite, 4) = "Theo" | Asc() | 转换字符为 ANSI 编码 . 例如: Asc("A") = 65 注:65是ASCII码的十进制 |
| Ltrim$() | 去除字符串左边空格例如: Ltrim$ (" Hello ") = "Hello " | Chr$() | 转换 ANSI 编码为字符 . 例如 Chr$(65) = "A" |
| Right$() | 按要求从右取字符 |
几个常用函数简介:
1、 __vbavartstne 进去后在0F04E351你将看到: 下命令:d ebp+0c |
2、 __vbaR8Str 在这行fcomp qword ptr [00401028] Type: DL 00401028 将看到*real* serial #. DL 是显示 Long/real 型,SOFTICE默认时是DB状态。 |
3、 __vbastrcmp :005BDC32 CALL [MSVBVM50!__VbaFreeVar] |
2 、警告窗口函数
rtcBeep, rtcGetPresentDate (time API), rtcMsgBox
--------------------------------------------------------------
三、VB字串格式
在大部分 VB 程序中,我们能用 bpx Hmemcpy 命令设断,但是你将发现自己不久进入 VBRUNxxx.DLL 运行库,很快陷入 Vb dll 中,在大多数情况下,你很难到达其 EXE 文件中的真正比较核心。你通常是依靠字符串的线索来跟踪程序,你们还应记得 VB ( VB4 以上) 程序储存和比较字符是用 wide character 格式(本质是中在各字符间填 0x00)。
The MultiByteToWideChar( ) function maps a character string to a wide-character (Unicode) string. The character string mapped by this function is not necessarily from a multibyte character set.
int MultiByteToWideChar(UINT CodePage, // code page
DWORD dwFlags, // character-type options
LPCSTR lpMultiByteStr, // string to map
int cbMultiByte, // number of bytes in string
LPWSTR lpWideCharStr, // wide-character buffer
int cchWideChar // size of buffer);
如:
原来字符串 : CRACKZ (43h 52h 41h 43h 4Bh 5Ah).
Wide 字符串格式 : C R A C K Z (43h 00h 52h 00h 41h 00h 43h 00h 4Bh 00h 5Ah).
这时在 SOFTICE 下查看内存中的字符串时看到情况有可能是: C R A C K Z
有些情况下应该用 DL (长实型)命令,才能看到正确数字序号。( SOFTICE 默认时为 DB (字节型))
在多数情况下,在 VB 中设置正确断点是较困难的。断点设置好后,尝试输入序列号,运行后,应返回 VBRUNxxx.DLL 里,现在查找寄存器 (EAX & EBX) 中的值,那里放有你输入字符串长度,如果没发现什么,你应按 ctrl+D 再次返回到 VB dll 中另一处 ,继续查看,一直重复。
一但当你在寄存器中发现字符串长度时,你应一步一步注意观察,如果你幸运的话,你会发现输入字符串躺在寄存器或其显示附近内存里。这时你在 SOFTICE 里的数据窗口中用 ALT+ 光标键滚动查找,说不定会发现正确序列号懒洋洋躺在那附近。
---------------------------------------------------------------------
四、oleaut32.dll 简介 (作者:dr0)
破解VB程序时,对vbrun*.dll(VB4、VB3版本)和msvbvm*.dll(VB5、VB6)强调得比较多,实际上VB程序的很多运算是在oleaut32.dll中完成的,这个dll提供了很多对VB中的Variant类型的变量进行操作的函数,主要是一系列VarXXX( ),其中有几个是用来比较字符串和数值的,如下:
Addr:77A11AAE Ord: 176 (00B0h) Name: VarCmp
Addr:77A0E5D1 Ord: 311 (0137h) Name: VarCyCmp
Addr:77A0E5F8 Ord: 312 (0138h) Name: VarCyCmpR8
Addr:77A129CD Ord: 314 (013Ah) Name: VarBstrCmp
Addr:77A12958 Ord: 316 (013Ch) Name: VarR4CmpR8
Addr:77A13697 Ord: 204 (00CCh) Name: VarDecCmp
Addr:77A1298B Ord: 298 (012Ah) Name: VarDecCmpR8
这里有个小程序RAMQuota(www.stepnet.com.au),是用VB6写的,它使用上述函数中的VarBstrCmp( )比较注册码。该函数的关键指令如下:
:77A12A03 8B7D0C mov edi, dword ptr [ebp+0C]
:77A12A06 8B7508 mov esi, dword ptr [ebp+08]
:77A12A09 8B4D10 mov ecx, dword ptr [ebp+10]
:77A12A0C 33C0 xor eax, eax
:77A12A0E F3 repz
:77A12A0F 66A7 cmpsw
:77A12A11 7405 je 77A12A18
:77A12A13 1BC0 sbb eax, eax
:77A12A15 83D8FF sbb eax, FFFFFFFF
:77A12A18 85C0 test eax, eax
:77A12A1A 7F45 jg 77A12A61
:77A12A1C 7D16 jge 77A12A34
:77A12A1E 33C0 xor eax, eax
看来有必要仔细看一下oleaut32.dll
五、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