由于实验需要写一个分区表的分析程序,时间比较多就写了个适用于GPT和 MBR分区的通用程序
没啥特别的亮点,主要还是可以通用地分析磁盘分区以及适用两种磁盘格式 本程序是字符界面,之前的是图形化界面,规划得有点丑,就不献丑了 自带分析、提取数据函数,若想继续分析其他也可在此基础上添加。在此只演示GPT下的FAT32分区分析 注:需管理员权限运行,否则无法得到分区信息
分区/驱动器Drive类
#pragma once
#include<string>
#include<string.h>
#include<windows.h>
;
using namespace stdenum DriveType {
, FAT32, GPT, UNKNOWN
NTFS};
{
class Drive :
public//通用属性
;
DriveType typeint cluster; //单位:扇区
int sector;
; //卷标
string labelbool active;
//Bytes
long long offset;
long long size;
[512];
TCHAR msg//FAT32属性
int reversedSector;
int FATSector;
//Bytes
long long rootOffset;
long long FATOffest;
//NTFS属性
//待补充
(void) {
Drive= false;
active (msg, -1, sizeof(msg));
memset}
~Drive(void) {
}
};
主程序
#include <stdio.h>
#include<windows.h>
#include<String>
#include<Vector>
#include"Drive.h"
;
using namespace std
#define NULL_16 (unsigned char *)"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
#define NULL_8 (unsigned char *)"\x00\x00\x00\x00\x00\x00\x00\x00"
#define NULL_4 (unsigned char *)"\x00\x00\x00\x00"
#define NULL_2 (unsigned char *)"\x00\x00"
//读取磁盘在此修改
#define __READ "\\\\.\\PHYSICALDRIVE0"
#define EFI_FLAG (unsigned char *)"EFI PART"
#define NTFS_SYMBOL (unsigned char *)"NTFS "
#define FAT32_SYMBOL (unsigned char *)"MSDOS5.0"
#define PARTITION_FLAG_LEN 8
#define OFFSET_DPT 446
#define SECTOR_LEN 512
long LODWORD(long long a);
long HIDWORD(long long a);
double ConvertToGB(long long size);
double ConvertToMB(long long size);
double ConvertToKB(long long size);
void ComfortableDataExpress(long long a,TCHAR * str);
double ComfortableData(long long a);
unsigned long long HexStringToLong(unsigned char * a,int len);
void TranslateData(unsigned char * a,int len, unsigned char * b,bool Remove_zero=0);
void Analysis_GPT(long long offset ,int show_analysis=0);
(unsigned char *a ,int show_analysis=0);
DriveType Analysis_Partition_Typevoid Analysis_DPT(unsigned char *a ,int show_analysis=0,bool extendFlag=0,long long posOffset=0);
(unsigned char* &out,long start,long High,DWORD size,int pos=0);
DWORD ReadDiskbool Check(unsigned char * a,unsigned char * str,int len=4);
static vector<Drive>DriveList;
static bool GPT_FLAG=0,MBR_FLAG=0,exFlag=1;; //磁盘类型
static long long MainExtenedOffset=0;
int main()
{
char buff[512];
unsigned char* a;
(a,NULL,NULL,512);
ReadDisk("\n主分区DPT分析:\n");
printf(&a[OFFSET_DPT],1,0,NULL);
Analysis_DPT("分区个数:%d\n",DriveList.size());
printf("FAT32磁盘信息如下:\n");
printf(" -------------------------------------------\n");
printffor(int i=0;i<DriveList.size();i++)
{
if(DriveList[i].type==FAT32)
{
(" 分区序号:%d\n",i);
printf(DriveList[i].size,buff);
ComfortableDataExpress(" 分区大小: %s \n",buff );
printf(" 分区偏移:%I64d 字节\n",DriveList[i].offset);
printf(" 簇:%d 个扇区\n",DriveList[i].cluster);
printf(" 保留扇区:%d 个\n",DriveList[i].reversedSector);
printf(" FAT表偏移:%I64d 字节\n",DriveList[i].FATOffest);
printf(" FAT表扇区:%d 个\n",DriveList[i].FATSector);
printf(" 根目录偏移:%I64d 字节\n",DriveList[i].rootOffset);
printf(" -------------------------------------------\n");
printf
}
}
return 0;
}
/*------------------------------------------------------------------------------------------------*/
//进制转换
double ConvertToGB(long long size)
{
return size/1024.0/1024.0/1024.0;
}
double ConvertToMB(long long size)
{
return size/1024.0/1024.0;
}
double ConvertToKB(long long size)
{
return size/1024.0;
}
void ComfortableDataExpress(long long a,TCHAR * str)
{
if(ConvertToGB(a)>=1)sprintf(str,TEXT("%.2lf GB"),ConvertToGB(a));
else if(ConvertToMB(a)>=1)sprintf(str,TEXT("%.2lf MB"),ConvertToMB(a));
else sprintf(str,TEXT("%.2lf KB"),ConvertToKB(a));
}
double ComfortableData(long long a)
{
if(ConvertToGB(a)>=1)return ConvertToGB(a);
else if(ConvertToMB(a)>=1)return ConvertToMB(a);
else return ConvertToKB(a);
}
long LODWORD(long long a)
{
return (DWORD)a;
}
long HIDWORD(long long a)
{
return (a>>32);
}
/*------------------------------------------------------------------------------------------------*/
//读取硬盘
(unsigned char* &out,long start,long High,DWORD size,int pos)
DWORD ReadDisk{
/*OVERLAPPED over = { 0 };
over.Offset = start; */
= CreateFile(
HANDLE handle (__READ),
TEXT,
GENERIC_READ|FILE_SHARE_WRITE,
FILE_SHARE_READ0,
,
OPEN_EXISTING0,
0);
if (handle == INVALID_HANDLE_VALUE)return 0;
unsigned char* buffer = new unsigned char[size + 1];
(handle, start, &High, pos);
SetFilePointer;
DWORD readsizeif (ReadFile(handle, buffer, size, &readsize, NULL) == 0)
{
(handle);
CloseHandlereturn 0;
}
[size] = 0;
buffer= buffer;
out
return size;
}
/*------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------------------*/
//判断字符
bool Check(unsigned char * a,unsigned char * str,int len)
{
for(int i=0;i<len;i++)
{
if(a[i]!=str[i])return false;
}
return true;
}
/*------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------------------*/
//十六进制字符转十进制数字
unsigned long long HexStringToLong(unsigned char * a,int len)
{
unsigned long long num=0,t=0;
for(int i =0;i<len;i++)
{
=a[i];
tfor(int j=i;j>0;j--){
*=256;
t}
+=t;
num}
return num;
}
//获取字符信息
void TranslateData(unsigned char * a,int len, unsigned char * b,bool Remove_zero)
{
int zero_num=0;
int char_num=0;
if (len){
for (int i = 0; i < len; i++){
if (Remove_zero)
{
if(a[i]==0)
{zero_num++;
continue;
}
}
++;
char_num[i-zero_num]=a[i];
b}
}
[char_num]=0;
b((char *)b,"%s",b);
sprintf}
/*------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------------------*/
//分析DPT
void Analysis_DPT(unsigned char *a ,int show_analysis,bool extenedFlag,long long posOffset)
{
[512];
TCHAR buffunsigned char * BUFFER;
long long offset=0;
unsigned char * partition_sector;
for (int i=0;i<4;i++)
{
if(Check(&a[i*16],NULL_16,16))break;
else
{
if (show_analysis)
{
(" 活动分区标志: %02x |", a[0+i*16]);
printf
(" 分区类型标志: %02x |", a[4+i*16]);
printf
(" 偏移扇区: %I64d |", HexStringToLong(&a[8+i*16],4));
printf
(512*HexStringToLong(&a[12+i*16],4),buff);
ComfortableDataExpress(" 磁盘大小: %s |\n",buff );
printf}
=512*HexStringToLong(&a[8+i*16],4);
offsetif(Check(&a[4+i*16],(unsigned char *)"\x0f",1) || (i==1 && extenedFlag))
{
if(exFlag){
= 512*HexStringToLong(&a[8+i*16],4);
MainExtenedOffset =0;
exFlag}
if(extenedFlag)offset+=MainExtenedOffset;
(" 偏移扇区: %I64d |\n", HexStringToLong(&a[8+i*16],4));
printf
(partition_sector,LODWORD(offset),HIDWORD(offset),SECTOR_LEN);
ReadDisk(&partition_sector[OFFSET_DPT],1,1,offset);
Analysis_DPTreturn ;
}
if(extenedFlag)offset+=posOffset;
(partition_sector,LODWORD(offset),HIDWORD(offset),SECTOR_LEN);
ReadDisk//ShowData(partition_sector,512);
if(Analysis_Partition_Type(partition_sector)!=GPT)
{
("\n检测到该磁盘为MBR磁盘!\n\n");
printf;
Drive drive//活动分区标志
if(a[0+i*16]==0x80)drive.active=true;
//盘位移
if(!extenedFlag)
=512*HexStringToLong(&a[8+i*16],4);//计算逻辑分区的位移
offset.offset=offset;//存入位移
drive.size=512*HexStringToLong(&a[12+i*16],4);//盘大小
drive
//开始跳转至盘分析
(BUFFER,LODWORD(offset),HIDWORD(offset),1*SECTOR_LEN);
ReadDisk.type = Analysis_Partition_Type(BUFFER);
driveswitch(drive.type)
{
case NTFS:
break;
case FAT32:
.cluster = HexStringToLong(&BUFFER[0x0d],1);
drive.reversedSector=HexStringToLong(&BUFFER[0x0e],2);
drive.FATOffest = drive.reversedSector * SECTOR_LEN;
drive.FATSector = HexStringToLong(&BUFFER[0x24],4);
drive.rootOffset = drive.FATOffest + SECTOR_LEN * drive.FATSector *2;
drivebreak;
case UNKNOWN:
break;
}
.push_back(drive);
DriveList}
else
{
("\n检测到该磁盘为GPT磁盘!\n\n");
printf(offset,1);
Analysis_GPT}
}
}
}
/*------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------------------*/
(unsigned char *a ,int show_analysis)
DriveType Analysis_Partition_Type{
if(Check(a,EFI_FLAG,PARTITION_FLAG_LEN))
{
=1;
GPT_FLAGif(show_analysis)printf(" 磁盘为GPT磁盘!\n");
return GPT;
}
else if(Check(&a[3],NTFS_SYMBOL,PARTITION_FLAG_LEN))
{
if(show_analysis)printf("分区格式:%-10s|","NTFS");
return NTFS;
}
else if(Check(&a[3],FAT32_SYMBOL,PARTITION_FLAG_LEN))
{
if(show_analysis)printf("分区格式:%-10s|","FAT32");
return FAT32;
}
else
{
if(show_analysis)printf("分区格式:%-10s|","UNKNOWN");
return UNKNOWN;
}
}
/*------------------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------------------*/
//解析GPT头
void Analysis_GPT(long long offset,int show_analysis)
{
[512];
TCHAR buffunsigned char * GPT_PT;
unsigned char * BUFFER;
(GPT_PT,LODWORD(offset),HIDWORD(offset),32*SECTOR_LEN);
ReadDisklong long GPT_Offset = HexStringToLong(&GPT_PT[0x48],8)*512;
long long Offset=0;
(GPT_PT,LODWORD(GPT_Offset),HIDWORD(GPT_Offset),32*SECTOR_LEN);
ReadDisk
for(int i=0;i<128;i++)
{
if(Check(&GPT_PT[i*128],NULL_16,16))break;
;
Drive drive//初始化GPT磁盘的分区属性
//分区大小
.size = 512*(HexStringToLong(&GPT_PT[i*128+0x28],8)-HexStringToLong(&GPT_PT[i*128+0x20],8) );
drive//GPT头自带72字节的分区信息
(&GPT_PT[i*128+0x38],72,(unsigned char *)drive.msg,true);
TranslateData//分区偏移
=512*(HexStringToLong(&GPT_PT[i*128+0x20],8));
Offset.offset = Offset;
drive(BUFFER,LODWORD(Offset),HIDWORD(Offset),1*SECTOR_LEN);
ReadDisk.type = Analysis_Partition_Type(BUFFER);
driveswitch(drive.type)
{
case NTFS:
break;
case FAT32:
.cluster = HexStringToLong(&BUFFER[0x0d],1);
drive.reversedSector=HexStringToLong(&BUFFER[0x0e],2);
drive.FATOffest = drive.reversedSector * SECTOR_LEN;
drive.FATSector = HexStringToLong(&BUFFER[0x24],4);
drive.rootOffset = drive.FATOffest + SECTOR_LEN * drive.FATSector *2;
drivebreak;
case UNKNOWN:
break;
}
.push_back(drive);
DriveList
if(show_analysis)
{
(512*(HexStringToLong(&GPT_PT[i*128+0x28],8)-HexStringToLong(&GPT_PT[i*128+0x20],8) ),buff );
ComfortableDataExpress(" 磁盘大小: %-10s |",buff );
printf(&GPT_PT[i*128+0x38],72,(unsigned char *)buff,true);
TranslateData=512*(HexStringToLong(&GPT_PT[i*128+0x20],8));
Offset(BUFFER,LODWORD(Offset),HIDWORD(Offset),1*SECTOR_LEN);
ReadDisk(BUFFER,1);
Analysis_Partition_Type(" GPT磁盘分区信息: %-30s |\n",buff);
printf
}
}
("\n");
printf}
/*------------------------------------------------------------------------------------------------*/
输出展示
输出结果:
主分区DPT分析:
活动分区标志: 00 | 分区类型标志: ee | 偏移扇区: 1 | 磁盘大小: 465.76 GB |
检测到该磁盘为GPT磁盘!
磁盘大小: 500.00 MB |分区格式:FAT32 | GPT磁盘分区信息: EFI system partition |
磁盘大小: 40.00 MB |分区格式:FAT32 | GPT磁盘分区信息: Basic data partition |
磁盘大小: 128.00 MB |分区格式:UNKNOWN | GPT磁盘分区信息: Microsoft reserved partition |
磁盘大小: 750.00 MB |分区格式:NTFS | GPT磁盘分区信息: Basic data partition |
磁盘大小: 188.96 GB |分区格式:NTFS | GPT磁盘分区信息: Basic data partition |
磁盘大小: 126.95 GB |分区格式:NTFS | GPT磁盘分区信息: Basic data partition |
磁盘大小: 69.71 GB |分区格式:NTFS | GPT磁盘分区信息: Basic data partition |
磁盘大小: 1023.50 KB |分区格式:NTFS | GPT磁盘分区信息: |
磁盘大小: 40.00 GB |分区格式:UNKNOWN | GPT磁盘分区信息: Basic data partition |
磁盘大小: 300.00 MB |分区格式:UNKNOWN | GPT磁盘分区信息: Basic data partition |
磁盘大小: 8.46 GB |分区格式:NTFS | GPT磁盘分区信息: Microsoft recovery partition |
磁盘大小: 30.00 GB |分区格式:UNKNOWN | GPT磁盘分区信息: |
分区个数:12
FAT32磁盘信息如下:
-------------------------------------------
分区序号:0
分区大小: 500.00 MB
分区偏移:1048576 字节
簇:8 个扇区
保留扇区:6206 个
FAT表偏移:3177472 字节
FAT表扇区:993 个
根目录偏移:4194304 字节
-------------------------------------------
分区序号:1
分区大小: 40.00 MB
分区偏移:525336576 字节
簇:1 个扇区
保留扇区:7038 个
FAT表偏移:3603456 字节
FAT表扇区:577 个
根目录偏移:4194304 字节
-------------------------------------------