阅读:1802回复:11
驱动中如何读磁盘扇区?
我想在2000下读写MBR,需要在Ring0级才可以实现,请问如何实现?
|
|
沙发#
发布于:2003-12-01 11:35
刚刚写了一个
可以到ddk的src\\storage\\class\\disk里去借鉴一下源码 ;) |
|
板凳#
发布于:2003-12-01 13:44
那个目录下有那么多文件是哪一个呀?
还有问一个弱智的问题: mov ax, 201h mov bx, buffer mov cx, 1 mov dx, 80h int 13h 这段代码能在内核中执行吗? |
|
地板#
发布于:2003-12-01 18:50
2K下读写硬盘扇区很容易,可以参考我以前的代码,通过直接IO饶过MS的驱动,还可以直接读写128GB硬盘中的任一扇区。。。。。。
|
|
|
地下室#
发布于: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盘第一个扇区,保存文件 |
|
5楼#
发布于:2003-12-02 08:43
谢谢各位,我已经知道如何读写MBR,现在,我想把我自己的引导程序写入到MBR,MBR中的程序是16位的,而VC++6是32位的编译器,我如何把我自己的引导程序编译成16位的呢?并将其作为数据写入到MBR扇区中?
|
|
6楼#
发布于:2003-12-02 09:44
一样,把你代码读入缓冲区,然后将其作为数据写入MBR
WriteFile ( hDevice,buffer, 512, &bytesread, NULL ); |
|
|
7楼#
发布于:2003-12-02 10:41
比如说我自己写的MBR程序如下:
xor ax, ax push ax pop cs push ax pop ds push ax pop es ... ... 现我需要将其写入MBR,则我的代码以什么形式存在?怎样写入? |
|
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 当然如果你想保留分区表,就不用写那么多了。。。。。。 |
|
|
9楼#
发布于:2003-12-02 13:42
分区表肯定是需要保存的,我只是想改变它引导的那一部分。
|
|
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 |
|
|
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 ); |
|