用户名: 密码: 验证码: gdcode 注册

仿FDISK及PQMAGIC列出分区逻辑盘符的prw.asm实现

时间:2007-06-15 来源: 作者: 【字体: 减小 增大点击: 收藏 | 投稿
  
仿98(DOS7.1)的F$.EXE(>512M模式运行),P_QUEST的P$.EXE

本文基于486DX2,主板,可带primary(启动)/secondary控制IDE器2,中断14/15,每个IDE,可带master(启动,电缆中)/slave(缆端)(跳线ds插/空)2通道,每通道,可带1台硬盘驱动器,每驱动器,可带1块NORMAL,LBA,LARGE模式的IDE硬盘.

DOS,98对硬盘,先按IDE,后按m/s,依次编号,不编闲置通道.例如,有3块盘,块1,2在pri_m/s上,块3在sec_cs上,此3块,编为80h~82h.

开机盘的IDE及通道,由BIOS的BOOTSEQ指定.

(1)DOS/98的读写F16/32格式的位置X的Y个连续扇区的BIOS中断13h参数:
ah的2/3指明读/写,al的低6位指明Y,es:bx指向内存buf首,cl的低6位指明X的扇号sector,最小1,ch,左拼cl第6,7位,齐指X的柱面号cylinder,最小0,dh指明磁头号head,最小0,dl指明软硬盘编号.

IDE原有的NORMAL,BIOS限定柱面数1024,磁头数16,扇区数63,每扇512字节,相乘=容量528MB.用作cmos_chs(cylinder:head:sector)立体寻扇.

LBA,仅磁头数异达255,容量8.4GB 财管家园 fs119.net

LARGE,柱面数>1024,磁头数16,控制器做柱面数/2,磁头数*2,以适13h.容量2048*16*63*512=1G

周边设定:Block模式加速,PIO(并行I/O接口)模式,影响rate

(2)针对LBA的扩展13h线性64位lba寻扇:

chs转时,lba=c*sectors_per_cylinderh*sectors_per_track(s-1)
其中,sectors_per_cylinder为每柱面扇数,sectors_per_track为每磁道扇数,因s从1编号,要减1.

互转,见"(7)文"的chs2lba,lba2chs.

利用extblk块:

extblkdb16;块的字节数(含此字节)
db0
sec_totdw1指明Y个扇区
buf_offdw0;内存buf偏移
buf_segdw0;buf段值
lbaldw0;lba低双字低字
lbahdw0;lba低双字高字
dd0;lba高双字

读/写时,ah=42h/43h,多ds:si指向extblk

扩展i13的BIOS支持性(柱数<1024,先用chs),及导出硬盘柱数,头数,每道扇数,算法见"(7)文"的h_geo

(3)硬盘分区:

每硬盘,最多划为DOS主分区,DOS扩展分区,非DOS分区之1的4区,述于16字节/区的64字节分区表(dpt): 财软联盟,fs119.net

bootONdb080H/0,是活跃/不活跃.
db?分区启动chs的头号
dw?低6位:扇区,低第6,7位与高字节,'齐指'柱面号
volumedb0分区标识值
db?结束chs
dw?
Frontdd0此分区之前(称隐藏)扇区数.INT_25H_dx=1,是在其后读逻辑首扇
Indd0此分区所含扇区数

MBR(F$制的1扇盘主引导记录,软盘0:0:1,硬盘DOS分区的首扇,即INT_25H_扇号dx=1),转cpu给Format.com制的驻有OS的活跃主分区引导记录(OBR).

主分区的保留区(引导扇区PBS囿其内,软盘仅藏1区)之后,常是2份FAT,再后,是根目录.

PBS片断:

0~2:JMP引导程序
3~0AH:厂,sys_ver
(BPB首)0BH~0CH:每扇bytes
0DH:每簇扇数
0EH~0FH:保留区扇数
10H:FAT份数
11H~12H:F16根目录32字节项的数目,F32:0.
13H~14H:软盘,32M内硬盘:分区总扇数
15H:介质,软盘:F0H,硬盘:F8H
16H~17H:软盘,32M内硬盘:每FAT占用扇
18H~19H:每道扇数
1AH~1BH:磁头数
1CH~1FH:此分区之前隐藏扇数
20H~23H:32M外硬盘:分区总扇数 财 管家园 fs119.net
24H~27H:32M外硬盘:每FAT占用扇
40H:磁盘BIOS,1st硬盘:80H,软盘:0
47H~51H:vol
52H~59H:file_sys

