Rose_zsf
驱动牛犊
驱动牛犊
  • 注册日期2002-07-04
  • 最后登录2004-02-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1802回复:11

驱动中如何读磁盘扇区?

楼主#
更多 发布于:2003-12-01 11:19
我想在2000下读写MBR,需要在Ring0级才可以实现,请问如何实现?
wenzi_1980
驱动牛犊
驱动牛犊
  • 注册日期2003-10-14
  • 最后登录2007-01-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-12-01 11:35
刚刚写了一个
可以到ddk的src\\storage\\class\\disk里去借鉴一下源码
 ;)
Rose_zsf
驱动牛犊
驱动牛犊
  • 注册日期2002-07-04
  • 最后登录2004-02-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-12-01 13:44
那个目录下有那么多文件是哪一个呀?
还有问一个弱智的问题:
mov ax, 201h
mov bx, buffer
mov cx, 1
mov dx, 80h
int 13h
这段代码能在内核中执行吗?
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地板#
发布于:2003-12-01 18:50
2K下读写硬盘扇区很容易,可以参考我以前的代码,通过直接IO饶过MS的驱动,还可以直接读写128GB硬盘中的任一扇区。。。。。。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
QJE
QJE
驱动小牛
驱动小牛
  • 注册日期2001-08-09
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分470分
  • 威望49点
  • 贡献值0点
  • 好评度44点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-12-01 19:11
其实一般的应用程序就可以使用
代码如下
int LogicalSector = 0 ;
LPBYTE buffer = new BYTE[512];
memset(buffer,0,512);

DWORD bytesread ;

