SetFilePointerEx API读取MFT
我想从分区上的 MFT 偏移量读取一些字节。我获得分区句柄并成功读取前 1K 字节,但 SetFilePointerEx
返回错误。请帮我解决一下。
int nread = 0;
IntPtr handle = IntPtr.Zero;
byte[] buff = new byte[1024];
IntPtr newaddress = IntPtr.Zero;
long MFTAddress = bytepersector * sectorpercluster * (long)MFTStart;
string driveRoot = "\\\\.\\c:";
IntPtr hRoot = CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
SetFilePointerEx(hRoot, MFTAddress, ref newaddress, 0);
int error = GetLastError();
if (hRoot != IntPtr.Zero)
handle = ReadFile(newaddress, buff, 1024,ref nread, new System.Threading.NativeOverlapped());
这是找到 MFTOffset 和其他信息的代码。
uint nread = 0;
IntPtr handle;
byte[] buff = new byte[1024];
string driveRoot = string.Concat("\\\\.\\", driveLetter);
IntPtr hRoot = CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hRoot != IntPtr.Zero)
ReadFile(hRoot, buff, 1024,out nread, IntPtr.Zero);
string SystemFile = Convert.ToString(LittleEndian(4, new byte[] { buff[3], buff[4], buff[5], buff[6] }, typeof(string)));
int BytePerSector = 0;
int SectorPerCluster = 0;
double MFTStart = 0;
if (SystemFile == "NTFS")
{
listBox1.Items.Add(SystemFile);
BytePerSector = (int)LittleEndian(2, new byte[] { buff[11], buff[12] }, BytePerSector.GetType());
listBox1.Items.Add("Byte per Sector : " + BytePerSector);
SectorPerCluster = (int)LittleEndian(1, new byte[] { buff[13] }, typeof(int));
listBox1.Items.Add("Sector per Cluster : " + SectorPerCluster.ToString());
MFTStart = (long)LittleEndian(8, new byte[]{
buff[48],buff[49],buff[50],buff[51],buff[52],buff[53],buff[54],buff[55]}, typeof(long));
listBox1.Items.Add("MFT LCN : " + MFTStart);
}
else
listBox1.Items.Add("No NTFS Valoume");
我想读取 MFT。我发现它在分区上的偏移量。我使用 CreateFile API 获取了分区句柄,然后我使用 ReadFile API 从 MBR 获取了 MFT 偏移量。我将结果与 WinHex 进行了比较,结果是正确的。现在我想移动到分区上的 mft 地址。我发现 SetFilePointer API 可以做到这一点。 我使用 SetFilePointer 但在使用 ReadFile(newAddress) 时出现错误
public static void ReadMFT(string DriveLetter, ulong MFTStart, int bytepersector, int sectorpercluster)
{
IntPtr handle = IntPtr.Zero;
IntPtr newaddress = IntPtr.Zero;
long MFTAddress = bytepersector * sectorpercluster * (long)MFTStart;
string driveRoot = string.Concat("\\\\.\\", DriveLetter);
IntPtr hRoot = CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
**newaddress = SetFilePointer(hRoot, (ulong)MFTAddress, IntPtr.Zero, 0);**
Console.WriteLine("hroot : " + hRoot.ToString());
Console.WriteLine("MFTAddress : " + MFTAddress.ToString());
Console.WriteLine("NewAddress : " + newaddress.ToString());
if (hRoot.ToInt64() != INVALID_HANDLE_VALUE)
{
uint nread;
byte[] buff = new byte[1024];
if (**ReadFile(newaddress, buff, (uint)buff.Length, out nread, IntPtr.Zero)**)
Console.WriteLine("Read successful");
else
Console.WriteLine("Read unsuccessful");
}
while (true)
{
//read other MFT Record
break;
}
}
I want to read some bytes from MFT offset on a partition. I got partition handle and read first 1K bytes successfully, but SetFilePointerEx
returns an error. Please help me with it.
int nread = 0;
IntPtr handle = IntPtr.Zero;
byte[] buff = new byte[1024];
IntPtr newaddress = IntPtr.Zero;
long MFTAddress = bytepersector * sectorpercluster * (long)MFTStart;
string driveRoot = "\\\\.\\c:";
IntPtr hRoot = CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
SetFilePointerEx(hRoot, MFTAddress, ref newaddress, 0);
int error = GetLastError();
if (hRoot != IntPtr.Zero)
handle = ReadFile(newaddress, buff, 1024,ref nread, new System.Threading.NativeOverlapped());
this is code that found MFTOffset and other information.
uint nread = 0;
IntPtr handle;
byte[] buff = new byte[1024];
string driveRoot = string.Concat("\\\\.\\", driveLetter);
IntPtr hRoot = CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hRoot != IntPtr.Zero)
ReadFile(hRoot, buff, 1024,out nread, IntPtr.Zero);
string SystemFile = Convert.ToString(LittleEndian(4, new byte[] { buff[3], buff[4], buff[5], buff[6] }, typeof(string)));
int BytePerSector = 0;
int SectorPerCluster = 0;
double MFTStart = 0;
if (SystemFile == "NTFS")
{
listBox1.Items.Add(SystemFile);
BytePerSector = (int)LittleEndian(2, new byte[] { buff[11], buff[12] }, BytePerSector.GetType());
listBox1.Items.Add("Byte per Sector : " + BytePerSector);
SectorPerCluster = (int)LittleEndian(1, new byte[] { buff[13] }, typeof(int));
listBox1.Items.Add("Sector per Cluster : " + SectorPerCluster.ToString());
MFTStart = (long)LittleEndian(8, new byte[]{
buff[48],buff[49],buff[50],buff[51],buff[52],buff[53],buff[54],buff[55]}, typeof(long));
listBox1.Items.Add("MFT LCN : " + MFTStart);
}
else
listBox1.Items.Add("No NTFS Valoume");
I wanna read MFT.I found its offset on partition.i got partition handle with CreateFile API then i got MFT offset from MBR with ReadFile API.i compared result with WinHex and result was correct.now i wanna move to mft address on partition.i found SetFilePointer API to do it.
i used SetFilePointer but i got error while use ReadFile(newAddress)
public static void ReadMFT(string DriveLetter, ulong MFTStart, int bytepersector, int sectorpercluster)
{
IntPtr handle = IntPtr.Zero;
IntPtr newaddress = IntPtr.Zero;
long MFTAddress = bytepersector * sectorpercluster * (long)MFTStart;
string driveRoot = string.Concat("\\\\.\\", DriveLetter);
IntPtr hRoot = CreateFile(driveRoot,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
IntPtr.Zero,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
**newaddress = SetFilePointer(hRoot, (ulong)MFTAddress, IntPtr.Zero, 0);**
Console.WriteLine("hroot : " + hRoot.ToString());
Console.WriteLine("MFTAddress : " + MFTAddress.ToString());
Console.WriteLine("NewAddress : " + newaddress.ToString());
if (hRoot.ToInt64() != INVALID_HANDLE_VALUE)
{
uint nread;
byte[] buff = new byte[1024];
if (**ReadFile(newaddress, buff, (uint)buff.Length, out nread, IntPtr.Zero)**)
Console.WriteLine("Read successful");
else
Console.WriteLine("Read unsuccessful");
}
while (true)
{
//read other MFT Record
break;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我可以看到以下错误:
CreateFile
的返回值是否成功。ReadFile
的第一个参数传递了错误的内容。您需要将句柄传递给文件。byte[]
缓冲区一起使用。传递IntPtr.Zero
为lpOverlapped
或null
,具体取决于 P/invoke 的声明方式。ReadFile
不返回句柄,它返回一个表示函数调用成功的布尔值。GetLastError
。而是调用Marshal.GetLastWin32Error
。 文档中解释了原因对于该方法。Marshal.GetLastWin32Error
。您没有检查是否SetFilePointerEx
成功。就像ReadFile
一样,它返回一个布尔值来指示成功或失败。I can see the following errors:
CreateFile
for success or failure.ReadFile
. You need to pass the handle to the file.byte[]
buffer. PassIntPtr.Zero
forlpOverlapped
or perhapsnull
depending on how your P/invoke is declared.ReadFile
does not return a handle, it returns a boolean indicating success of the function call.GetLastError
from managed code. Instead callMarshal.GetLastWin32Error
. The reasons are explained in the documentation for that method.Marshal.GetLastWin32Error
unless the prior API call actually failed. You did not check whether or notSetFilePointerEx
succeeded. Just likeReadFile
, it returns a boolean to indicate success or failure.根据文档 (物理磁盘和卷部分),如果要访问分区表,则必须使用
DeviceIoControl
< /a>.从 Windows Vista 开始,限制和要求适用。从文档链接的示例: 调用DeviceIoControl。
As per documentation (section Physical Disks and Volumes), if you want to access the partition table, you must use
DeviceIoControl
. Restrictions and requirements apply starting from Windows Vista.An example linked from the documentation: Calling DeviceIoControl.