
| 파일입출력 | 소켓 |
| 파일구조체생성 | 소켓 생성 |
| fopen() | connect() |
| read()/write() | read()/write() |
| close() | close() |
- 권영기

// 헤더 : ntfs.h
#pragma once
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
typedef BOOLEAN TF;
typedef UCHAR U8;
typedef USHORT U16;
typedef ULONG U32;
typedef ULONGLONG U64;
typedef struct {
U32 Type;
U16 UsaOffset;
U16 UsaCount;
U64 Usn;
} NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;
typedef struct {
NTFS_RECORD_HEADER Ntfs;
U16 SequenceNumber;
U16 LinkCount;
U16 AttributeOffset;
U16 Flags; // inUse 0x0001 Directory 0x0002
U32 BytesInUse;
U32 BytesAllocated;
U64 BaseFileRecord;
U16 NextAttributeNumber;
} FILE_RECORD_HEADR, *PFILE_RECORD_HEADER;
// Standard Attribute
typedef enum {
AttributeStandardInformation = 0x10,
AttributeAttributeList = 0x20,
AttributeFileName = 0x30,
AttributeObjectId = 0x40,
AttributeSecurityDesciptor = 0x50,
AttributeVolumeName = 0x60,
AttributeVolumeInformation = 0x70,
AttributeData = 0x80,
AttributeIndexRoot = 0x90,
AttributeIndexAllocation = 0xA0,
AttributeBitmap = 0xB0,
AttributeReparsePoint = 0xC0,
AttributeEAInformation = 0xD0,
AttributeEA = 0xE0,
AttributePropertySet = 0xF0,
AttributeLoggedUtilityStream = 0x100
} ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;
typedef struct {
ATTRIBUTE_TYPE AttributeType;
U32 Length;
TF Nonresident;
U8 NameLength;
U16 NameOffset;
U16 Flags;
U16 AttributeNumber;
} ATTRIBUTE, *PATTRIBUTE;
typedef struct {
ATTRIBUTE Attribute;
U32 ValueLength;
U16 ValueOffset;
U16 Flags;
} RESIDENT_ATTRIBUTE,*PRESIDENT_ATTRIBUTE;
#pragma pack(push, 1)
typedef struct {
U8 Jump[3];
U8 Format[8];
U16 BytesPerSector; //섹터당 바이트 수
U8 SectorsPerCluster; //섹터당 클러스터수
U16 BootSectors;
U8 Mbz1;
U16 Mbz2;
U16 Reserved1;
U8 MediaType;
U16 Mbz3;
U16 SectorsPerTrack;
U16 NumberOfHeads;
U32 PartitionOffset;
U32 Reserved2[2];
U64 TotalSectors; //디스크의 총 섹터수.
U64 MftStartLcn; //MFT가 시작되는 주소.
U64 Mft2StartLcn; // MFT Mirror 부분이 시작되는 주소
U32 ClustersPerFileRecord; // 파일 레코드당 클러스터수
U32 ClustersPerIndexBlock; // 인덱스 블럭당 클러스터수
U64 VolumeSerialNumber;
U8 Code[0x1AE];
U16 BootSignature;
} BOOT_BLOCK, *PBOOT_BLOCK;
#pragma pack(pop)
- main.cpp
#include "ntfs.h"
U32 BytesPerFileRecord;
BOOT_BLOCK boot_block;
HANDLE hVolume;
U32 cnt;
CHAR drive[] = "\\\\.\\C:";
PFILE_RECORD_HEADER MFT;
void ReadSector(U64 sector, U32 count, void* buffer);
void LoadMFT();
void main()
{
hVolume = CreateFile(drive, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, 0,OPEN_EXISTING, 0, 0);
ReadFile(hVolume, &boot_block, sizeof(boot_block), &cnt, 0);
printf("======My FILE SYSTEM INFO==========\n");
printf("File System : %s \n",boot_block.Format);
printf("Total Sectors : %u \n",boot_block.TotalSectors);
printf("Sector per Bytes : %u \n",boot_block.BytesPerSector);
printf("Cluster per Sectors : %u\n",boot_block.SectorsPerCluster);
printf("Clusters Per FileRecord : %u\n",boot_block.ClustersPerFileRecord);
printf("Clusters Per IndexBlock : %u\n",boot_block.ClustersPerIndexBlock);
}
void LoadMFT()
{
BytesPerFileRecord = boot_block.ClustersPerFileRecord < 0x80? boot_block.ClustersPerFileRecord* boot_block.SectorsPerCluster* boot_block.BytesPerSector : 1 << (0x100 - boot_block.ClustersPerFileRecord);
MFT = PFILE_RECORD_HEADER(new U8[BytesPerFileRecord]);
ReadSector(boot_block.MftStartLcn * boot_block.SectorsPerCluster, BytesPerFileRecord / boot_block.BytesPerSector, MFT);
printf("buffer : %s\n", MFT+0x27);
}
void ReadSector(U64 sector, U32 count, void* buffer)
{
ULARGE_INTEGER offset;
OVERLAPPED overlap = {0};
U32 n;
offset.QuadPart = sector * boot_block.BytesPerSector;
overlap.Offset = offset.LowPart;
overlap.OffsetHigh = offset.HighPart;
ReadFile(hVolume, buffer, count * boot_block.BytesPerSector, &n, &overlap);
}
#include "ntfs.h"
U32 BytesPerFileRecord;
BOOT_BLOCK boot_block;
HANDLE hVolume;
U32 cnt;
CHAR drive[] = "\\\\.\\C:";
//WCHAR drive[] = TEXT("\\\\.\\C:");
PFILE_RECORD_HEADER MFT;
void ReadSector(U64 sector, U32 count, void* buffer);
void LoadMFT();
void main()
{
hVolume = CreateFile(drive, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, 0,OPEN_EXISTING, 0, 0);
ReadFile(hVolume, &boot_block, sizeof(boot_block), &cnt, 0);
// FILE *fp=fopen(drive,"rb");
// fread((void*)&boot_block,sizeof(boot_block),1,fp);
printf("======My FILE SYSTEM INFO==========\n");
printf("File System : %s \n",boot_block.Format);
printf("Total Sectors : %u \n",boot_block.TotalSectors);
printf("Sector per Bytes : %u \n",boot_block.BytesPerSector);
printf("Cluster per Sectors : %u\n",boot_block.SectorsPerCluster);
printf("Clusters Per FileRecord : %u\n",boot_block.ClustersPerFileRecord);
printf("Clusters Per IndexBlock : %u\n",boot_block.ClustersPerIndexBlock);
printf("\n\n");
LoadMFT();
}
void LoadMFT()
{
int i;
BytesPerFileRecord = boot_block.ClustersPerFileRecord < 0x80? boot_block.ClustersPerFileRecord* boot_block.SectorsPerCluster* boot_block.BytesPerSector : 1 << (0x100 - boot_block.ClustersPerFileRecord);
MFT = PFILE_RECORD_HEADER(new U8[BytesPerFileRecord]);
ReadSector(boot_block.MftStartLcn * boot_block.SectorsPerCluster, BytesPerFileRecord / boot_block.BytesPerSector, MFT);
printf("$MFT's Signaturer : %s\n", MFT);//+0x27);
printf("Offset to fixup array : 0x%02x%02x\n", *((unsigned char*)MFT+5),*((unsigned char*)MFT+4));
printf("Number of this MFT Entry : 0x%02x%02x%02x%02x\n"
, *((unsigned char*)MFT+47),*((unsigned char*)MFT+46),*((unsigned char*)MFT+45),*((unsigned char*)MFT+44));
printf("Offset to first attribute : 0x%02x%02x \n"
, *((unsigned char*)MFT+21),*((unsigned char*)MFT+20));
i=((int)(*((unsigned char*)MFT+21))<<8)+*((unsigned char*)MFT+20);//Offset으로 포인터 이동
printf("First Attribute : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
i+=4;//속성값의 4바이트 이동
printf("First Attribute Size : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
printf("\n");
i= i+
((int)(*((unsigned char*)MFT+i+3))<<24)+
((int)(*((unsigned char*)MFT+i+2))<<16)+
((int)(*((unsigned char*)MFT+i+1))<<8)+
*((unsigned char*)MFT+i)
-4;//사이즈를 읽기위해 사용한 4바이트를 제외한다.
printf("Second Attribute : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
i+=4;//속성값의 4바이트 이동
printf("Second Attribute Size : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
printf("\n");
i= i+
((int)(*((unsigned char*)MFT+i+3))<<24)+
((int)(*((unsigned char*)MFT+i+2))<<16)+
((int)(*((unsigned char*)MFT+i+1))<<8)+
*((unsigned char*)MFT+i)
-4;//사이즈를 읽기위해 사용한 4바이트를 제외한다.
printf("Third Attribute : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
i+=4;//속성값의 4바이트 이동
printf("Third Attribute Size : 0x%02x%02x%02x%02x\n",*((unsigned char*)MFT+i+3),*((unsigned char*)MFT+i+2),*((unsigned char*)MFT+i+1),*((unsigned char*)MFT+i));
printf("\n");
/*
ReadSector(boot_block.Mft2StartLcn * boot_block.SectorsPerCluster, BytesPerFileRecord / boot_block.BytesPerSector, MFT);
printf("$MFT Mirr's Signaturer : %s\n", MFT);//+0x27);
printf("Offset to fixup array : 0x%02x%02x\n", *((unsigned char*)MFT+5),*((unsigned char*)MFT+4));
printf("Number of this MFT Entry : 0x%02x%02x%02x%02x\n"
, *((unsigned char*)MFT+47),*((unsigned char*)MFT+46),*((unsigned char*)MFT+45),*((unsigned char*)MFT+44));
printf("\n");
//*/
printf("MftStartLcn : %d\n",boot_block.MftStartLcn);
printf("Mft2StartLcn : %d\n",boot_block.Mft2StartLcn);
}
void ReadSector(U64 sector, U32 count, void* buffer)
{
ULARGE_INTEGER offset;
OVERLAPPED overlap = {0};
U32 n;
offset.QuadPart = sector * boot_block.BytesPerSector;
overlap.Offset = offset.LowPart;
overlap.OffsetHigh = offset.HighPart;
ReadFile(hVolume, buffer, count * boot_block.BytesPerSector, &n, &overlap);
}
#include "ntfs.h"
U32 BytesPerFileRecord;
BOOT_BLOCK boot_block;
HANDLE hVolume;
U32 cnt;
CHAR drive[] = "\\\\.\\C:";
//WCHAR drive[] = TEXT("\\\\.\\C:");
PFILE_RECORD_HEADER MFT;
void ReadSector(U64 sector, U32 count, void* buffer);
void LoadMFT();
unsigned int LoadAttribute(int i);
unsigned __int64 htonll(unsigned __int64);
unsigned int htonl(unsigned int);
//unsigned short htons(unsigned short);
void main()
{
hVolume = CreateFile(drive, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, 0,OPEN_EXISTING, 0, 0);
ReadFile(hVolume, &boot_block, sizeof(boot_block), &cnt, 0);
// FILE *fp=fopen(drive,"rb");
// fread((void*)&boot_block,sizeof(boot_block),1,fp);
printf("======My FILE SYSTEM INFO==========\n");
printf("File System : %s \n",boot_block.Format);
printf("Total Sectors : %u \n",boot_block.TotalSectors);
printf("Sector per Bytes : %u \n",boot_block.BytesPerSector);
printf("Cluster per Sectors : %u\n",boot_block.SectorsPerCluster);
printf("Clusters Per FileRecord : %u\n",boot_block.ClustersPerFileRecord);
printf("Clusters Per IndexBlock : %u\n",boot_block.ClustersPerIndexBlock);
printf("\n\n");
LoadMFT();
system("pause");
}
void LoadMFT()
{
int point;
unsigned __int64 num;
BytesPerFileRecord = boot_block.ClustersPerFileRecord < 0x80? boot_block.ClustersPerFileRecord* boot_block.SectorsPerCluster* boot_block.BytesPerSector : 1 << (0x100 - boot_block.ClustersPerFileRecord);
MFT = PFILE_RECORD_HEADER(new U8[BytesPerFileRecord]);
printf("MftStartLcn : %016x\n",boot_block.MftStartLcn);
printf("Mft2StartLcn : %016x\n",boot_block.Mft2StartLcn);
printf("\n");
//0 대신 값을 대입하면 다른 MFT entry를 볼 수 있음.
ReadSector((boot_block.MftStartLcn+0) * boot_block.SectorsPerCluster, BytesPerFileRecord / boot_block.BytesPerSector, MFT);
printf("MFT's Signaturer : %s\n", MFT);//+0x27);
printf("Offset to fixup array : 0x%02x%02x\n", *((unsigned char*)MFT+5),*((unsigned char*)MFT+4));
printf("Number of this MFT Entry : 0x%02x%02x%02x%02x\n"
, *((unsigned char*)MFT+47),*((unsigned char*)MFT+46),*((unsigned char*)MFT+45),*((unsigned char*)MFT+44));
printf("Offset to first attribute : 0x%02x%02x \n"
, *((unsigned char*)MFT+21),*((unsigned char*)MFT+20));
printf("\n");
point=((int)(*((unsigned char*)MFT+21))<<8)+*((unsigned char*)MFT+20);//Offset으로 포인터 이동
printf("Attribute List Start\n\n");
while(htonl(*((unsigned int*)((unsigned char*)MFT+point)))!=0xFFFFFFFF)
point+=LoadAttribute(point);
printf("Attribute List End\n");
printf("\n");
}
unsigned int LoadAttribute(int point)
{
int i=0,j=0,k=0;
int HeaderSize;
/*
*((unsigned char*)MFT+i+9) = Attribute Name Size
Resident=24 / Non-resident=64
*/
if(*((unsigned char*)MFT+point+8))
HeaderSize=64+*((unsigned char*)MFT+point+9);
else
HeaderSize=24+*((unsigned char*)MFT+point+9);
switch(htonl(*((unsigned int*)((unsigned char*)MFT+point))))
{
case 0x10://$STANDARD_INFORMATION
printf("Attribute type : Standard Information\n");
break;
case 0x20://$ATTRIBUTE_LIST
printf("Attribute type : Attribute List\n");
break;
case 0x30://$FILE_NAME
printf("Attribute type : File Name\n");
printf("File Name Size : %d\n",*((unsigned char*)MFT+point+HeaderSize+64));
printf("File NameSpace : ");
switch(*((unsigned char*)MFT+point+HeaderSize+65))
{
case 0:
printf("POSIX\n");
break;
case 1:
printf("Win32\n");
break;
case 2:
printf("DOS\n");
break;
case 3:
printf("Win32 & DOS\n");
break;
}
printf("File Name : ");
for(j=0;j<2**((unsigned char*)MFT+point+HeaderSize+64);j++)
printf("%c",*((unsigned char*)MFT+point+HeaderSize+66+j));
printf("\n");
break;
case 0x40://$
printf("Attribute type : \n");
break;
case 0x50://$SECURITY_DESCRIPTOR
printf("Attribute type : Security Descriptor\n");
break;
case 0x60://$
printf("Attribute type : \n");
break;
case 0x70://$
printf("Attribute type : \n");
break;
case 0x80://$DATA
printf("Attribute type : Data\n");
//__int64는 메모리상에 little endian식으로 저장됨. 왜인지 이해가 안 가지만...
printf("Run List Start VCN : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+16)));
printf("Run List End VCN : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+24)));
printf("Run List Start Offset : 0x%02x%02x\n",*((unsigned char*)MFT+point+33),*((unsigned char*)MFT+point+32));
// printf("Cluster Size : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+40)));
// printf("Attribute Size : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+48)));
// printf("real Size : %I64d\n",*((unsigned __int64*)((unsigned char*)MFT+point+56)));
i=(int)*((unsigned char*)MFT+point+33)+*((unsigned char*)MFT+point+32);
for(j=0;j<(*((unsigned char*)MFT+point+i)&0x0F);j++)//*((unsigned __int64*)((unsigned char*)MFT+point+24));j++)
{
printf("Cluster %d lenth : 0x",j);
for(k=0;k<(*((unsigned char*)MFT+point+i)&0x0F);k++)
printf("%02x",*((unsigned char*)MFT+point+i+(*((unsigned char*)MFT+point+i)&0x0F)-k));
printf("\n");
printf("Cluster %d offset : 0x",j);
for(;k<(*((unsigned char*)MFT+point+i)&0x0F)+((*((unsigned char*)MFT+point+i)&0xF0)>>4);k++)
printf("%02x",*((unsigned char*)MFT+point+i
+(*((unsigned char*)MFT+point+i)&0x0F)+((*((unsigned char*)MFT+point+i)&0xF0)>>4)
-k+(*((unsigned char*)MFT+point+i)&0x0F)));
printf("\n");
i+=(*((unsigned char*)MFT+point+i)&0x0F)+((*((unsigned char*)MFT+point+i)&0xF0)>>4)+1;
}
break;
case 0xB0:
printf("Attribute type : Bitmap\n");
break;
}
printf("\n");
return htonl(*((unsigned int*)((unsigned char*)MFT+point+4)));
}
void ReadSector(U64 sector, U32 count, void* buffer)
{
ULARGE_INTEGER offset;
OVERLAPPED overlap = {0};
U32 n;
offset.QuadPart = sector * boot_block.BytesPerSector;
overlap.Offset = offset.LowPart;
overlap.OffsetHigh = offset.HighPart;
ReadFile(hVolume, buffer, count * boot_block.BytesPerSector, &n, &overlap);
}
unsigned __int64 htonll(unsigned __int64 LittleEndian)
{
unsigned __int64 BigEndian;
int i;
LittleEndian>>=16;
BigEndian=0;
BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+7))<<54;
BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+6))<<48;
BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+5))<<40;
BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+4))<<32;
BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+3))<<24;
BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+2))<<16;
BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+1))<<8;
BigEndian+=(unsigned __int64)(*((unsigned char*)&LittleEndian+0));
return BigEndian;
}
unsigned int htonl(unsigned int LittleEndian)
{
unsigned int BigEndian;
BigEndian=
((unsigned int)(*((unsigned char*)&LittleEndian+3))<<24)+
((unsigned int)(*((unsigned char*)&LittleEndian+2))<<16)+
((unsigned int)(*((unsigned char*)&LittleEndian+1))<<8)+
*((unsigned char*)&LittleEndian)
;
return BigEndian;
}
/*
unsigned short htons(unsigned short LittleEndian)
{
unsigned short BigEndian;
BigEndian=
((unsigned short)(*((unsigned char*)&LittleEndian+1))<<8)+
*((unsigned char*)&LittleEndian)
;
return BigEndian;
}
/*/