软盘6.22的io.sys,最先分得簇,如目录项0基第13字,指向1e,此12BIT的项值,是1f0002,指明01f->020->...->fff链.

分区标识值:

闲置:0
DOS主分区:1,4,6,0bh,0ch,0eh
DOS扩展分区:5,0fh
非DOS分区:其它

笔者用P,对硬盘划分4个DOS主分区,再prw,读此盘(0:0:0)到文件0,用debug,改分区vol值为2,用prw,回写0到(0:0:0),P的分区info页,显vol对应XENIX.

释意,见"(7)文"的FAT

若vol<20H,则高4位,1/0表示隐藏/非隐藏,后缀X,用于扩展i13接口.

各硬盘,均含0:0:1(chs)的1扇MBR,其偏移1be字节,连续存4个分区表.

各硬盘,最多1个DOS扩展分区,其内,能划分称为逻辑分区的数个DOS主分区,非DOS分区.

逻辑分区串成链.例如,vol=5的扩展分区E,先含1个DOS主分区D,后含1个非DOS分区N,则E的Front域值F,是E内的各逻辑分区位置基址,F指明扇区S1,而S1的偏移1be字节,是D的分区表,偏移1ce字节,其vol=0fh,表示DOS扩展分区,其Front域值,加上基址F,指明扇区S2,而S2的偏移1be字节,是N的分区表,偏移1ce字节,其vol=链尾0. 财软.联盟.fs119.net

(4)仿F$及P$,列出分区逻辑盘符:

盘符,C:~Z:列出.用F$,P$,能建数个逻辑分区

分区超过Z:符时,F$照列,P$不赋盘符,prw赋^符

活跃分区数>1时,引导错,但F$及prw照列,P$显错

F$,P$,依vol域,查以下3步,每步,查80h至83h:

(1)查DOS主分区
若是,则查bootON是否80H,若是,此分区就占1个逻辑盘符,若无活跃主分区,表项在MBR首现的主分区,就占1个逻辑盘符.

例如,3硬盘,80h的第1,3分区是主分区,但第3分区活跃,则第3分区占盘符C:.而81h,只含DOS扩展分区,其上,含1个DOS主分区及1个非DOS分区;82h的第2,4分区是不活跃主分区,则最先在MBR中出现的第2分区,占盘符D:

(2)查DOS扩展分区
按逻辑分区在链上次序,查它是否DOS主分区,若是,就占盘符,81h的DOS扩展分区上的DOS主分区,占盘符E:

(3)查未占过盘符的DOS主分区及非DOS分区
按MBR中,分区表项出现的先后次序,查分区是否DOS主分区,若是,且它未占过盘符,就占盘符.80h的第1分区,占盘符F:,82h的第4分区,占盘符G: 财.软联盟.fs119.net

F$,P$,prw,不给非DOS分区赋盘符,仅显In值.

(5)例:

笔者486,在pri_ds上,装ST32140A驱动器(2012M),在sec_ds上,装QUANTUM(514M).

(5.1)80h上,现有vol=6的DOS活跃主分区(FAT16B,1299M),vol=6的主分区(F16B,39.4M),vol=17h的非DOS分区(HiddenNTFS,574.9M),vol=5的扩展分区,其托4个逻辑分区,按链上次序是:

vol=0bh的DOS主分区(F32,35.4M),vol=83h的非DOS分区(LINUX_Ext2,19.7M),vol=1的DOS主分区(Unfmt,3.9M),vol=6的主分区(41.3M)

(5.2)81h上,现有vol=82h的非DOS分区(L_Swap,3M),vol=11h的非DOS分区(Unfmt,3M),vol=6的活跃主分区(472.5M),vol=0fh的扩展分区,其托4个逻辑分区,按链上次序:

vol=82h的非DOS分区(L_Swap,10.8M),vol=1的主分区(F12,8.8M),vol=7的非DOS分区(N,9,8M),vol=1的主分区(U,7.8M).

从98软盘启动,F$,P$,列出这些分区的盘符及容:

C:1299M
D;472.5M
E:35.4M
F:3.9M
G:41.3M
J:39.4M
H:8.8M
I:7.8M

(6)prw功能

命令行是prw.exe[foo1]

财.软联盟.fs119.net



初见:
b(pb),p(arti),r(eadsectofoo/stdout),w(ritefootosec),v(xdw)

命令键b,p,r,w,v:

(6.1)b,显subBPB
(6.2)p,显分区盘编号,逻辑盘符,BootON值,vol值,Front值,In值,例如

80,C:,Boot:80,FAT:06,Front:0000003f,In:00101661

(6.3)r,读软硬盘内容到新建foo,或stdout
(6.4)wv,写已存foo到软硬盘.v多依VxD,胜v86禁13h写.算法,见"(8)论V86下,直寻硬盘扇区,只能靠VxD"

rwv,用旧FCB式,读源F16,F32,写F16.逐扇有结果I/O,直至出错或事成.

欲读80h的MBR到文件b:d,先发:

prwb:d

再答r,界面:

drv(00~01,80~83)80
0~cyl(0029)
0~hd(1f)
1~sec(3f)
0~lba(00014abf)
c(hs),l(ba)l
0~lba(00014abf)00000000
0~cyl(0000)
0~hd(00)
1~sec(01)
0~lba(00000000)
1~total(ffff)0001

事成/中止,d长度512/0.

v86时,改向buf文符到F32的文件g,可发prwc:u>g

(7)文
NIBSZ=8;8个hex数

nibascmacro
localnq

addal,48
cmpal,1048
jbnq
addal,97-48-10 财管家,园,fs119.net
nq:
endm

alascmacro
movah,al
andal,15
nibasc
xchgah,al
rept4
shral,1高nibble
endm
nibasc
stosw
endm

axascmacro
pushax
moval,ah转ah
alasc
popax转al
alasc
endm

dsegment
bufdb511dup(0)放MRB.全囿V86页(4k),buf长1023,囿DMA_64k
buf511db0老buf尾

info_szdw26;minszofinfobuf新buf
flagsdw0;flags
cylinders0dw0;numberofcylindersondisk
cylinders1dw0
heads00db0;numberofheadsondisk
heads01db0
heads1dw0
s1track00db0;numberofsectorspertrack
s1track01db0
s1track1dw0
sectorsdq0;numberofsectorsonrequesteddisk
sector_szdw0;numberofbytespersector
db511-26dup(0);新buf

FATdb13,10,'0~0eh:'
db13,10,'?OS,F12/Unfmt,,,F16/U_,EXtend,F16B,NTFS,,,,F32,F32_13X,,F16'
db13,10,'11,14,16,17,1b:(Hidden)'
db13,10,'F12/U_,F16,F16B,N,F32$'

.viewdb'0000,cx='
viewcxdb'13EX,dx='
viewdxdb'tend'
CRdb13,10,36

extblkdb16,0分区表16字节用
sec_totdw1
buf_offdwbuf;buf偏移
buf_segdwSEGbuf

财管家园,fs119.net


lbaldw0;lba低双字低字
lbahdw0;lba低双字高字
dd0;lba高双字

cmd_pdb'b(pb),p(arti),r(eadsectofoo/stdout),w(ritefootosec),v(xdw)$';rwv用

logi_pdb13,10,'logi_drv(A:=01)$'
subBPBdb13,10,'SV_sec:'
SV_secdb0,'000,FATs:'向foo读
FATsdb'00,sec_per_FAT:'
sec1FATdb'0000$'

drv_pdb13,10,'drv(00~01,80~83)$';扩展i13用
mod_pdb13,10,'c(hs),l(ba)$';dosext,nondos用

db13,10
from80db'8?,'
logidrvdb'C:,Boot:'
Bootdb'?0,FAT:'
volumedb'06,Front:'
Front_hdw?,?又做总扇数
Front_ldb'0000,In:'
In_hdw0,?又做当前扇号
In_ldb'0000$'

cyl_pdb13,10,'0~cyl('
cyl_p1db'????)$'

hd_pdb13,10,'0~hd('
hd_p1db'??)$'

sec_pdb13,10,'1~sec('
sec_p1db'??)$'

lba_pdb13,10,'0~lba('
lbah_p1db'????'
lbal_p1db'????)$'

total_pdb13,10,'1~total(ffff)$'

scr_pdb'^C,f(ast),n(ext)$'

primkdb1,4,6,11,12,14主分区标识
primksz=$-primk
extmkdb5,15扩展分区标识
extmksz=$-extmk

stk1dwNIBSZ/4dup(0);INnib栈
财,管家园,fs119.net

db32
rowascdb(21)*16dup(32),36

