📄 硬盘.txt
字号:
当我学习从DOS转向WINDOWS MASM32 时,曾在一些BBS上,提问过如何在Win下读写硬盘扇区,
也看了其他人提出的类似问题,但不知是出于何种原因,高手们都是闪烁其词,或让你去写VXD、
或提示你int_31的用法,就是不愿意直面问题。
下面是我在DOS下摸索出而在Win下实现的例子。没有复杂的过程,现将此贴出,不知妥否。
;******************************
; 03-3-30 23:17
; 实验:直接读写硬盘
; 例一:在Ring0环境下,读出硬盘的主引导扇区
;
; 例二:在Ring0环境下,向硬盘写入数据
;******************************
.586P
.MODEL FLAT, STDCALL
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
GDTR df 0 ; This will receive the contents of the IDTR
; register
CallPtr dd 00h ; As we're using the first descriptor (8) and
dw 0Fh ; its located in the LDT and the privilege level
; is 3, our selector will be 000Fh.
; That is because the low-order two bits of the
; selector are the privilege level, and the 3rd
; bit is set if the selector is in the LDT.
OurGate dw 0 ; Offset low-order word
dw 028h ; Segment selector
dw 0EC00h ;
dw 0 ; Offset high-order word
;----------------------------------------------------------------
param db 0,1,0,0,0
db 0e0h
db 0c4h
ASCII_ db '0123456789ABCDEF'
byte_ dd 200h
Caption db 'Windows 9x绝对磁盘读写,第0扇区',0
.data?
Buffer db 200h dup(?)
ShowText db 200h*3 dup (?)
;----------------------------------------------------------------
.code
Start:
mov eax, offset Ring0Proc
mov [OurGate], ax ; Put the offset words
shr eax, 16 ; into our descriptor
mov [OurGate+6], ax
xor eax, eax
sgdt fword ptr GDTR
mov ebx, dword ptr [GDTR+2] ; load GDT Base Address
sldt ax
add ebx, eax ; Address of the LDT descriptor in ebx
mov al, [ebx+4] ; Load the base address
mov ah, [ebx+7] ; of the LDT itself into
shl eax, 16 ; eax, refer to your pmode
mov ax, [ebx+2] ; manual for details
add eax, 8 ; Skip NULL Descriptor
mov edi, eax
mov esi, offset OurGate
movsd ; Move our custom callgate
movsd ; into the LDT
call fword ptr [CallPtr] ; Execute the Ring0 Procedure
xor eax, eax ; Clean up the LDT
sub edi, 8 ; edi之值跟随在先前的 movsd 指令后。
stosd
stosd
nop
;**********************************************
call ShowBuffer
invoke MessageBoxA,NULL,offset ShowText,offset Caption,MB_OK
INVOKE ExitProcess,NULL
;**********************************************
ShowBuffer proc
cld
lea esi, Buffer
lea edi, ShowText
mov ebx,offset ASCII_
xor edx,edx
xor ecx,ecx
compute:
xor eax,eax
cmp edx,byte_
jnc end_
lodsb
push eax
shr eax,4
mov al,[ebx+eax]
stosb
pop eax
and eax,0fH
mov al,[ebx+eax]
mov ah,' '
stosw
inc ecx
cmp ecx,16
jnz compute
add edx,ecx
xor ecx,ecx
mov byte ptr[edi-1],0dh
jmp compute
end_:
ret
ShowBuffer endp
;**********************************************
Ring0Proc PROC
;------------------------------------------------------
pushad
mov al,[param+5]
mov dx,1f6h
out dx,al
call delay
mov ecx,6
lea esi,param
mov dx,1f1h
outp: lodsb
out dx,al
inc dx
loop outp
nop
call delay
lodsb
out dx,al
test_: in al,dx
cmp al,58h
jnz test_
xor eax,eax
mov ecx,80h
mov al,[param+1]
mul cx
mov ecx,eax
lea edi,Buffer
mov dx,1f0h
rep insd
nop
popad
xor eax,eax
retf
delay:
mov ecx,1000h
mov dx,1f7h
n1: in al,dx
cmp al,50h
jz n2
loop n1
mov eax,1
n2: ret
Ring0Proc ENDP
;**********************************************
end Start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -