#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