kbddbNIBSZ1;键盘buf
kbd1db67parti用
kbd2dbNIBSZ1dup(0)

fcbdrvdb0
fcbnamdb8dup(32)
fcbextdb3dup(32)

fcbblkdw0
fcbrszdw512

fcbszdb4dup(4)已占分区表号,4硬盘*1字节,parti用
fcbdatdw0

fcbdos1db10dup(0)
fcbrnodb0

entrylabeldword;fcbrand
entrydidw0
entryesdw0

media_hdb0;头数
media_cdw0;柱数
s1cyldw0;扇数/柱
s1trackdb0;扇数/道

drvdb0;输入
hddb0
cyldw0
secdb0

hextbldb'0123456789abcdef'
dends

csegment
assumecs:c,ds:d,es:d

@procfar

pushds;为exe返回
xorax,ax压cd20的psp:0
pushax

movax,d
moves,ax

cmpbyteptrds:[5dh],32缺foo
je@0

inces:SV_sec
movcx,183
movsi,5chsh复制盘符大写8.3名到5ch
leadi,fcbdrv
repmovsbes:di=ds:si的盘符8.3

@0:movds,ax

movah,9
leadx,cmd_p;问命令
int21h

movah,1
int21h

cmpal,'b'
jeb
jmpp

b:movkbd,21
leadx,logi_p问逻辑盘

财.管家园.fs119.net


CallINnib

movax,440dh
movcx,860h传统及扩展13,共享BPB前12字节
leadx,buf
int21h

movax,wordptrbuf[73]
leadi,SV_sec
axasc

moval,buf[75]
leadi,FATs
alasc

movax,wordptrbuf[711]
orax,ax
jnzbo

movax,wordptrbuf[725]

bo:leadi,sec1FAT
axasc

movah,9
leadx,subBPB
int21h
ret

p:cmpal,'p'
jner

movah,9
leadx,FAT
int21h

leabx,buf

movdx,80h扩展i13,可兼容传统
Calldospri
movmod_p,dl

movdl,80h
Calldosext

movlbal,0
movlbah,0

movdl,80h
Callnondos
ret

r:movcmd_p,al

cmpal,'r'
jerwv

cmpal,'w'
jerwv

cmpal,'v'
jev

ret

v:movax,1684h;func
movbx,3180h;接口ID
int2fh

movax,es;es:di=V86口cs:ip
orax,di
jnzv1
retes,di全0,失败

v1:moventrydi,di
moventryes,es
pushds
popes

rwv:movkbd,21
leadx,drv_p问磁盘
CallINnib

movdrv,bl
movdl,bl驱动器

testbl,80h 财管家园,fs119.net
jnerwv1

xordh,dh头
Callf_geo
jmprwv2

rwv1:Callh_geo

rwv2:testmedia_h,255
jnerwv3
ret

rwv3:muls1cyl

subax,1;lba始于0,可写CF
sbbdx,0

movlbal,ax
movlbah,dx

Calllba2chs
Callrng

movah,9;问寻扇
leadx,mod_p
int21h

movah,1
int21h
cmpal,'c'
jerwv4

movkbd,81
leadx,lba_p
callINnib;问lbah,lbal
movlbal,bx

movax,stk1
movlbah,ax

Calllba2chs
jmprwv5

rwv4:movkbd,41
leadx,cyl_p;问柱面号
CallINnib
movcyl,bx

movkbd,21
leadx,hd_p;问头号
CallINnib
movhd,bl

movkbd,21
leadx,sec_p;问扇号
CallINnib
movsec,bl

Callchs2lba

rwv5:Callrng;显出立体,线性值

movkbd,41
leadx,total_p;问总计
CallINnib

movFront_h,bx

leadx,fcbdrv;指向fcb

movah,15;openforw,v
cmpcmd_p,'r'
jnerw1

testSV_sec,1向foo读
jzrw2

movah,16h;createortruncforr,软盘启动,拒存取F32盘
rw1:int21h改fcbdrv为3=C
财.软联盟.fs119.net


oral,alal为0,成功
jnzrw7

movfcbrsz,512重置

rw2:movax,600hal=clr
movbx,700hbl=page
xorcx,cx
movdx,184fh25*80
int10hcursorgrow0,24

movah,1ah;DTA
leadx,buf
movbx,dx;I/O数据区
int21h

rw3:testFront_h,65535
jzrw6

cmpcmd_p,'r'
jnerw4

