SetFilePointerEx API读取MFT

发布于 2024-12-19 08:18:28 字数 3830 浏览 1 评论 0原文

我想从分区上的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

还如梦归 2024-12-26 08:18:28

我可以看到以下错误:

  • 您没有检查 CreateFile 的返回值是否成功。
  • 您向 ReadFile 的第一个参数传递了错误的内容。您需要将句柄传递给文件。
  • 您使用了您不想要的重叠 I/O,并且该 I/O 无法与编组的 byte[] 缓冲区一起使用。传递 IntPtr.ZerolpOverlappednull,具体取决于 P/invoke 的声明方式。
  • ReadFile 不返回句柄,它返回一个表示函数调用成功的布尔值。
  • 您绝不能从托管代码中调用 GetLastError。而是调用 Marshal.GetLastWin32Error文档中解释了原因对于该方法。
  • 除非先前的 API 调用实际上失败,否则请勿调用 Marshal.GetLastWin32Error。您没有检查是否 SetFilePointerEx 成功。就像ReadFile一样,它返回一个布尔值来指示成功或失败。

I can see the following errors:

  • You are not checking the return value of CreateFile for success or failure.
  • You are passing the wrong thing to the first parameter of ReadFile. You need to pass the handle to the file.
  • You use overlapped I/O which you do not want, and which cannot work with a marshalled byte[] buffer. Pass IntPtr.Zero for lpOverlapped or perhaps null depending on how your P/invoke is declared.
  • ReadFile does not return a handle, it returns a boolean indicating success of the function call.
  • You must never call GetLastError from managed code. Instead call Marshal.GetLastWin32Error. The reasons are explained in the documentation for that method.
  • Do not call Marshal.GetLastWin32Error unless the prior API call actually failed. You did not check whether or not SetFilePointerEx succeeded. Just like ReadFile, it returns a boolean to indicate success or failure.
懵少女 2024-12-26 08:18:28

根据文档物理磁盘和卷部分),如果要访问分区表,则必须使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文