修改指针法破解VB程序-Fast PC Linker-III (8千字)

发布者:Editor
发布于:2001-06-29 21:31

修改指针法破解VB程序
Fast PC Linker-III

作者: 囚童
课题: 解除Fast PC Linker-III传送量限制,清NAG
背景: VB3.0编程
下载:    
工具: TRW2000
   Ultra Edit 32
   FC

Fast PC Linker-III支持基于不同平台(Windows 3.1, 95, 98 和 NT4 WorkStation)的两台PC
之间通过串并口进行高速文件传送.支持全目录和全盘复制.支持长文件名.也支持网络设备及
光驱.Fast PC Linker-III具有自动搜索和优化配置I/O口的功能,又十分小巧,一张软盘就可以
带走.对于那些没有光驱的老式机器和笔记本机,想安装运行大一点的程序有了它可就方便多了.
特别在它之前,由于NT不支持直接电缆连接,从办公室向家里传送MP3之类的大文件,要是其中一
台机不能上网,那可就惨了.有了Fast PC Linker-III,找一台笔记本机,在打印电缆上装一个转
换接头(有关转换接头另文介绍),两下搞定.

Fast PC Linker-III试用版采用传送量限制,试用完规定的传送量(大约25x300MB),程序就停止
工作.倘若正在传送一个大硬盘,刚传了一半就死翘翘,确实让人恼火.

由于必须支持Windows 3.1,Fast PC Linker-III选择VB3.0编程.大家知道,VB程序的特点是既难
跟又难改,这就给破解带来相当的难度.


下面给出用修改指针法破解VB程序的例子,供参考.

将C:\WINDOWS\WIN.INI以1.INI为名做一个备份.
安装Fast PC Linker-III,将安装后的WIN.INI以2.INI为名再做一个备份.
在C:\WINDOWS\COMMAND目录下找到fc.exe,在DOS提示符下键入:

fc 1.ini 2.ini > comp.txt

fc将对安装前后的两个ini文件进行比较,并把比较结果存入comp.txt中.
打开comp.txt,可以看到:

Comparing files 1.INI and 2.ini
****** 1.INI


****** 2.ini

[Disk Safety Info]   ┐
Protection FL3= 25    > FastPCL安装后向WIN.INI中加入的两行
            ┘
******

新加入的两行即试用版赋予用户的初始传送量,其最大值为25节,每节大约300MB.当这一数值用
尽时,即使重新安装,也不能恢复.


启动TRW2000,点OK,TRW2000在屏幕右下角生成一个小图标.右击这个图标,选TRmewTCB.

双击Fast PC Linker-III图标,TRW截获这一新线程.

WIN.INI是WINDOWS启动时调入内存常驻的.
下指令:    S 30:0 LFFFFFFFF 3D 32 35    ;=25
TRW给出:  9B0B6

下指令:    BPM 30:9B0B6+1 R
按F5,程序被TRW截获.
下指令:    BD*  ;清中断.

按F5数次,程序来到:

014F:5A96 CLD   
014F:5A97 PUSH DS
014F:5A98 PUSH ES
014F:5A99 POP  DS
014F:5A9A MOV  SI,DI
014F:5A9C LES  DI,[BP+06]
014F:5A9F MOV  AX,CX
014F:5AA1 REP     MOVSB      ;光标停在这里
014F:5AA3 MOV  BYTE [ES:DI],00
014F:5AA7 POP  DS

下指令:    D DS:SI-1
TRW给出:
00CF:25D7 32 35 0D 0A 0D 0A 0D 0A-0D 0A 00 00 00 00 00 00 25..............

此时若连续下指令: BPM ES:DI-1,通过88C0、96E5可以跟踪这个"25"一直来到:

1B2F:0B43 LODSB 
1B2F:0B44 CMP BYTE [0FB9],00 ;光标停在这里
1B2F:0B49 JZ  0B5B
1B2F:0B4B CMP AL,20
1B2F:0B4D JZ  0B3D
1B2F:0B4F CMP AL,09
1B2F:0B51 JZ  0B3D

下指令:    D DS:SI-1
TRW给出:
0F1F:779A 32 35 00 FF 9C 00 C0 77-A8 91 47 35 04 00 2A 00 25.?wG5..*.