HANDLE hDevice;
hDevice = CreateFile(\"\\\\\\\\.\\\\C:\",GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == NULL)
{
MessageBox (\"Failed !\");
return;
}
SetFilePointer (hDevice, (LogicalSector*512), NULL, FILE_BEGIN);
ReadFile ( hDevice,buffer, 512, &bytesread, NULL );
CloseHandle(hDevice);
CFile f;
f.Open(\"a\",CFile::modeCreate|CFile::modeWrite,NULL);
f.Write(buffer,512);
f.Close();

delete [] buffer;
buffer=NULL;

这段代码是读C盘第一个扇区,保存文件
Rose_zsf
驱动牛犊
驱动牛犊
  • 注册日期2002-07-04
  • 最后登录2004-02-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-12-02 08:43
谢谢各位,我已经知道如何读写MBR,现在,我想把我自己的引导程序写入到MBR,MBR中的程序是16位的,而VC++6是32位的编译器,我如何把我自己的引导程序编译成16位的呢?并将其作为数据写入到MBR扇区中?
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
6楼#
发布于:2003-12-02 09:44
一样,把你代码读入缓冲区,然后将其作为数据写入MBR
WriteFile ( hDevice,buffer, 512, &bytesread, NULL );
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
Rose_zsf
驱动牛犊
驱动牛犊
  • 注册日期2002-07-04
  • 最后登录2004-02-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-12-02 10:41
比如说我自己写的MBR程序如下:
xor ax, ax
push ax
pop  cs
push ax
pop  ds
push ax
pop  es
...
...
现我需要将其写入MBR,则我的代码以什么形式存在?怎样写入?
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
8楼#
发布于:2003-12-02 13:17
char buffer[512];
MBR:
xor ax, ax
push ax
pop cs
push ax
pop ds
push ax
pop es
...
...
memcpy(buffer,mbr,512);
or
lea esi,MBR
mov edi,buffer
mov ecx,512
cld
rep movsb
当然如果你想保留分区表,就不用写那么多了。。。。。。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
Rose_zsf
驱动牛犊
驱动牛犊
  • 注册日期2002-07-04
  • 最后登录2004-02-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-12-02 13:42
分区表肯定是需要保存的,我只是想改变它引导的那一部分。
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
10楼#
发布于:2003-12-02 14:49
汇编代码,给你是读的,将20H改30H,IN-》OUT,ESI-》EDI
即可写.
用MASM32编译。。。。。。
.686p
.model flat, stdcall
option casemap :none   ; case sensitive
; #########################################################################
include \\masm32\\include\\windows.inc
include \\masm32\\include\\user32.inc
include \\masm32\\include\\kernel32.inc
include \\masm32\\include\\advapi32.inc
      
includelib \\masm32\\lib\\user32.lib
includelib \\masm32\\lib\\kernel32.lib
includelib \\masm32\\lib\\advapi32.lib
DEBUG = TRUE

HMODULE typedef dword
NTSTATUS typedef dword
PACL typedef dword
PSECURITY_DESCRIPTOR typedef dword

OBJ_INHERIT=2
OBJ_PERMANENT=10h
OBJ_EXCLUSIVE=20h
OBJ_CASE_INSENSITIVE=40h
OBJ_OPENIF=80h
OBJ_OPENLINK =100h
OBJ_KERNEL_HANDLE=200
OBJ_VALID_ATTRIBUTES=3F2h

SE_KERNEL_OBJECT = 6
GRANT_ACCESS =1
NO_INHERITANCE =0
TRUSTEE_IS_NAME=1
TRUSTEE_IS_USER=1
STATUS_SUCCESS =0
STATUS_ACCESS_DENIED =0C0000022h

STATUS_ACCESS_VIOLATION equ 0C0000005h
STATUS_INFO_LENGTH_MISMATCH equ 0C0000004h
SystemModuleInformation               equ 11
PVOID  TYPEDEF DWORD
UNLONG TYPEDEF DWORD
CHAR   TYPEDEF BYTE

UNICODE_STRING struct
   nLength word ?
   MaximumLength word ?
   Buffer dword ?
UNICODE_STRING ends

OBJECT_ATTRIBUTES struct
   nLength dword ?
   RootDirectory HANDLE ?
   ObjectName dword ?;PUNICODE_STRING  
   Attributes dword ?;
   SecurityDescriptor dword ?; PVOID // Points to type SECURITY_DESCRIPTOR
   SecurityQualityOfService dword ?;PVOID  // Points to type SECURITY_QUALITY_OF_SERVICE
OBJECT_ATTRIBUTES ends


TRUSTEE struct
    pMultipleTrustee dword ?;PTRUSTEE                    
    MultipleTrusteeOperation dword ?; MULTIPLE_TRUSTEE_OPERATION  
    TrusteeForm dword ?;TRUSTEE_FORM
    TrusteeType dword ?;TRUSTEE_TYPE                
    ptstrName dword ?;LPTSTR                      
TRUSTEE ends


EXPLICIT_ACCESS  struct
    grfAccessPermissions DWORD   ?    
    grfAccessMode  dword ? ;ACCESS_MODE
    grfInheritance DWORD ?       ;
    Trustee TRUSTEE  <>    ;
EXPLICIT_ACCESS ends

MyGATE     struct    ;门结构类型定义
    OFFSETL  WORD      ?  ;32位偏移的低16位
    SELECTOR WORd      ?  ;选择子
    DCOUNT   BYTE      ?  ;双字计数字段
    GTYPE    BYTE      ?  ;类型
    OFFSETH  WORD     ?  ;32位偏移的高16位
MyGATE     ends

SetPhyscialMemorySectionCanBeWrited proto :dword
MiniMmGetPhysicalAddress proto :dword

ENTERRING0 macro
pushad  
pushfd
cli
mov eax,cr0   ;get rid off readonly protect
and eax,0fffeffffh
mov cr0,eax
endm

LEAVERING0 macro
mov eax,cr0 ;restore readonly protect
or eax,10000h
mov cr0,eax
sti
popfd
popad  
retf
endm


UNICODE_STR macro str
irpc _c,<str>
db \'&_c\'
db 0
endm
endm

.data?
GdtLimit dw ?
GdtAddr dd ?

mapAddr dd ?
OldEsp dd ?

readed  dw ?
buffer db 512 dup(?)
ShowText db 512*3 dup (?)

.data
align 4
objname dw objnamestr_size,objnamestr_size+2
objnameptr dd 0
objnamestr equ this byte
UNICODE_STR <\\Device\\PhysicalMemory>
objnamestr_size equ $-objnamestr

align 4
ObjAttr db 24 dup (0)
IsIdtFlag dd 0
Callgt dq 0        ;call gate\'s sel:off
Caption db \'Windows XP绝对磁盘读写--MBR\',0
Digit db \'0123456789ABCDEF\',0
.code
_ShowBuffer proc ;显示所读出的信息
;把数据转换成16进制的形式
mov  [readed],512
mov  esi,offset buffer ;数据
mov  edi,offset ShowText ;转换后的数据
mov  ebx,offset Digit
xor  ecx,ecx
xor  eax,eax
computeAgain:
cmp  [readed],0
jz   endCompute
dec  [readed]
lodsb
push eax
shr  eax,4 ;高4位
xlatb
stosb
pop  eax
and  eax,0fH ;低4位
xlatb
stosb
mov  byte ptr[edi],\' \' ;空格
inc  edi
inc  ecx
cmp  ecx,16
jnz  computeAgain
xor  ecx,ecx
mov  byte ptr[edi-1],13 ;回车
jmp  computeAgain
endCompute:
;显示
invoke  MessageBoxA,NULL,offset ShowText,offset Caption,MB_OK
ret
_ShowBuffer endp

SetPhyscialMemorySectionCanBeWrited proc uses ebx esi edi hSection:HANDLE
local pDacl: PACL
local pNewDacl:PACL
local pSD :PSECURITY_DESCRIPTOR
local dwRes:DWORD ;
local ea:EXPLICIT_ACCESS ;
invoke GetSecurityInfo,hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,\\
                  NULL,NULL, addr pDacl,NULL, addr pSD
cmp eax,ERROR_SUCCESS
jz @f
jmp OutSet
@@:
mov dwRes,eax
mov ea.grfAccessPermissions ,SECTION_MAP_WRITE;2
mov ea.grfAccessMode ,GRANT_ACCESS;1
mov ea.grfInheritance,NO_INHERITANCE;0
mov ea.Trustee.pMultipleTrustee,0
mov ea.Trustee.MultipleTrusteeOperation,0
mov ea.Trustee.TrusteeForm,TRUSTEE_IS_NAME;1
mov ea.Trustee.TrusteeType,TRUSTEE_IS_USER;1
call @f
db \"CURRENT_USER\",0
@@:
pop edx
mov ea.Trustee.ptstrName,edx
invoke SetEntriesInAcl,1,addr ea,pDacl,addr pNewDacl
cmp eax,ERROR_SUCCESS
jz @f
jmp OutSet
@@:
invoke SetSecurityInfo,hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,\\
                  NULL,NULL,pNewDacl,NULL
OutSet:
cmp pSD,0
jz @f
invoke LocalFree,pSD
@@:
cmp pNewDacl,0
jz @f
invoke LocalFree,pNewDacl
@@:
ret
SetPhyscialMemorySectionCanBeWrited endp

MiniMmGetPhysicalAddress proc virtualaddress:dword
 mov eax,virtualaddress
 cmp eax,80000000h
 jb @f
 cmp eax,0a0000000h
 jae @f
 and eax,1FFFF000h
 ret
 @@:
 mov eax,0
 ret
MiniMmGetPhysicalAddress endp

ExecRing0Proc proc
local tmpSel:dword
local setcg:dword
local BaseAddress:dword
local NtdllMod :dword
local hSection:HANDLE
local status:NTSTATUS
local objectAttributes:OBJECT_ATTRIBUTES  
local objName:UNICODE_STRING
mov status,STATUS_SUCCESS;
sgdt GdtLimit
invoke MiniMmGetPhysicalAddress,GdtAddr
mov mapAddr,eax
test eax,eax
jz Exit1
call @f
db \"Ntdll.dll\",0
@@:
call LoadLibraryA
mov NtdllMod,eax

lea edx,objnamestr
mov objnameptr,edx
lea edi,ObjAttr
and di,0fffch ;align to 4 bytes,or ZwOpenSection will fail
push edi   ;edi->ObjAttr
push 24    ;length of <\\Device\\PhysicalMemory>
pop ecx
push ecx
xor eax,eax
rep stosb   ;put ObjAttr with 0
pop ecx
pop edi
mov esi,edi
stosd
mov dword ptr[esi],ecx
stosd
lea eax,[edx-8] ;eax->objname
stosd      ;ObjAddr(18h,00,00,00,00,00,00,00,offset objname,40,02,00,00,dd 2 dup(0)
mov dword ptr [edi],240h

call @f
db \"ZwOpenSection\",0
@@:
push NtdllMod
call GetProcAddress
mov ebx,eax ;ebx=ZwOpenSection

push esi ;esi->ObjAttr
push SECTION_MAP_READ or SECTION_MAP_WRITE
lea edi,hSection
push edi ;edi->hSection
call eax ;ZwOpenSection(&hSection,SECTION_MAP_READ or SECTION_MAP_WRITE,ObjAttr)

mov status,eax
cmp status,STATUS_ACCESS_DENIED
jnz AccessPermit
mov eax,ebx

push esi
push READ_CONTROL or WRITE_DAC
push edi
call eax

mov status,eax
invoke SetPhyscialMemorySectionCanBeWrited,hSection

call @f
db \"ZwClose\",0
@@:
push NtdllMod
call GetProcAddress

push hSection
call eax  ;zwClose hSection

mov eax,ebx

push esi
push SECTION_MAP_READ or SECTION_MAP_WRITE
lea edi,hSection
push edi
call eax
mov status ,eax
;status =ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
AccessPermit:
cmp status ,STATUS_SUCCESS
jz @f
;printf(\"Error Open PhysicalMemory Section Object,Status:%08X\\n\",status);
;return 0;
mov eax,0
ret
@@:
movzx eax,word ptr[GdtLimit]
inc eax
invoke MapViewOfFile,hSection, FILE_MAP_READ or FILE_MAP_WRITE, 0, mapAddr, \\
                     eax
mov BaseAddress,eax
cmp BaseAddress,0
jnz @f
;printf(\"Error MapViewOfFile:\");
;PrintWin32Error(GetLastError()); return 0;
mov eax,0
ret
@@:
mov    esi,eax ;esi->gdt base
mov ecx,3e0h
mov eax,GdtAddr

.if dword ptr [esi+ecx+2]!=0ec0303e8h  ;3 parameters
;.if dword ptr [esi+ecx+2]!=0ec0003e8h
mov byte ptr [esi],0c3h

mov word ptr [esi+ecx],ax
shr eax,16
mov word ptr [esi+ecx+6],ax
mov dword ptr [esi+ecx+2],0ec0303e8h
;mov dword ptr [esi+ecx+2],0ec0003e8h

mov dword ptr [esi+ecx+8],0000ffffh
mov dword ptr [esi+ecx+12],00cf9a00h
.endif

mov setcg,TRUE
cmp setcg,0
jnz ChangeOK
call @f
db \"ZwClose\",0
@@:
push NtdllMod
call GetProcAddress
push hSection
call eax
xor eax,eax
ret
ChangeOK:
and    dword ptr Callgt,0
xor eax,eax
mov    ax,3e0h
or     al,3h
mov    word  ptr [Callgt+4],ax
;farcall[2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3; //Ring 3 callgate;
lea eax,_Ring0Proc
;invoke VirtualLock,eax,seglen
test eax,eax
jnz @f
xor eax,eax
ret
@@:
invoke GetCurrentThread
invoke SetThreadPriority,eax,THREAD_PRIORITY_TIME_CRITICAL

mov eax,3e0h
lar edx,eax
jnz Ring3

invoke Sleep,0
push 0
push 0ffffffffh
push 12345678h
call    fword ptr [Callgt]            ;use callgate to Ring0!
;_asm call fword ptr [farcall]
_Ring0Proc:   ; Ring0 code here..
mov eax,esp   ;save ring0 esp
mov esp,[esp+4*4];->ring3 esp
push eax
mov dx,1f6h  ;Drive and head port
        mov al,0a0h  ;Drive 0,Head 0
        out dx,al

        mov dx,1f2h  ;Sector count port
        mov al,1     ;Read One Sector
        out dx,al

        mov dx,1f3h  ;Sector number port
        mov al,1     ;Read One Sector
        out dx,al

        mov dx,1f4h  ;Cylinder low port
        xor al,al    ;Cylinder 0
        out dx,al

        mov dx,1f5h  ;Cylinder high port
        xor al,al    ;The rest of Cylinder 0
        out dx,al
 
        mov dx,1f7h  ;Command port
        mov al,20h   ;Read with Entry
        out dx,al
Still_going:
        in al,dx
        test al,8   ;This means the sector buffer requires servcing
        jz Still_going;do not continue until the sector buffer is ready
        xor ecx,ecx
mov cx,512/2  ;one sector/2
        mov edi,offset buffer
        mov dx,1f0h   ;data port - data comes in and out here
        cli
        cld
        rep insw
        sti
pop esp   ;restore ring0 esp
push offset Ring3
retf 4*3
Ring0CodeLen=$-_Ring0Proc

Ring3:
invoke GetCurrentThread
invoke SetThreadPriority,eax,THREAD_PRIORITY_NORMAL

;invoke VirtualUnlock,Entry,seglen

call @f
db \"ZwClose\",0
@@:
push NtdllMod
call GetProcAddress
push hSection
call eax
mov eax,TRUE
ret
ExecRing0Proc endp

main:
assume fs:nothing
push offset MySEH
push fs:[0]
mov fs:[0],esp
mov OldEsp,esp
mov ax,ds ;if Win9x?
test ax,4
jnz Exit1
invoke ExecRing0Proc

call _ShowBuffer
Exit1:
pop fs:[0]
add esp,4
invoke ExitProcess,0

MySEH :
mov esp,OldEsp
pop fs:[0]
add esp,4
invoke ExitProcess,-1
end main
    
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
Rose_zsf
驱动牛犊
驱动牛犊
  • 注册日期2002-07-04
  • 最后登录2004-02-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-12-02 15:06
先感谢你的回复,我现在是在VC6里进行读写,代码如下:
HANDLE hDisk = ::CreateFile( \"\\\\\\\\.\\\\PHYSICALDRIVE0\",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if( INVALID_HANDLE_VALUE == hDisk )
{
AfxMessageBox( _T(\"open disk failed\\n\") );
return -1;
}

//
// Read mbr
UCHAR mbr[512];
memset( &mbr[0], 0, sizeof(mbr) );
DWORD dwBytes=0;
BOOL bRet = FALSE;
bRet = ::SetFilePointer( hDisk, 0, NULL, FILE_BEGIN );
bRet = ReadFile( hDisk, mbr, sizeof(mbr), &dwBytes, NULL );

//
// Back up to 2nd sector if not yet.
UCHAR back[512];
memset( &back[0], 0, sizeof(back) );
::SetFilePointer( hDisk, SECTOR_SIZE, NULL, FILE_BEGIN );
bRet = ReadFile( hDisk, back, sizeof(back), &dwBytes, NULL );
if( bRet && *((ULONG *)&mbr[BKUP_TAG])==0x88FF ) //already backuped.
;
else //back up MBR to 2nd secotr.
{
::WriteFile( hDisk, mbr, sizeof(mbr), &dwBytes, NULL );
}


//这里需要把新的MBR程序写进1st扇区。

::CloseHandle( hDisk );
游客

返回顶部