FDump - 使用逻辑偏移量直接从磁盘转储文件扇区






4.89/5 (23投票s)
关于使用逻辑偏移量直接从磁盘读取文件扇区的文章

引言
此源代码演示了如何使用逻辑偏移量直接从磁盘读取文件扇区进行转储。它大量使用了 FSCTL_GET_RETRIEVAL_POINTERS
IO 控制代码。有关 FSCTL_GET_RETRIEVAL_POINTERS
IO 控制代码的完整说明,请参阅 Mark Roddy 的文章 "Adventures in Luserland: Finding Disk Sectors Associated with File Records" 以及 MSDN。
背景
最近,我发现了 Windows 注册表格式规范,并想探索“原始” Windows 注册表文件。但是,我发现其中一些文件被系统(操作系统)本身锁定了。我想在不重启系统并从其他操作系统启动的情况下转储这些文件,并寻找解决方案。我在网上找到了一些关于使用 FSCTL_GET_RETRIEVAL_POINTERS
IO 控制代码获取卷逻辑偏移量的示例,但没有一个支持 FAT,而且没有一个具有正确的错误处理。我想要一个“一站式”解决方案,因此我根据几篇文章的起点,编写了自己的文件转储实现,该实现支持 Windows 使用的所有文件系统。
Using the Code
提供了几个 API 以方便用户转储文件扇区。调用顺序如下:
FsGetFileInfo()
FsGetVolumeInfo()
FsGetFileExtents()
// Here you should iterate through extents returned by FsGetFileExtents(),
// read and dump the raw sectors of the volume. For the complete
// sample see FsSectorCopy() implementation.
FsFreeFileInfo()
FsFreeVolumeInfo()
如果您不想使用这些 API,还有一个已实现的函数可以完成您需要的所有工作 - FsSectorCopy()
,它会调用上述 API。该函数的简短文档如下:
STDAPI_( BOOL )
FsSectorCopy(
IN LPCTSTR pszSrcFileName,
IN LPCTSTR pszDstFileName,
IN FS_CALLBACK_DATA* pCallbackData
);
函数参数
pszSrcFileName
- 要转储的源文件路径pszDstFileName
- 要将文件扇区转储到的目标文件路径pCallbackData
- 回调数据(可选)
回调数据结构(pCallbackData)
声明如下:
typedef struct _FS_CALLBACK_DATA
{
PFNFS_PROGRESS_CALLBACK pfnFsProgress;
HANDLE hEventBreak;
LPCVOID lpUserParam;
} FS_CALLBACK_DATA;
回调数据结构的成员
pfnFsProgress
- 指向进度回调函数的指针,该函数在FsSectorCopy()
执行期间被调用,以指示其进度。hEventBreak
- 可用于停止FsSectorCopy()
函数执行的事件。此变量必须在调用FsSectorCopy()
之前初始化。lpUserParam
- 传递给进度回调函数(pfnFsProgress)
的用户参数。
请注意,进度回调函数(pfnFsProgress
)可能会根据操作类型和总体完成百分比调用多次。进度回调函数(pfnFsProgress
)声明如下:
typedef BOOL ( CALLBACK* PFNFS_PROGRESS_CALLBACK )
(
IN LPCVOID lpUserParam,
IN DWORD dwJobType,
IN BOOL bJobDone,
IN LPCVOID lpJobContext,
IN DWORD dwPercentComplete
);
回调函数参数
lpUserParam
- 传递给FsSectorCopy()
在回调数据结构lpUserParam
成员中的用户参数。dwJobType
- 当前执行的操作类型。操作类型及其上下文在下一节中列出。bJobDone
- 指示操作成功或失败的布尔值。如果操作失败,您可以在系统消息表中查找最后一个错误描述。lpJobContext
- 操作上下文,其类型取决于dwJobType
。操作类型及其上下文在下一节中列出。dwPercentComplete
- 操作总体的完成百分比。
传递给进度回调函数的]操作类型和上下文
FS_JOB_GET_SRC_VOLUME_INFO
- 进度回调函数将使用此操作类型调用一次,以指示FsSectorCopy()
函数正在获取源卷信息。进度函数的lpJobContext
参数是指向FS_VOLUME_INFO
结构的指针。结构声明未在此处显示,应在源代码中查找。dwPercentComplete
为 0。FS_JOB_GET_SRC_FILE_INFO
- 进度回调函数将使用此操作类型调用一次,以指示FsSectorCopy()
函数正在获取源文件信息。进度函数的lpJobContext
参数是指向FS_FILE_INFO
结构的指针。结构声明未在此处显示,应在源代码中查找。dwPercentComplete
为 0。FS_JOB_GET_SRC_FILE_EXTENTS
- 进度回调函数将使用此操作类型调用一次,以指示FsSectorCopy()
函数正在获取源文件范围。进度函数的lpJobContext
参数为空。dwPercentComplete
为 0。FS_JOB_GET_SRC_FILE_MFT
- 进度回调函数将使用此操作类型调用一次,以指示FsSectorCopy()
函数正在从 MFT 获取源文件(如果它太小而无法占用整个群集)。进度函数的lpJobContext
参数为空。dwPercentComplete
为 0。FS_JOB_CREATE_FILE_DST
- 进度回调函数将使用此操作类型调用一次,以指示FsSectorCopy()
函数正在创建目标文件。进度函数的lpJobContext
参数为空。dwPercentComplete
为 0。FS_JOB_COPY_DATA_FROM_MFT
- 进度回调函数将使用此操作类型调用一次,以指示FsSectorCopy()
函数正在将文件数据从 MFT 转储到目标文件。进度函数的lpJobContext
参数为空。dwPercentComplete
为 0。FS_JOB_COPY_DATA_FROM_DISK
- 使用此操作类型,进度回调函数会多次调用,以指示FsSectorCopy()
函数正在将源文件扇区转储到目标文件。进度函数的lpJobContext
参数是 LCN(逻辑簇)号。dwPercentComplete
会根据复制的扇区进度从 0 增加到 100。
有关更多信息,请参阅源代码。
系统要求
- 支持的平台:Windows 2000 Workstation/Servers 及更高版本(XP/2003 Servers, Vista/2008 Servers)。
- 所需用户权限:用户必须以管理员身份启动应用程序才能使用它。
- 支持的文件系统:目前应用程序支持 FAT12/16/32 和 NTFS。还有一个由 Microsoft 为闪存驱动器创建的新文件系统,称为 exFAT。它随 Microsoft Windows Vista SP1(可能还有 Windows 2008)引入。不幸的是,我未能找到任何 exFAT 规范,因此该应用程序不支持它。
- 非标准磁盘:应用程序应能在条带化和镜像磁盘上运行(个人在我的 SATAII RAID0 条带化上进行了测试)。如果出现错误,请向我报告以改进应用程序的行为。
- 大文件支持:我个人转储了约 5GB 的大型图像文件,并与原始文件进行了比较。但是,大文件可能会出现错误(尽管不应该出现),请报告。
已知限制
- 目前不支持压缩卷、压缩文件和稀疏文件。
- exFAT 文件系统不受支持。
- 该程序支持 64 位平台编译。但是我没有在 Windows x64 上进行测试。
重要提示:如果有人拥有有关上述问题的有用信息或解决方案,请分享。
参考文献
- Direct Copy Method by Napalm (听起来像黑客的名字)
- “将逻辑偏移量转换为物理偏移量” by Omri Shaked
- FAT32 文件系统规范 by Microsoft Corporation
- “Adventures in Luserland: Finding Disk Sectors Associated with File Records” by Mark Roddy
- DOSFS Embedded FAT-Compatible Filesystem by Andreas R. Fugl
- MSDN 上的 FSCTL_GET_RETRIEVAL_POINTERS 控制代码
历史
- 2008年9月1日
- 应用程序的初始版本
- 2008年10月22日
- 应用程序的最终版本
- 2008年12月27日
- 将文章提交给 The Code Project
- 2009年1月5日
- 两次小错误修复(感谢 marcosvelasco)