|
* U0 O6 T% S: B+ b " ?% u. f. q4 P/ k, Y+ v
软件试用次数的限制有很多种方法,其关键是把次数这个值存储在哪里。本文介绍一种方法,通过改变文件 的时间来存储试用次数,从而限制软 件的试用。 % P2 E9 G/ d5 a* r
一、通过改变文件时间来限制软件的试用次数 . Z2 l0 l/ e" A1 o1 p4 z6 u7 S
在MS-DOS中,文件的时间是 通过一个16位的值来保存的,位 15~11用来保存小时数,位10~5用 来保存分钟数,位4~0用来保存秒钟 数。这个16位的值正好可以被我们用来保存试用次数。例如,在下面的示例 程序中,笔者就使用了保存分钟数的 位来保存试用次数。运行一下示例程序,我们可以看到,只是文件时间的分 钟数加了1,一般人很难察觉,这种方 法有比较好的隐蔽性。 8 t. |" b; q5 b+ u
二、示例程序中所涉及的中断 7 \8 V! \! v9 ]# U
1.中断21H的功能3DH
7 |1 K4 b) O1 x 用途:打开文件用于读。写或补 充。
; f J9 L% a& p- ^: o! u 调用寄存器:AH=3DH,AL=00H,DS X=文件名;
+ T) w5 k( }! k; X# R6 ?- ` 返回寄存器:CF 复位--成功,AX=文件把柄。
) V- U/ Q4 e+ G; x) L& ` CF 置位--出错,AX=错误代码。
: P3 Q9 f E8 o5 Y; ? 2.中断21H的功能3EH ( x/ F' ?! Z4 I
用途:强迫清除所有缓冲区,更新目录,使文件把 柄无效。
+ z% n: G8 f% |5 ]0 @$ y+ h3 y 调用寄存器:AH=3EH,BX=文件把柄;
. t7 N" Z( g2 _' s3 Z+ A& \% o9 P, B 返回寄存器:CF 复位--成功,AX被破坏, 5 s6 \: U7 A' a4 Q5 R9 `
CF 置位--出错,AX=错误代码。
* F% B+ Z, }5 V 3.中断21H的功能57H、子功能00H
2 z4 e/ e4 c7 d% @, S4 z I 用途:读出文件被最后修改的日期和时间。
6 j0 c4 F/ _2 ~% x2 A 调用寄存器:AX=5700H,BX=文件把柄;
7 g6 y( ?6 T& K* J 返回寄存器:CF 复位--成功,CX=文件时间, DX=文件日期,
( V% l5 H# N( X) U CF 置位--出错,AX=错误代码。
4 E- k! s9 F; S9 Z9 k% V! W- t4 v/ l3 V 4。中断21H的功能57H、子功能01H 0 r+ _, e) f0 _/ N- R
用途:将文件最后被修改过的日期和时间信息变 成指定值。
( n5 D- j* C' x u 调用寄存器:AX=5701H,BX=文件把柄,CX= 新时间,DX=新日期; k1 B, m9 x M1 a1 l
返回寄存器:CF 复位--成功, $ x4 U& f+ d6 m. d, x# b2 M7 T
CF 置位--出错,AX=错误代码。
2 k3 ~6 K( ]! D* O三、示例程序 ( ^6 q/ r% o) y& B9 j, p+ Q
#include <sidio.h> . _; z: f8 b; v, Y( Z- N
#include <dos.h> - c$ f. x, t2 X& m% L2 ~
#include <conio.h> - P9 n+ m) r1 B
int count( ) & R8 W$ \4 T5 R! @" B* {& E% z
{ ' H! g3 z/ C& d& h
union REGS inregs,outregs; 4 |# N( Z, H4 o9 F
strut SREGS segs;
+ n/ R9 K7 Z+ j! } unsigned handle;
* S2 Y" O% m4 {; n/ U unsigned times; / F- I& @6 ]; d7 ~! C7 B
/ * 打开文件 * /
5 W- H4 v- K% V4 ]$ e( [ inregs.h.ah =0x3d; # v* K8 P! B6 P, K: `9 F* T$ f
inregs.h.al =0; 5 w( P: E" p! g( h4 j
scgread(& segs);
! P6 U! r1 }( b, Y! ^- M inregs.x.dx ="test.exe";
m# o) L: S B+ k" O intdosx(& inregs, & outregs, & segs); ! n q1 j" i1 x# g) f9 D" N, R2 v
if(outregs.x.cflag) return(0);
6 c0 I0 ?' }% [& V) F# J0 Y7 Q8 d else
" f# l" l, V6 G# i {
$ w0 w$ A+ l g( h/ ]- |) J* W / * 读取文件日期时间 * / p% I0 N/ D4 U0 t4 ]+ t' a
handle = Outregs.x.ax;
5 D* h+ f, y* M g" Z) J6 p& n" ] inregs.x.ax = 0x5700;
- _( J5 ~3 T7 A7 A inregs.x.bx = handle; 4 n( q) [3 x4 k; g5 J1 M; r
intdosx(& inregs, & outregs, &segs);
' q& P' q( m5 c0 ? times = (outregs.x.cx &0x7e0)> > 5; 4 j/ y7 a* @. O6 @) A% O. H
if(times <40)/ * 试用次数可以通过改变此处的'40'来实现 * /
6 P, v8 ?$ J" g, [- {# l( o {
, n$ } f0 W1 Y5 W, m- M- q, Q2 i inregs.x.ax = 0x5701; % ]# o- h g6 a1 X7 k% L9 g* M/ Z8 \
inregs.x.bx = handle;
# f5 e# h& Q9 @9 o' m. f inregs.x.cx = outregs.x.cx + 0x20; / * 试用次数计数 * / * B6 w3 \* S' d
inregs.x.dx = outregs.x.dx; - ^8 S A3 A$ t- X- V
intdosx(& inregs, & outregs, & segs); / * 重置日期时间 * / , g5 I; s) T0 B6 M1 Z6 q0 Q
return(2);
- Z4 p J0 |- G; r6 { ~2 m } 4 ?9 x! g& I% k
else return(1);
8 n( p; m" m7 ?( U / * 关闭文件 * /
! q, f; f. j+ s* d6 K M3 ^9 O2 ]3 k8 M' Y inregs.h.ah = 0x3e; ; q6 c u, b# i# n9 @
inregs.x.bx = handle; 4 g# B/ K' Z, ~/ ?3 j# b1 P
intdosx(& inregs, & outregs, & segs);
, q6 F+ b9 d0 M3 ]$ n" T6 z( L; |/ X }
, k# d j/ e6 f5 w}
* ~- z, E4 T; h. V5 bmain()
. j. ^+ H5 T/ { ?{
9 v1 S$ G2 v0 O int flag; . I4 L; w m( w$ _$ ]
flag = count();
8 D7 }, ?) T5 l% X5 p5 h* C if(flag==0) printf("此软件为试用版,请勿任意修改!\ n");
1 M1 d" B! a* ~* F6 Z# R; m& P8 S- ~ if(flag==1) printf("此软件为试用版,您的试用次数已满!\n");
" r# A+ R& N: y, `* N8 k9 c* g if(flag==2) printf("此软件为试用版,欢迎试用!\n");
2 R! |/ k7 u7 S1 L0 Y; H} & \: O7 B* v1 C
|