#include <Windows.h>
#include <stdio.h>
#include <winioctl.h>
#include <malloc.h>
BOOL GetFileClusters(ULONGLONG ** Clusters, ULONG * ClusterSize, PCHAR lpFileName)
{
HANDLE hFile;
ULONG ClCount, FileSize;
ULONG OutSize;
ULONG Bytes, Cls, CnCount, r;
LARGE_INTEGER PrevVCN, Lcn;
STARTING_VCN_INPUT_BUFFER InBuf;
PRETRIEVAL_POINTERS_BUFFER OutBuf;
CHAR Name[7];
DWORD SecPerCl;
DWORD BtPerSec;
Name[0] = lpFileName[0];
Name[1] = ':';
Name[2] = 0;
GetDiskFreeSpace(Name, &SecPerCl, &BtPerSec, NULL, NULL);
*ClusterSize = SecPerCl * BtPerSec;
hFile = CreateFile(lpFileName, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
FileSize = GetFileSize(hFile, NULL);
OutSize = sizeof(RETRIEVAL_POINTERS_BUFFER) + (FileSize / *ClusterSize) * sizeof(OutBuf->Extents);
OutBuf = (RETRIEVAL_POINTERS_BUFFER *)malloc(OutSize);
InBuf.StartingVcn.QuadPart = 0;
if (DeviceIoControl(hFile, FSCTL_GET_RETRIEVAL_POINTERS, &InBuf,
sizeof(InBuf), OutBuf, OutSize, &Bytes, NULL))
{
ClCount = (FileSize + *ClusterSize - 1) / *ClusterSize;
*Clusters = (ULONGLONG *)malloc(ClCount * sizeof(ULONGLONG));
PrevVCN = OutBuf->StartingVcn;
for (r = 0, Cls = 0; r < OutBuf->ExtentCount; r++)
{
Lcn = OutBuf->Extents[r].Lcn;
for (CnCount = (ULONG)(OutBuf->Extents[r].NextVcn.QuadPart - PrevVCN.QuadPart); CnCount; CnCount--, Cls++, Lcn.QuadPart++)
(*Clusters)[Cls] = Lcn.QuadPart;
PrevVCN = OutBuf->Extents[r].NextVcn;
}
}else
{
free(OutBuf);
CloseHandle(hFile);
return FALSE;
}
}else
return FALSE;
return TRUE;
}
void Read(PCHAR lpSrcName)
{
ULONG ClusterSize, Bytes;
ULONGLONG *Clusters = 0;
HANDLE hDrive;
PVOID Buff;
LARGE_INTEGER Offset;
CHAR Name[7];
if (GetFileClusters(&Clusters, &ClusterSize, lpSrcName))
{
Name[0] = '\\';
Name[1] = '\\';
Name[2] = '.';
Name[3] = '\\';
Name[4] = lpSrcName[0];
Name[5] = ':';
Name[6] = 0;
hDrive = CreateFile(Name, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if (hDrive != INVALID_HANDLE_VALUE)
{
Buff = malloc(ClusterSize);
Offset.QuadPart = ClusterSize * Clusters[0];
SetFilePointer(hDrive, Offset.LowPart, &Offset.HighPart, FILE_BEGIN);
ReadFile(hDrive, Buff, ClusterSize, &Bytes, NULL);
printf("%s",Buff);
free(Buff);
CloseHandle(hDrive);
}
free(Clusters);
}
}
int main(int argc, char* argv[])
{
Read("D:\\test.rar");
return 0;
}
修改网上的代码 小弟对文件系统并不熟悉,上面的程序在ntfs文件系统可以正确的读取内容
可是在fat32文件系统却不行 读取的数据是错误的!
google,baidu好半天 是说
"RETRIEVAL_POINTERS_BUFFER 获得的 LCN 还要加上卷隐含扇区数,才是簇的绝对起始位置。这里的隐含扇区包括保留扇区、 2 个 FAT 表占用的扇区。"
这保留扇区和俩个FAT表怎么计算呢?
是不是计算结果加上RETRIEVAL_POINTERS_BUFFER的Extents域中的 LCN 就是该簇的绝对位置呢?
走过路过的哥哥们 麻烦说下


.... 谢谢啊
[培训]科锐逆向工程师培训第53期2025年7月8日开班!