如果有耐心继续跟踪,将会发现程序将ASCII码"25"转换为16进制码H19后,又将16进制码转换为
80Bit的浮点数,自76A2送入浮点系统进行繁杂的浮点运算,然后来到:

372F:0F67 SUB  SP,BYTE +02
372F:0F6A MOV  BX,SP
372F:0F6C NOP   
372F:0F6D FISTP WORD [SS:BX]    ;关键!
372F:0F70 INT  3D
372F:0F72 LODSW 
372F:0F74 JMP  AX

利用F6D处的指令FISTP,将预放在浮点堆栈内的80Bit运算结果,恢复成16进制码H19压入当前堆
栈内.接着通过F74处的跳转指令,来到:

3DC7:2D55 LODSW 
3DC7:2D57 XCHG AX,BX
3DC7:2D58 MOV  BX,[BX]
3DC7:2D5A MOV  DS,[SS:1CFA]
3DC7:2D5F POP  WORD [BX]    ;关键!
3DC7:2D61 MOV  DS,[SS:1CF2]
3DC7:2D66 LODSW 
3DC7:2D68 JMP  AX

利用2D5F处的弹出指令,将16进制码H19从栈顶弹出到变量寄存器中.

下指令:    ? BX
TRW给出:
DEC = 32106
HEX = 7D6A

试着用E命令修改DS:7D6A.
置入0,程序在后面的运行中将弹出程序失效的提示窗口;置入H63(D99),试用版传输量将大大提
升.

但是,上面提到的全部数据传输和处理过程都是在vbrun300.dll中完成的,无法将f6d处改写为例
如MOV [SS:BX],H63 这样的指令.

分析上面给出的F67和2D55两节指令,可以看出VB代码结构的明显特征:指针ES:SI指向一个混合
装有指令入口和数据的指针列表,节首的装载指令通过指针列表下载数据;节尾的装载指令通过
指针列表下载新的指令入口.这样就将事先按死顺序编好在VB运行库里的指令代码和用户数据通
过指针列表盘活了.

把上面的过程整理一下,如下表:

节序    ①    ②    ③       ④
指令指针  6080   6084   6086      6088
指令入口  3234   76A2   F67      2D55
数据指针  6082   -     -       -
数据内容  0380   -     -       -
功能    传送数据 浮点处理    浮点栈>当前栈 当前栈>变量寄存器

如果能舍去浮点处理,将数据如H63(D99)在节①处直接压入当前堆栈内,在节④处从栈顶弹出到
变量寄存器中,试用版传输量将提高到可以认为是没有限制了.

在当前指令代码段中找了一下,有下面3节大约可用:


1C2F:2A86 LODSW 
1C2F:2A88 XCHG AX,BX
1C2F:2A89 MOV  BX,[BX]
1C2F:2A8B MOV  DS,[SS:1CFA]
1C2F:2A90 PUSH WORD [BX]
1C2F:2A92 MOV  DS,[SS:1CF2]
1C2F:2A97 LODSW 
1C2F:2A99 JMP  AX


1C2F:2B50 LODSW 
1C2F:2B52 XCHG AX,BX
1C2F:2B53 PUSH WORD [BX]
1C2F:2B55 LODSW 
1C2F:2B57 JMP  AX


1C2F:3834 LODSW 
1C2F:3836 PUSH AX
1C2F:3837 LODSW 
1C2F:3839 JMP  AX

试选⑶,做一个新的指针方案:

节序   ①      ②   ③   ④
指令指针 6080     6084  6086  6088
指令入口 3834     3837  3837  2D55
数据指针 6082     -    -    -
数据内容 0063     -    -    -
功能   数据>当前栈 空运转 空运转 当前栈>变量寄存器

选定TRW的TRnewTCB,重新激活FastPCL,TRW截获它.

下指令:    BPM 30:9B0B7 R
按F5,程序被TRW截获.
下指令:    BD*  ;清中断.
按F12三次,F10六次,来到:

342F:650E PUSH AX  ;光标停在这里
342F:650F CMP  CL,FF
342F:6512 JZ  6515
342F:6514 PUSH CX
342F:6515 OR  SI,SI
342F:6517 JZ  651D
342F:6519 LODSW 
342F:651B JMP  AX

可以看到TRW反汇编窗口下面的横线中央标有VBRUN300(xx)+xxx,指出当前模块名是vbrun300,
括号中是子模块序号,加号后是在模块中的偏移量.
这就是VB3的指针控制域.所谓VB难追,也是指在这个域里.

