使用DeviceIoControl读写磁盘MBR, 修改分区类型示例

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <tchar.h>  
  4. #include <windows.h>  
  5.   
  6. #pragma pack(1)  
  7.   
  8. #define MAX_MBR_PARTITIONS          4  
  9. #define MBR_DISK_SIGNATURE_OFFSET   440  
  10. #define MBR_DISK_PPT_OFFSET         446  
  11. #define MBR_SIGNATURE_OFFSET        510  
  12.   
  13. //  
  14. // MBR Partition Entry  
  15. //  
  16. typedef struct {  
  17.   UINT8  BootIndicator;  
  18.   UINT8  StartHead;  
  19.   UINT8  StartSector;  
  20.   UINT8  StartTrack;  
  21.   UINT8  OSType;  
  22.   UINT8  EndHead;  
  23.   UINT8  EndSector;  
  24.   UINT8  EndTrack;  
  25.   UINT32 StartingLBA;  
  26.   UINT32 SizeInLBA;  
  27. } MBR_PARTITION_RECORD;  
  28.   
  29. //  
  30. // MBR Partition table  
  31. //  
  32. typedef struct {  
  33.   UINT8                 BootCode[440];  
  34.   UINT32                UniqueMbrSignature;  
  35.   UINT16                Unknown;  
  36.   MBR_PARTITION_RECORD  PartitionRecord[MAX_MBR_PARTITIONS];  
  37.   UINT16                Signature;  
  38. } MASTER_BOOT_RECORD;  
  39.   
  40. #pragma pack()  
  41.   
  42. #define MBR_SIGNATURE               0xAA55  
  43. #define EXTENDED_DOS_PARTITION      0x05  
  44. #define EXTENDED_WINDOWS_PARTITION  0x0F  
  45.   
  46.   
  47. BOOL ReadMBR(LPVOID *pBuffer)  
  48. {  
  49.     HANDLE hDevice;  
  50.     DWORD dwSize;  
  51.     DWORD dwOverRead;  
  52.     BOOL bRet = TRUE;  
  53.     hDevice = CreateFile(TEXT("\\\\.\\PhysicalDrive2"),  
  54.                          GENERIC_READ | GENERIC_WRITE,  
  55.                          FILE_SHARE_READ | FILE_SHARE_WRITE,  
  56.                          NULL,  
  57.                          OPEN_EXISTING,  
  58.                          0,  
  59.                          NULL);  
  60.     if (hDevice == INVALID_HANDLE_VALUE) {  
  61.         printf("Open \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());  
  62.         return FALSE;  
  63.     }  
  64.       
  65.     if (!DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL)) {  
  66.         CloseHandle(hDevice);  
  67.         printf("FSCTL_LOCK_VOLUME \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());  
  68.         return FALSE;  
  69.     }  
  70.     DISK_GEOMETRY Geometry;  
  71.     if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &Geometry, sizeof(DISK_GEOMETRY), &dwSize, NULL)) {  
  72.         bRet = FALSE;  
  73.         printf("IOCTL_DISK_GET_DRIVE_GEOMETRY \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());  
  74.         goto _out;  
  75.     }  
  76.       
  77.     *pBuffer = (LPVOID)GlobalAlloc(GPTR, Geometry.BytesPerSector);  
  78.     if (*pBuffer) {  
  79.         if (!ReadFile(hDevice, *pBuffer, Geometry.BytesPerSector, &dwOverRead, NULL)) {  
  80.             printf("ReadFile \\\\.\\PhysicalDrive0 %u bytes failed. Error=%u\n", Geometry.BytesPerSector, GetLastError());  
  81.             bRet = FALSE;  
  82.         }  
  83.     }  
  84. _out:     
  85.     DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);  
  86.     CloseHandle(hDevice);     
  87.     return bRet;  
  88.   
  89. }  
  90.   
  91. BOOL WriteMBR(LPVOID pBuffer, DWORD nNumberOfBytesToWrite)  
  92. {  
  93.     HANDLE hDevice;  
  94.     DWORD dwBytesReturned = 0;  
  95.     DWORD dwNumberOfBytesWritten = 0;  
  96.     BOOL bRet = TRUE;  
  97.       
  98.     if (!pBuffer || IsBadReadPtr(pBuffer, nNumberOfBytesToWrite)){  
  99.         return FALSE;  
  100.     }  
  101.     hDevice = CreateFile(TEXT("\\\\.\\PhysicalDrive2"),  
  102.                          GENERIC_READ | GENERIC_WRITE,  
  103.                          FILE_SHARE_READ | FILE_SHARE_WRITE,  
  104.                          NULL,  
  105.                          OPEN_EXISTING,  
  106.                          0,  
  107.                          NULL);  
  108.     if (hDevice == INVALID_HANDLE_VALUE) {  
  109.         printf("Open \\\\.\\PhysicalDrive2 failed. Error=%u\n", GetLastError());  
  110.         return FALSE;  
  111.     }  
  112.       
  113.     if (!DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL)) {  
  114.         CloseHandle(hDevice);  
  115.         printf("FSCTL_LOCK_VOLUME \\\\.\\PhysicalDrive2 failed. Error=%u\n", GetLastError());  
  116.         return FALSE;  
  117.     }  
  118.     DISK_GEOMETRY pdg;  
  119.     if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &pdg, sizeof(DISK_GEOMETRY), &dwBytesReturned, NULL)) {  
  120.         bRet = FALSE;  
  121.         printf("IOCTL_DISK_GET_DRIVE_GEOMETRY \\\\.\\PhysicalDrive2 failed. Error=%u\n", GetLastError());  
  122.         goto _out;  
  123.     }  
  124.       
  125.     printf("Write %u bytes to \\\\.\\PhysicalDrive2\n", pdg.BytesPerSector);  
  126.       
  127.     if (nNumberOfBytesToWrite != pdg.BytesPerSector) {  
  128.         bRet = FALSE;  
  129.         printf("\\\\.\\PhysicalDrive2 nNumberOfBytesToWrite %u != BytesPerSector %u.\n",  
  130.             nNumberOfBytesToWrite, pdg.BytesPerSector);  
  131.         goto _out;  
  132.     }  
  133.     if (!WriteFile(hDevice, pBuffer, pdg.BytesPerSector, &dwNumberOfBytesWritten, NULL)) {  
  134.         printf("WriteFile \\\\.\\PhysicalDrive2 %u bytes failed. Error=%u\n", pdg.BytesPerSector, GetLastError());  
  135.         bRet = FALSE;  
  136.     }  
  137.       
  138. _out:     
  139.     DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL);  
  140.     CloseHandle(hDevice);     
  141.     return bRet;  
  142.   
  143. }  
  144.   
  145.   
  146. int main(int argc,  char **argv)  
  147. {  
  148.     LPVOID lpMBRBuffer = NULL;  
  149.     UINT nIdx = 0x1BE;  
  150.     UINT nCnt = 0;  
  151.     UCHAR *pBuf = NULL;  
  152.     MASTER_BOOT_RECORD *lpMbr = NULL;  
  153.       
  154.     if (ReadMBR(&lpMBRBuffer)){  
  155.         pBuf = (UCHAR *)lpMBRBuffer;  
  156.         lpMbr = (MASTER_BOOT_RECORD *)lpMBRBuffer;  
  157.           
  158.         for (; nIdx < 0x1FE; nIdx ++){  
  159.             printf("%02X ", pBuf[nIdx]);  
  160.             nCnt ++;  
  161.             if (nCnt >= 0x10){  
  162.                 nCnt = 0;  
  163.                 printf("\n");  
  164.             }  
  165.         }  
  166.         for (nIdx = 0; nIdx < MAX_MBR_PARTITIONS; nIdx ++){  
  167.             printf("Part %u Type 0x%x\n", nIdx + 1, lpMbr->PartitionRecord[nIdx].OSType);  
  168.         }  
  169.         lpMbr->PartitionRecord[1].OSType = 0x5;  
  170.           
  171.         WriteMBR(pBuf, sizeof(MASTER_BOOT_RECORD));       
  172.         GlobalFree(lpMBRBuffer);  
  173.         lpMBRBuffer = NULL;  
  174.     }  
  175.     printf("*******************************************\n");  
  176.     if (ReadMBR(&lpMBRBuffer)){  
  177.         pBuf = (UCHAR *)lpMBRBuffer;  
  178.         lpMbr = (MASTER_BOOT_RECORD *)lpMBRBuffer;  
  179.           
  180.         nIdx = 0x1BE;  
  181.         nCnt = 0;  
  182.         for (; nIdx < 0x1FE; nIdx ++){  
  183.             printf("%02X ", pBuf[nIdx]);  
  184.             nCnt ++;  
  185.             if (nCnt >= 0x10){  
  186.                 nCnt = 0;  
  187.                 printf("\n");  
  188.             }  
  189.         }  
  190.         for (nIdx = 0; nIdx < MAX_MBR_PARTITIONS; nIdx ++){  
  191.             printf("Part %u Type 0x%x\n", nIdx + 1, lpMbr->PartitionRecord[nIdx].OSType);  
  192.         }         
  193.         GlobalFree(lpMBRBuffer);  
  194.         lpMBRBuffer = NULL;  
  195.     }  
  196.     return 0;  
  197. }  