movax,201h
movdl,drv
Callrw1by1
jerw6

Callscr

testSV_sec,1;向foo读
jzrw5

movah,15h;强制write
leadx,fcbdrv
int21h
jmprw5

rw4:movah,14h;read
leadx,fcbdrv
int21h

Callscr

movax,301h
movdl,drv
Callrw1by1
jerw8;出错,关闭

rw5:addlbal,1
adclbah,0

incIn_h
decFront_h
jmprw3

rw6:testSV_sec,1向foo读
jnzrw8

rw7:ret

rw8:movah,16;close
leadx,fcbdrv
int21h

ret
@endp

dospriproc;统计硬盘数,查DOS主分区
dospri0:cmpdl,80h4
jedospri7

movax,201h;测硬盘
movcx,1
int13h
jcdospri7

movbp,4*16

xorsi,si;分区表,占4*16字节
dospri1:cmpsi,4*16 财软联 盟 fs119.net
jedospri4

moval,buf[1behsi4]取vol
movcx,primksz是主分区?
leadi,primk
repnescasb
jnedospri3

testbyteptrbuf[1behsi],80h;取BootON
jnzdospri2

cmpbp,4*16
jnzdospri3

dospri2:movbp,si;暂选首现主分区
jnzdospri5

dospri3:Addsi,16
jmpdospri1

dospri4:cmpbp,4*16
jedospri6

dospri5:movsi,dx
subsi,80h

movax,bp
divextblk
movfcbsz[si],al标占分区表项号

moval,kbd1
movlogidrv,al
inckbd1

CallShow

dospri6:incdl;读下块硬盘
jmpdospri0

dospri7:ret
dospriendp

pri_nonproc
movlogidrv,32

movcx,primksz
leadi,primk
repnescasb
jnenon;不赋非DOS分区盘符

movlogidrv,94^符

moval,kbd1
cmpal,'Z'
janon

movlogidrv,al
inckbd1

non:CallShow
ret
pri_nonendp

dosextproc查DOS扩展分区
dosext0:cmpdl,mod_p
jedosext4

movax,201h
movcx,1
int13h

xorbp,bp
dosext1:cmpbp,4*16
jedosext3

moval,buf[1behbp4]

财,软联盟,fs119.net


movcx,extmksz是扩展分区?
leadi,extmk
repnescasb
jnedosext2

pushbx
pushdx
Callh_geo
popdx
popbx

movax,wordptrbuf[1behbp8];Frontlow
moventrydi,ax基址
movlbal,ax

movax,wordptrbuf[1behbp10];Fronthigh
moventryes,ax
movlbah,ax

xorbp,bp;为show
Callchain
jmpdosext3

dosext2:Addbp,16
jmpdosext1

dosext3:incdl
jmpdosext0

dosext4:ret
dosextendp

h_geoproc
movah,41h
movbx,55aah;测BIOS支持i13_X
int13h
jch_geoo

cmpbx,0aa55h再核
jneh_geoo

testcx,1;支持41~44,47~48第1子集?
jzh_geoo

movah,48h取尺寸
leasi,info_sz
int13h

moval,heads00;头数
oral,al
jzh_geoo无效info包

movmedia_h,al
incdrv_p启扩展

movah,s1track00;每道扇数
movs1track,ah

mulah
movs1cyl,ax每柱面扇数

movax,cylinders0;柱面数
movmedia_c,ax
ret

h_geoo:movah,8取尺寸
int13h
jch_geoq

incdh

moval,dh
movmedia_h,al;头数

财管家.园.fs119.net



movs1track,cl
ands1track,63每道扇数

muls1track
movs1cyl,ax;每柱面扇数

xchgch,cl
rolch,1
rolch,1
andch,3

movax,cx
incax
movmedia_c,ax;柱面数

h_geoq:ret
h_geoendp

chainproc;处理链
chain0:movax,201h
Callrw1by1

moval,buf[1beh4]
callpri_non

testbuf[1beh164],255;0,5,15之1
jechain1

movax,wordptrbuf[1beh168]
addax,entrydi;加基址entrydi
movlbal,ax

movax,wordptrbuf[1beh1610]
adcax,entryes;加基址entryes
movlbah,ax

jmpchain0
chain1:ret
chainendp

nondosproc查未占过盘符的DOS主分区及非DOS分区
nondos0:cmpdl,mod_p
jenondos4

movax,201h
movcx,1
int13h

movbp,dx
subbp,80h

