使用DeviceIoControl读写磁盘MBR, 修改分区类型示例
来源:互联网 发布:淘宝培训课程列表 编辑:程序博客网 时间:2024/06/05 18:49
- #include <stdio.h>
- #include <stdlib.h>
- #include <tchar.h>
- #include <windows.h>
- #pragma pack(1)
- #define MAX_MBR_PARTITIONS 4
- #define MBR_DISK_SIGNATURE_OFFSET 440
- #define MBR_DISK_PPT_OFFSET 446
- #define MBR_SIGNATURE_OFFSET 510
- //
- // MBR Partition Entry
- //
- typedef struct {
- UINT8 BootIndicator;
- UINT8 StartHead;
- UINT8 StartSector;
- UINT8 StartTrack;
- UINT8 OSType;
- UINT8 EndHead;
- UINT8 EndSector;
- UINT8 EndTrack;
- UINT32 StartingLBA;
- UINT32 SizeInLBA;
- } MBR_PARTITION_RECORD;
- //
- // MBR Partition table
- //
- typedef struct {
- UINT8 BootCode[440];
- UINT32 UniqueMbrSignature;
- UINT16 Unknown;
- MBR_PARTITION_RECORD PartitionRecord[MAX_MBR_PARTITIONS];
- UINT16 Signature;
- } MASTER_BOOT_RECORD;
- #pragma pack()
- #define MBR_SIGNATURE 0xAA55
- #define EXTENDED_DOS_PARTITION 0x05
- #define EXTENDED_WINDOWS_PARTITION 0x0F
- BOOL ReadMBR(LPVOID *pBuffer)
- {
- HANDLE hDevice;
- DWORD dwSize;
- DWORD dwOverRead;
- BOOL bRet = TRUE;
- hDevice = CreateFile(TEXT("\\\\.\\PhysicalDrive2"),
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if (hDevice == INVALID_HANDLE_VALUE) {
- printf("Open \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());
- return FALSE;
- }
- if (!DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL)) {
- CloseHandle(hDevice);
- printf("FSCTL_LOCK_VOLUME \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());
- return FALSE;
- }
- DISK_GEOMETRY Geometry;
- if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &Geometry, sizeof(DISK_GEOMETRY), &dwSize, NULL)) {
- bRet = FALSE;
- printf("IOCTL_DISK_GET_DRIVE_GEOMETRY \\\\.\\PhysicalDrive0 failed. Error=%u\n", GetLastError());
- goto _out;
- }
- *pBuffer = (LPVOID)GlobalAlloc(GPTR, Geometry.BytesPerSector);
- if (*pBuffer) {
- if (!ReadFile(hDevice, *pBuffer, Geometry.BytesPerSector, &dwOverRead, NULL)) {
- printf("ReadFile \\\\.\\PhysicalDrive0 %u bytes failed. Error=%u\n", Geometry.BytesPerSector, GetLastError());
- bRet = FALSE;
- }
- }
- _out:
- DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwSize, NULL);
- CloseHandle(hDevice);
- return bRet;
- }
- BOOL WriteMBR(LPVOID pBuffer, DWORD nNumberOfBytesToWrite)
- {
- HANDLE hDevice;
- DWORD dwBytesReturned = 0;
- DWORD dwNumberOfBytesWritten = 0;
- BOOL bRet = TRUE;
- if (!pBuffer || IsBadReadPtr(pBuffer, nNumberOfBytesToWrite)){
- return FALSE;
- }
- hDevice = CreateFile(TEXT("\\\\.\\PhysicalDrive2"),
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if (hDevice == INVALID_HANDLE_VALUE) {
- printf("Open \\\\.\\PhysicalDrive2 failed. Error=%u\n", GetLastError());
- return FALSE;
- }
- if (!DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL)) {
- CloseHandle(hDevice);
- printf("FSCTL_LOCK_VOLUME \\\\.\\PhysicalDrive2 failed. Error=%u\n", GetLastError());
- return FALSE;
- }
- DISK_GEOMETRY pdg;
- if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &pdg, sizeof(DISK_GEOMETRY), &dwBytesReturned, NULL)) {
- bRet = FALSE;
- printf("IOCTL_DISK_GET_DRIVE_GEOMETRY \\\\.\\PhysicalDrive2 failed. Error=%u\n", GetLastError());
- goto _out;
- }
- printf("Write %u bytes to \\\\.\\PhysicalDrive2\n", pdg.BytesPerSector);
- if (nNumberOfBytesToWrite != pdg.BytesPerSector) {
- bRet = FALSE;
- printf("\\\\.\\PhysicalDrive2 nNumberOfBytesToWrite %u != BytesPerSector %u.\n",
- nNumberOfBytesToWrite, pdg.BytesPerSector);
- goto _out;
- }
- if (!WriteFile(hDevice, pBuffer, pdg.BytesPerSector, &dwNumberOfBytesWritten, NULL)) {
- printf("WriteFile \\\\.\\PhysicalDrive2 %u bytes failed. Error=%u\n", pdg.BytesPerSector, GetLastError());
- bRet = FALSE;
- }
- _out:
- DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
- CloseHandle(hDevice);
- return bRet;
- }
- int main(int argc, char **argv)
- {
- LPVOID lpMBRBuffer = NULL;
- UINT nIdx = 0x1BE;
- UINT nCnt = 0;
- UCHAR *pBuf = NULL;
- MASTER_BOOT_RECORD *lpMbr = NULL;
- if (ReadMBR(&lpMBRBuffer)){
- pBuf = (UCHAR *)lpMBRBuffer;
- lpMbr = (MASTER_BOOT_RECORD *)lpMBRBuffer;
- for (; nIdx < 0x1FE; nIdx ++){
- printf("%02X ", pBuf[nIdx]);
- nCnt ++;
- if (nCnt >= 0x10){
- nCnt = 0;
- printf("\n");
- }
- }
- for (nIdx = 0; nIdx < MAX_MBR_PARTITIONS; nIdx ++){
- printf("Part %u Type 0x%x\n", nIdx + 1, lpMbr->PartitionRecord[nIdx].OSType);
- }
- lpMbr->PartitionRecord[1].OSType = 0x5;
- WriteMBR(pBuf, sizeof(MASTER_BOOT_RECORD));
- GlobalFree(lpMBRBuffer);
- lpMBRBuffer = NULL;
- }
- printf("*******************************************\n");
- if (ReadMBR(&lpMBRBuffer)){
- pBuf = (UCHAR *)lpMBRBuffer;
- lpMbr = (MASTER_BOOT_RECORD *)lpMBRBuffer;
- nIdx = 0x1BE;
- nCnt = 0;
- for (; nIdx < 0x1FE; nIdx ++){
- printf("%02X ", pBuf[nIdx]);
- nCnt ++;
- if (nCnt >= 0x10){
- nCnt = 0;
- printf("\n");
- }
- }
- for (nIdx = 0; nIdx < MAX_MBR_PARTITIONS; nIdx ++){
- printf("Part %u Type 0x%x\n", nIdx + 1, lpMbr->PartitionRecord[nIdx].OSType);
- }
- GlobalFree(lpMBRBuffer);
- lpMBRBuffer = NULL;
- }
- return 0;
- }
编译
执行结果:
参考:
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 来进行访问硬盘。
代码及详细注释:
- ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
- ; by 小甲鱼, http://www.fishc.com
- ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
- ; 功能:读取硬盘引导扇区并保存于boot.ini文件中
- ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
- .386
- .model flat,stdcall
- option casemap:none
- include windows.inc
- include comdlg32.inc
- include user32.inc
- include kernel32.inc
- includelib comdlg32.lib
- includelib user32.lib
- includelib kernel32.lib
- .data
- szFileName db '\\.\\physicaldrive0', 0 ; 硬盘设备名
- .data?
- szBuffer db 512 dup (?)
- @hFile dd ?
- @dwBytesRead dd ?
- @szLogFile db MAX_PATH dup (?)
- .const
- szNewFile db 'boot.ini', 0
- szErrOpenFile db '无法打开硬盘文件!', 0
- szErrCreateFile db '无法创建boot.ini文件!', 0
- szSuccess db '成功读取硬盘引导区并写入boot.ini文件!', 0
- szCaption db '鱼C工作室', 0
- .code
- start:
- invoke CreateFile, ; 打开或创建文件
- addr szFileName, ; 文件的名字
- GENERIC_READ, ; 允许读访问
- FILE_SHARE_READ, ; 允许对文件进行共享访问
- 0, ; 指向一个SECURITY_ATTRIBUTES结构的指针
- OPEN_EXISTING, ; 文件必须存在
- FILE_ATTRIBUTE_NORMAL, ; 默认属性
- 0
- .if eax == INVALID_HANDLE_VALUE ; 打开文件错误
- invoke MessageBox,
- NULL,
- addr szErrOpenFile,
- addr szCaption,
- MB_OK
- jmp exit
- .endif
- mov @hFile, eax ; 返回文件句柄,这时候硬盘被看成是一个文件的哦~
- invoke ReadFile, ; 从文件中读取数据
- @hFile, ; 文件句柄
- addr szBuffer, ; 用于保存读入数据的缓冲区
- sizeof szBuffer, ; 需要读入的字符数
- addr @dwBytesRead, ; 实际读入的字节数
- 0
- invoke CloseHandle, @hFile ; 小甲鱼温馨提醒:记得文件打开后要擦屁股->关闭文件,否则造成内存泄漏
- invoke lstrcpy, ; 拷贝字符串
- addr @szLogFile,
- addr szNewFile
- invoke CreateFile, ; 创建boot.ini文件
- addr @szLogFile,
- GENERIC_WRITE,
- FILE_SHARE_READ,
- 0,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- 0
- .if eax != INVALID_HANDLE_VALUE
- mov @hFile, eax
- invoke WriteFile, ; 将数据写入boot.ini文件
- @hFile,
- addr szBuffer,
- sizeof szBuffer,
- addr @dwBytesRead,
- 0
- invoke CloseHandle, @hFile ; 擦屁股
- invoke wsprintf, ; 这个事实上常用的函数,如果有问题的鱼油可以在论坛搜索下,有篇文章中小甲鱼已经做好了详细的解释给大家。
- addr szBuffer,
- addr szSuccess
- invoke MessageBox,
- NULL,
- addr szBuffer,
- addr szCaption,
- MB_OK
- .else
- invoke MessageBox,
- NULL,
- addr szErrCreateFile,
- addr szCaption,
- MB_OK
- .endif
- exit:
- invoke ExitProcess, NULL
- end start
- 使用DeviceIoControl读写磁盘MBR, 修改分区类型示例
- 使用DeviceIoControl读写磁盘MBR, 修改分区类型示例
- 磁盘,fdisk分区,MBR,dd命令
- Linux 分区详解之—Parted,可以查看你的磁盘的分区类型(比如说GPT/MBR)
- 课时9 磁盘基本概念(磁盘、分区、MBR与GPT)
- Linux 磁盘基本概念(磁盘、分区、MBR、GPT)
- 硬盘(MBR磁盘)分区基本认识+Windows启动原理
- 【centos6,2】centos6 系统 :磁盘,分区,MBR,GPT
- VC Win32 读取 磁盘MBR 和 EBR扩展分区 数据
- Linux 学习手记(6): 磁盘、分区、MBR与GPT
- linux 基础学习之 磁盘,分区,MBR与GPT
- 磁盘结构,原理,MBR,文件系统,分区,swap,加密,raid,配额
- 磁盘,MBR
- MBR分区
- 关于GPT分区转换成MBR分区的几个方式 GPT分区下安装Windows7 x64 完整教程 把MBR磁盘转换为GPT磁盘
- 文件系统与存储:MBR/EBR类型分区建立
- 实战DeviceIoControl 之七:在Windows 9X中读写磁盘扇区
- 实战DeviceIoControl 之七:在Windows 9X中读写磁盘扇区
- 杭电ACM OJ 1003 Max Sum 一点点的动态规划思想 入门级
- hdu1002(超超长数字相加)
- C++20171110日志 Static类型的声明
- 为什么表单中用name而不是id
- android4.4透明标题栏实现
- 使用DeviceIoControl读写磁盘MBR, 修改分区类型示例
- Spring 的微内核与FactoryBean扩展机制--转载
- 开源网站
- 我的Qt学习之路——按钮特效
- codevs 1008 选数 dfs
- 推荐系统---基于概率的矩阵分解(PMF)
- 对比Ubuntu与Win10的资源占用
- java.lang.StackOverflowError错误
- Spring之BeanFactory 与 FactoryBean