本文介绍了SetFilePointerEx API来读取MFT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想读一些字节从MFT偏移上的分区。我得到了分区处理,并成功地读取前1K字节,但 SetFilePointerEx 返回一个错误。请大家帮帮我吧。

  INT NREAD = 0;
IntPtr的处理= IntPtr.Zero;
byte []的BUFF =新的字节[1024];
IntPtr的newaddress = IntPtr.Zero;
长MFTAddress = bytepersector * sectorpercluster *(长)MFTStart;
字符串driveRoot =\\\\。\\ C:;

IntPtr的HR管理世界=的CreateFile(driveRoot,
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    IntPtr.Zero,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    IntPtr.Zero);

SetFilePointerEx(HR管理世界,MFTAddress,裁判newaddress,0);

INT错误= GetLastError函数();
如果(HR管理世界!= IntPtr.Zero)
    处理= ReadFile的(newaddress,浅黄色,1024,裁判NREAD,新System.Threading.NativeOverlapped());
 


这是code表示发现MFTOffset和其他信息。

  UINT NREAD = 0;
        IntPtr的手柄;
        byte []的BUFF =新的字节[1024];
        字符串driveRoot = string.Concat(\\\\。\\,驱动器号);
        IntPtr的HR管理世界=的CreateFile(driveRoot,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            IntPtr.Zero,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            IntPtr.Zero);
        如果(HR管理世界!= IntPtr.Zero)
             ReadFile的(HR管理世界,浅黄色,1024,出NREAD,IntPtr.Zero);
        串system文件= Convert.ToString(LittleEndian(4,新字节[] {抛光轮[3],抛光轮[4],浅黄色[5],浅黄色[6]}的typeof(字符串)));
        INT BytePerSector = 0;
        INT SectorPerCluster = 0;
        双MFTStart = 0;
        如果(system文件==NTFS)
        {
            listBox1.Items.Add(system文件);

            BytePerSector =(int)的LittleEndian(2,新的字节[] {抛光轮[11],浅黄色[12]},BytePerSector.GetType());
            listBox1.Items.Add(每个扇区字节:+ BytePerSector);

            SectorPerCluster =(INT)LittleEndian(1,新的byte [] {BUFF [13]}的typeof(INT));
            listBox1.Items.Add(每群集扇区:+ SectorPerCluster.ToString());

            MFTStart =(长)LittleEndian(8,新的byte [] {
                BUFF [48],BUFF [49],BUFF [50],BUFF [51],BUFF [52],BUFF [53],BUFF [54],BUFF [55]}的typeof(长));
            listBox1.Items.Add(MFT LCN:+ MFTStart);

        }
        其他
            listBox1.Items.Add(否NTFS Valoume);
 

我想读MFT.I发现其对partition.i抵消了分区手柄的CreateFile API,然后我得到的MFT从MBR偏移ReadFile的API.i比较的结果与WinHex中,并因此被correct.now我想移动到MFT地址在partition.i发现SetFilePointer API来做到这一点。我用SetFilePointer,但我得到的错误,而使用ReadFile的(newAddress)

 公共静态无效ReadMFT(串驱动器号,ULONG MFTStart,INT bytepersector,INT sectorpercluster)
    {
        IntPtr的处理= IntPtr.Zero;
        IntPtr的newaddress = IntPtr.Zero;
        长MFTAddress = bytepersector * sectorpercluster *(长)MFTStart;
        字符串driveRoot = string.Concat(\\\\。\\,驱动器号);
        IntPtr的HR管理世界=的CreateFile(driveRoot,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            IntPtr.Zero,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            IntPtr.Zero);

        ** newaddress = SetFilePointer(HR管理世界,(ULONG)MFTAddress,IntPtr.Zero,0); **
        Console.WriteLine(HR管理世界:+ hRoot.ToString());
        Console.WriteLine(MFTAddress:+ MFTAddress.ToString());
        Console.WriteLine(NewAddress:+ newaddress.ToString());
        如果(hRoot.ToInt64()!= INVALID_HANDLE_VALUE)
        {
            UINT NREAD;
            byte []的BUFF =新的字节[1024];
            如果(** ReadFile的(newaddress,浅黄色,(UINT)buff.Length,出NREAD,IntPtr.Zero)**)
                Console.WriteLine(读成功);
            其他
                Console.WriteLine(读取失败);

        }
        而(真)
        {
            //读取其他MFT记录
            打破;
        }
    }
 

解决方案

我可以看到以下错误:

  • 您没有检查的CreateFile 成功或失败的返回值。
  • 您正在传递了错误的事情的ReadFile 的第一个参数。您需要将句柄传递给该文件。
  • 您使用重叠I /你不想0,并且不能与整理字节[] 缓冲区工作。通 IntPtr.Zero lpOverlapped的或者视你是如何的P / Invoke声明。
  • 的ReadFile 不返回的句柄,它返回一个布尔值,表示函数调用成功。
  • 您必须永远不会调用 GetLastError函数从管理code。而是叫 Marshal.GetLastWin32Error 。其原因是在文档的方法。
  • 请不要叫 Marshal.GetLastWin32Error ,除非事先API调用实际上失败。你没有检查是否不 SetFilePointerEx 成功。就像的ReadFile ,它返回一个布尔值,表明成功或失败。

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;
        }
    }
解决方案

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.

这篇关于SetFilePointerEx API来读取MFT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 14:48