moval,fcbsz[bp]取已占分区表号
mulextblk
movfcbdat,ax

xorbp,bp
nondos1:cmpbp,4*16
jenondos3

cmpbp,fcbdat
jenondos2;已占

moval,buf[1behbp4]

testal,255不理闲置分区
jznondos2

movcx,extmksz;略扩展分区

财软 联盟 fs119.net


leadi,extmk
repnescasb
jznondos2

callpri_non

nondos2:Addbp,16
jmpnondos1

nondos3:incdl
jmpnondos0

nondos4:ret
nondosendp

showproc;分区信息
pushdx

anddl,3盘号80~83
adddl,48
movfrom80[1],dl

movBoot,48多数为0
testbuf[1behbp],80h
jzshow0
movBoot,56

show0:moval,buf[1behbp4];显vol
leadi,volume
alasc

movax,wordptrbuf[1behbp8];取Frontlow
addax,lbal;为chain而加
pushf
leadi,Front_l
axasc
movax,wordptrbuf[1behbp10];Fronthigh
popf
adcax,lbah;为chain而加
leadi,Front_h
axasc

movax,wordptrbuf[1behbp12];取Inlow
leadi,In_l
axasc

movax,wordptrbuf[1behbp14];Inhigh
leadi,In_h
axasc

movah,9
leadx,from80
subdx,2
int21h

popdx
ret
Showendp

rw1by1proc读/写1扇
testdrv_p,113=传统
jnzrw1by11

xoral,al不校验写
orah,40h
leasi,extblk;扩展块
jmprw1by12

rw1by11:pushax
pushdx
calllba2chs
popdx

财软 联盟 fs119.net


popax

callcxdh

movwordptrviewcx,cx
movwordptrviewdx,dx

rw1by12:cmpcmd_p,'v'
jerw1by13

int13h
ret遗c

rw1by13:Call[entry]

cmpbp,4096VxD按(8.3)返bp值
jaerw1by14

pushbx

addbx,bp;使bx,bx511在4k内
movbuf_off,bx扩展i13

pushcx
pushsi

leasi,buf511;原buf尾

movdi,si
adddi,bp;新buf尾

std;从后向前移1扇
movcx,256
repmovsw
cld

popsi
popcx

Call[entry]

popbx
movbuf_off,bx扩展i13

cmpbp,4096
rw1by14:jerw1by15

cmpbp,1010h
jnerw1by16

xorah,ah
Call[entry]释它页

rw1by15:cmpal,al置zr
rw1by16:ret

rw1by1endp

f_geoproc
leabx,buf;缓区
movcx,1;0:0:1(chs)引导扇

f_geo0:movax,201h;读1扇
int13h;读11起的bios参数块
jcf_geo0;换盘

moval,[bx26];偏移26:头数
movmedia_h,al

movah,[bx24];偏移24:每道扇数
movs1track,ah

mulah
movs1cyl,ax;每柱面扇数

movax,[bx19];偏移19:总扇数 财软联 盟 fs119.net
xordx,dx;高字

divs1cyl

movmedia_c,ax;柱面数
ret
f_geoendp

rngproc
movax,cyl;当前柱面
leadi,cyl_p1
axasc

moval,hd;当前头
leadi,hd_p1
alasc

moval,sec;当前扇号
leadi,sec_p1
alasc

movax,lbah;当前lba高字
leadi,lbah_p1
axasc

movax,lbal;当前lba低字
leadi,lbal_p1
axasc

movah,9
leadx,cyl_p
int21h

leadx,hd_p
int21h

leadx,sec_p
int21h

leadx,lba_p
int21h

ret
rngendp

scrproc
movcx,16字符数/row

xorsi,si

scr0:pushbx
movah,2
xorbh,bhpg
xordx,dxdh=row
int10h
popbx

leadx,.view

testsi,256
jzscr1
jmpscr3

scr1:movdi,dx
movax,In_h现扇号
axasc

testdrv_p,1
jnzscr2
jmpscr3

scr2:leadi,viewcx
movax,wordptr[di]
axasc

leadi,viewdx
movax,wordptr[di]
axasc

scr3:movah,9
int21h

scr4:movax,si
leadi,stk1
axasc

leabp,rowasc

scr5:moval,[bxsi]
财.管家园.fs119.net


movdi,si
anddi,15

movFAT[di],46

cmpal,32
jbscr6

movFAT[di],al

scr6:movdi,bp
alasc