编译

执行结果:



参考:

http://en.wikipedia.org/wiki/Master_boot_record

http://thestarman.pcministry.com/asm/mbr/index.html

http://en.wikipedia.org/wiki/Disk_partitioning

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363986(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/aa363979(v=vs.85).aspx



版权声明:本文为博主原创文章,未经博主允许不得转载。

读取硬盘的MBR引导扇区(Windows各系统通用)

原文:

http://bbs.fishc.com/thread-18255-1-1.html

http://bbs.fishc.com/thread-18256-1-1.html

-----------------------------------------------------------------------------------------------------------

知识普及:


 

硬盘的引导扇区位于 0 磁道 0 磁头 1 扇区位置,该扇区存放着系统的引导程序和硬盘的分区表等重要信息。另外小甲鱼八卦一下,该扇区常常是病毒的重点攻击目标!



 

实现要求:读取硬盘引导扇区并保存为boot.ini文件

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

实现原理:


上节课小甲鱼不是说会告诉大家如何在用户模式下直接访问硬盘么?嗯,而且承诺绝对简单通俗。好吧,事实上,硬盘内核驱动程序将硬盘作为一个文件,文件名为:"\\.\\physicaldrive0"


我们可以利用这个鲜为人知的文件名,通过 CreateFile, ReadFile, WriteFile 和 DeviceIoControl API 来进行访问硬盘。


代码及详细注释:

[plain]  view plain  copy
  1. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
  2. ; by 小甲鱼, http://www.fishc.com  
  3. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
  4. ; 功能:读取硬盘引导扇区并保存于boot.ini文件中  
  5. ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  
  6.         .386  
  7.         .model flat,stdcall  
  8.         option casemap:none  
  9.   
  10. include windows.inc  
  11. include comdlg32.inc  
  12. include user32.inc  
  13. include kernel32.inc  
  14. includelib comdlg32.lib  
  15. includelib user32.lib  
  16. includelib kernel32.lib  
  17.   
  18.     .data  
  19. szFileName  db  '\\.\\physicaldrive0', 0            ; 硬盘设备名  
  20.   
  21.     .data?  
  22. szBuffer        db  512 dup (?)  
  23. @hFile          dd  ?  
  24. @dwBytesRead    dd  ?  
  25. @szLogFile      db  MAX_PATH dup (?)  
  26.   
  27.     .const  
  28. szNewFile       db  'boot.ini', 0  
  29. szErrOpenFile   db  '无法打开硬盘文件!', 0  
  30. szErrCreateFile db  '无法创建boot.ini文件!', 0  
  31. szSuccess       db  '成功读取硬盘引导区并写入boot.ini文件!', 0      
  32. szCaption       db  '鱼C工作室', 0      
  33.       
  34.     .code  
  35. start:  
  36.     invoke CreateFile,              ; 打开或创建文件  
  37.         addr szFileName,            ; 文件的名字  
  38.         GENERIC_READ,               ; 允许读访问  
  39.         FILE_SHARE_READ,            ; 允许对文件进行共享访问  
  40.         0,                          ; 指向一个SECURITY_ATTRIBUTES结构的指针  
  41.         OPEN_EXISTING,              ; 文件必须存在  
  42.         FILE_ATTRIBUTE_NORMAL,      ; 默认属性  
  43.         0  
  44.       
  45.     .if eax == INVALID_HANDLE_VALUE ; 打开文件错误  
  46.         invoke MessageBox,  
  47.             NULL,  
  48.             addr szErrOpenFile,  
  49.             addr szCaption,  
  50.             MB_OK  
  51.               
  52.         jmp exit  
  53.     .endif  
  54.       
  55.     mov @hFile, eax                 ; 返回文件句柄,这时候硬盘被看成是一个文件的哦~  
  56.       
  57.     invoke ReadFile,                ; 从文件中读取数据  
  58.         @hFile,                     ; 文件句柄  
  59.         addr szBuffer,              ; 用于保存读入数据的缓冲区  
  60.         sizeof szBuffer,            ; 需要读入的字符数  
  61.         addr @dwBytesRead,          ; 实际读入的字节数  
  62.         0  
  63.       
  64.     invoke CloseHandle, @hFile      ; 小甲鱼温馨提醒:记得文件打开后要擦屁股->关闭文件,否则造成内存泄漏  
  65.       
  66.     invoke lstrcpy,                 ; 拷贝字符串  
  67.         addr @szLogFile,  
  68.         addr szNewFile  
  69.       
  70.     invoke CreateFile,              ; 创建boot.ini文件  
  71.         addr @szLogFile,              
  72.         GENERIC_WRITE,                
  73.         FILE_SHARE_READ,              
  74.         0,                            
  75.         CREATE_ALWAYS,                
  76.         FILE_ATTRIBUTE_NORMAL,        
  77.         0  
  78.       
  79.     .if eax != INVALID_HANDLE_VALUE  
  80.         mov @hFile, eax  
  81.           
  82.         invoke WriteFile,           ; 将数据写入boot.ini文件  
  83.             @hFile,  
  84.             addr szBuffer,  
  85.             sizeof szBuffer,  
  86.             addr @dwBytesRead,  
  87.             0  
  88.       
  89.         invoke CloseHandle, @hFile  ; 擦屁股  
  90.           
  91.         invoke wsprintf,            ; 这个事实上常用的函数,如果有问题的鱼油可以在论坛搜索下,有篇文章中小甲鱼已经做好了详细的解释给大家。  
  92.             addr szBuffer,  
  93.             addr szSuccess  
  94.            
  95.         invoke MessageBox,  
  96.             NULL,  
  97.             addr szBuffer,  
  98.             addr szCaption,  
  99.             MB_OK  
  100.               
  101.     .else  
  102.         invoke MessageBox,  
  103.             NULL,  
  104.             addr szErrCreateFile,  
  105.             addr szCaption,  
  106.             MB_OK  
  107.     .endif      
  108.           
  109. exit:  
  110.     invoke ExitProcess, NULL  
  111.           
  112.     end start  


 

 

 

 

 

 



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值