下指令:    E ES:6080 34 38 63 00 37 38 37 38
按F5.
修改成功.FastPCL右上角的试用版窗口显示剩余传输量为99节.左上角是定购信息窗.

这么大的传输量对于一般用户来讲可以说已经没有什么限制了,故可以进一步尝试将试用版窗
口和定购信息窗去掉.

选定TRW的TRnewTCB,重新激活FastPCL,TRW截获它.

下指令:    BPX ACCESSRESOURCE
按F5十七次,按F12两次,F10一直来到:

3FEF:010D CALL 063C
3FEF:0112 MOV  SI,AX    ;光标停在这里
3FEF:0114 OR  SI,AX
3FEF:0116 JZ  0120
3FEF:0118 MOV  AX,SI
3FEF:011A POP  SI
3FEF:011B POP  DI
3FEF:011C LEAVE 
3FEF:011D RET  0A
3FEF:0120 LEA  AX,[BP-04]
3FEF:0123 PUSH SS
3FEF:0124 PUSH AX
3FEF:0125 MOV  ES,[1F3A]
3FEF:0129 LEA  BX,[DI+19]
3FEF:012C PUSH WORD [ES:BX]
3FEF:012F CALL 0482     ;按F8跟进去
3FEF:0134 MOV  SI,AX

下指令:    BD*  ;清中断.

接着一直按F10,来到:

1BD7:0493 CALL 07C0  ;按F8跟进去
1BD7:0498 MOV  SI,AX
1BD7:049A OR  SI,AX
1BD7:049C JZ  04A6
1BD7:049E MOV  AX,SI
1BD7:04A0 POP  SI
1BD7:04A1 POP  DI
1BD7:04A2 LEAVE 
1BD7:04A3 RETF 06

接着一直按F10,来到:

35C7:08F8 CALL `KERNEL!_LREAD`
35C7:08FD MOV  [BP-06],AX   ;光标停在这里
35C7:0900 CMP  AX,FFFF
35C7:0903 JNZ  0908
35C7:0905 JMP  09A8
35C7:0908 MOV  ES,[1F42]

下指令:    DW ES:26A
获得段地址①.

下指令:    DB 段地址①:B19
数据窗口显示:

35AF:0B19 04 00 00 00 00 05 2D 00-DE 03 9E 07 85 02 12 07 ......-.???..
35AF:0B29 00 14 02 1E FF FF 00 03-65 00 00 80 0A 12 00 00 ......e......
35AF:0B39 01 FF 00 22 41 6C 73 6F-20 4C 6F 67 20 4E 65 74 .."Also Log Net

这是定购窗口的VB显示参数,包括窗口位置、字体、字体尺寸、前景、背景、效果等.
在它的前面是将要显示的字串.

下指令:    DB 段地址①:CB8
数据窗口显示:

35AF:0CB8 03 00 00 FF 00 04 FF FF-FF 00 05 BB 17 DE 03 EA .......???
35AF:0CC8 06 85 02 0C 0D 4D 53 20-53 61 6E 73 20 53 65 72 .?..MS Sans Ser

这是试用版窗口的VB显示参数.

下指令:    E 段地址①:B21 0 0 0 0 A 0
下指令:    E 段地址①:CBE 0 0 0 0 5 2D 0 0 0 0 0 A 0

按F5.
修改成功.两个窗口均被清除.

使用Ultra Edit 32,按下面的方法做最后的修改:

34 32 80 03 A2 76 67 0F 55
-- 38 63 00 37 38 37 38 --

17 DE 03 EA 06 85 02 OC
-- 00 00 00 00 0A 00 --

00 DE 03 9E 07 85 02 12
-- 00 00 00 00 0A 00 --

试运行.哇,成功!
VB是可以修改的!

忙了半天,只是为了说明VB是可以修改的.
其实按下面的方法修改,只要修改一处,效果是一样的:

34 32 80 03 A2 76 67 0F 55
-- 38 FF FF 37 38 37 38 --

俨然一个正版.

倘若只是想用一用软件,或想偷个懒,或者缺少工具,只要用Notepad打开Win.ini,在Protection
FL3= 25一行的前面加上一个分号";",然后存盘,就万事大吉了.


声明:该文观点仅代表作者本人,转载请注明来自看雪