Addbp,22-1

incsi
testsi,15
jnescr5

movah,9行的hex
leadx,stk1
int21h

pushbx
movah,64行的asc及汉字
movbx,1
leadx,FAT
int21h
popbx

movah,9
leadx,CR
int21h

testsi,255
jescr7
jmpscr4

scr7:cmpscr_p,'f'
jescr8

movah,9
leadx,scr_p
int21h

movah,1;按1键
int21h

cmpal,'f'
jnescr8

movscr_p,al

scr8:testsi,511
jescr9
jmpscr0

scr9:ret
screndp

cxdhproc
movdh,hd;头号

movcx,cyl;柱面号
xchgcl,ch

rorcl,1
rorcl,1
andcl,not63

orcl,sec;低6位扇号
ret
cxdhendp

lba2chsproc
movax,lbal
movdx,lbah

divs1cyl;柱面号
movcyl,ax

movax,dx
divs1track

movhd,al;头号
incah
movsec,ah;扇号

ret
lba2chsendp

chs2lbaproc
movax,cyl;柱面号
muls1cyl

财 软联盟 fs119.net



movlbal,ax
movlbah,dx

moval,s1track;每道扇数
mulhd

Addlbal,ax
adclbah,0

moval,sec;此处,低6位扇号
decal
cbw

Addlbal,ax
adclbah,0

ret
chs2lbaendp

INnibproc;kbd限长nib入kbd2.转后入stk1,低字还入bx
INnib0:movah,9
int21h

pushdx
incah;回车才收
leadx,kbd
int21h
popdx

moval,kbd
decal

cmpal,kbd1;实长
jnzINnib0

xorbp,bp
leasi,kbd2
INnib1:lodsb

movcx,16
leadi,hextbl
repnescasb

jnzINnib0
deckbd1

inccx;转'[0-9a-f]'为0~15
subcx,16
negcx

rept4
shlbx,1;bx接收nibble,左入0
endm

orbl,cl

testkbd1,3;已收4个nibble
jnzINnib1

movstk1[bp],bx
addbp,TYPEstk1

testkbd1,NIBSZ*2-1
jnzINnib1
ret
INnibendp

cends
end@

(8)论V86下,直寻硬盘扇区,只能靠VxD

VToolsD建的C级VxD,有读/写DOS分区的R0_ReadAbsoluteDisk/R0_Write...函数.

例如,响应自32位C的W32_DEVICEIOCONTROL事件时,用格式R0_Read...(2,1,0,buf,&w),读相对DOS分区的逻辑扇号是1的分区引导扇区PBS.这时,当前虚拟机hVM,是系统(证于Test_Sys_VM_Handle测事件实参IOCTLPARAMS.dioc_hvm).VxD不改hVM身份. 财.软联盟.fs119.net

又如,响应自16位ASM程序的V86_API_Entry入口调用时,同上,读PBS,这时,hVM是DOS(证于Test_...测入口实参VMHANDLE).

均读PBS含"MSWIN4...".

但VxD,也能在V86下,用Exec_Int(0x13),法如13h,直寻硬盘,如PBS之前MBR.

笔者c.cppa.exe,直读MBR连续5扇.需cfg.sys,隐dev=EMM386

(8.1)用QuickVxD,建C级VxD,设备名=C,设备ID=0x3180,选动态装

选API页StandardAppEntryPoints框Real/V86Mode.体,见(8.3).

选OnSysDynamicDevice的Init及Exit.体中:

选发SHELL_SYSMODAL_Message(Get_Cur_VM_Handle(),MB_SYSTEMMODAL,"m","cap")
必发return(true)

(8.2)写a.asm,汇编时,/DNPAGE=5,指明5扇.读变写,需debug下,改r2w3处的2为3.

VxD查客户这5扇缓区,囿V86空间1页(4K字节)的整体性,未全囿,bp返回<4k的修正量.

IF2
IFNPAGELT1orNPAGEGT8
%OUT0.ERR
ENDIF
ENDIF

dsegment
bufdbNPAGE*512*2-1dup(9);留足修区
entrydd0
dends

csegment
assumecs:c,ds:d

@:movbp,d 财管家.园.fs119.net
movds,bp

movax,1684h功能号
movbx,3180h接口ID
int2fh

movax,eses/di=API_Entry入口段/偏移
orax,di
jz@3;es及di全为零,失败

movwordptr[entry],di
movwordptr[entry2],es

movax,ds设exec_int参数
moves,ax

leabx,bufes:bx,指向缓区首

r2w3:movah,2读80h硬盘MBR处NPAGE扇
moval,NPAGE
movcx,10:0:1(chs)
movdx,128

stdVxD出兰屏,写修
call[entry]

cmpbp,4096VxD按(8.3)返bp值
jae@2

addbx,bp修缓区首址

testah,1查读/写
jz@1此例ah=2,读盘

leasi,buf写入时,从后向前,移NPAGE*256字
addsi,NPAGE*512-1si指向原缓区尾

movdi,si
adddi,bpdi指向新缓区尾

movcx,NPAGE*256
repmovswds:si所指cx字,移到es:di

movcx,1

@1:call[entry]
cmpbp,4096

@2:je@3

cmpbp,1010h
jne@3

xorah,ah;释它页
call[entry]

@3:xorax,ax
moves,ax

movax,[bx1beh]成功/失败,72h矢量=分区表首字/9
moves:[1c8h],ax

财软.联盟.fs119.net


movah,4ch
int21h

cends
end@

(8.3)...V86_API_Entry(VMHANDLEhVM,CLIENT_STRUCT*pRegs)体

DWORDh,t;
CLIENT_STRUCTs;

if(pRegs->CBRS.Client_AH){//2读3写
h=(DWORD)Map_Flat(CLIENT_ES,CLIENT_BX);//h=客户缓区首es:bx的32位线性址
t=hpRegs->CBRS.Client_AL*512-1;//t=尾的线性址

if((h>>12)!=(t>>12)){
pRegs->CWRS.Client_BP=(4096-(h&4095));//首尾未囿同页,bp返客户增bx量
return;
}

if((h>>12)<0x110)//缓区能被V86寻,bp返4096
pRegs->CWRS.Client_BP=4096;
else
if(LinMapIntoV86(h>>12,hVM,0x10,1,0,&t)){
//缓区所在页,成功映入V86第0x10页,bp返0x1010
pRegs->CWRS.Client_BP=0x1010;
h=(16<<12)(h&4095);//由t及偏移,得缓区V86址h
}else{//无页等,bp返0x1110
pRegs->CWRS.Client_BP=0x1110;
return;
}

Save_Client_State(&s);//存reg
Begin_Nest_V86_Exec();//当前虚拟机,能寻V86

pRegs->CRS.Client_ES=(h>>4);//es=址h的段值

财管,家园,fs119.net


pRegs->CRS.Client_EBX=(h&15);//bx=址h的偏移

Exec_Int(0x13);

End_Nest_Exec();//复原
Restore_Client_State(&s);

if(pRegs->CWRS.Client_Flags&1024){//方向,控兰屏
sprintf((char*)s.CBRS.Client_res30,"%x",pRegs->CWRS.Client_BP);
SHELL_SYSMODAL_Message(hVM,MB_SYSTEMMODAL,(char*)s.CBRS.Client_res30,"bp");
}

}else//知bp返0x1010时,客户释它页
MapIntoV86(GetNulPageHandle(),hVM,16,1,0,0);

(8.4)装VxD法

静态:
放C.VXD于c:\windows\system,在c:\windows\system.ini的386Enh,写device=C.VxD,再reboot

动态4法:
用VxD_Loader,选C.VXD
用DriverMonitor,先打开C.VXD,再Start
放C.VXD于c:\windows\system\iosubsys,再reboot

用笔者DOS窗口a的exe

#include

#definepre"\\\\.\\"

main(intac,char*av[]){
char*vxd;
HANDLEh;

if(ac==1)printf("vxd_load?.vxd\n");
else{
vxd=malloc(strlen(pre)strlen(av[1]));
sprintf(vxd,"%s%s",pre,av[1]);

h=CreateFile(vxd,0,0,0,0,FILE_FLAG_DELETE_ON_CLOSE,0); 财管家.园.fs119.net

if(h!=INVALID_HANDLE_VALUE){
printf("Tounload,hitEnter");
getch();
CloseHandle(h);
}
}
}

装C.VXD,事毕,敲回车到窗a,卸此VXD

财,软联盟,fs119.net


文章摘自网络,如有侵权,请与我们联系.
数据统计中!!
上一篇:驻留exe文件
下一篇:5个DOS专用文件的6种io重定向,more实现管道原理

精品课程推荐



用户名: 密码: 匿名? 注册