private MEinfo GetMEFileInfo(Stream stream, string path, uint startoffset = 0, uint endoffset = 0) { stream.Seek(startoffset, SeekOrigin.Begin); var meinfo = new MEinfo(); var handle = GCHandle.Alloc(new BinaryReader(stream).ReadBytes(Marshal.SizeOf(typeof(FptPreHeader))), GCHandleType.Pinned); var fptPreHeader = (FptPreHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FptPreHeader)); handle.Free(); handle = GCHandle.Alloc(new BinaryReader(stream).ReadBytes(Marshal.SizeOf(typeof(FptHeader))), GCHandleType.Pinned); var fptHeader = (FptHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FptHeader)); handle.Free(); var fptEntries = new List <FptEntry>(); for (var i = 0; i < fptHeader.NumPartitions; i++) { handle = GCHandle.Alloc(new BinaryReader(stream).ReadBytes(Marshal.SizeOf(typeof(FptEntry))), GCHandleType.Pinned); var fptEntry = (FptEntry)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FptEntry)); handle.Free(); fptEntries.Add(fptEntry); } var mn2Manifests = new List <Mn2Manifest>(); //foreach (var fptEntry in fptEntries.Where(fptEntry => (fptEntry.Flags & 0x00FF) == 0x80)) foreach (var fptEntry in fptEntries.Where(fptEntry => (new string(fptEntry.Name) == "FTPR"))) { stream.Seek(fptEntry.Offset + startoffset, SeekOrigin.Begin); var o = 0; if (new string(new BinaryReader(stream).ReadChars(4)) == "$CPD") { o = new BinaryReader(stream).ReadByte() * 0x18 + 0x10; } stream.Seek(fptEntry.Offset + startoffset + o, SeekOrigin.Begin); handle = GCHandle.Alloc(new BinaryReader(stream).ReadBytes(Marshal.SizeOf(typeof(Mn2Manifest))), GCHandleType.Pinned); mn2Manifests.Add((Mn2Manifest)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Mn2Manifest))); handle.Free(); } if (mn2Manifests.Count < 1) { throw new Exception($@"Unsupported ME version: {path.SafeFileName()}"); } var manifest = mn2Manifests.First(); meinfo.Size = endoffset == 0 ? (uint)stream.Length : endoffset - startoffset; meinfo.Path = path; meinfo.Major = manifest.Major; meinfo.Minor = manifest.Minor; meinfo.Hotfix = manifest.Hotfix; meinfo.Build = manifest.Build; return(meinfo); }
private void LoadBIOS(string path) { Log("----------------------------------------", LogLevel.Default); BIOSfile = File.ReadAllBytes(path); var stream = File.Open(path, FileMode.Open); stream.Seek(0x10, SeekOrigin.Begin); var magic = new BinaryReader(stream).ReadBytes(4); if (magic.SequenceEqual(new byte[] { 0x5A, 0xA5, 0xF0, 0x0F })) // Flas descriptor sign. BIOS file { stream.Seek(0x14, SeekOrigin.Begin); var flmap0 = new BinaryReader(stream).ReadUInt32(); var flmap1 = new BinaryReader(stream).ReadUInt32(); var nr = flmap0 >> 24 & 0x7; var frba = flmap0 >> 12 & 0xff0; //var fmba = (flmap1 & 0xff) << 4; if (nr >= 2 || true) { Log("Intel BIOS image detected! :D", LogLevel.Info); stream.Seek(frba, SeekOrigin.Begin); //FLREG0 = Flash Descriptor //FLREG1 = BIOS //FLREG2 = ME var flreg0 = new BinaryReader(stream).ReadUInt32(); var flreg1 = new BinaryReader(stream).ReadUInt32(); var flreg2 = new BinaryReader(stream).ReadUInt32(); //var fd_start = (flreg0 & 0x1fff) << 12; //var fd_end = flreg0 >> 4 & 0x1fff000 | 0xfff + 1; BIOS_ME_start_offset = (flreg2 & 0x1fff) << 12; BIOS_ME_end_offset = flreg2 >> 4 & 0x1fff000 | 0xfff + 1; if (BIOS_ME_start_offset >= BIOS_ME_end_offset) { throw new Exception("The ME/TXE region in this image has been disabled"); } stream.Seek(BIOS_ME_start_offset + 0x10, SeekOrigin.Begin); if (new string(new BinaryReader(stream).ReadChars(4)) != "$FPT") { throw new Exception("The ME/TXE region is corrupted or missing"); } BIOS_ME_info = GetMEFileInfo(stream, path, BIOS_ME_start_offset, BIOS_ME_end_offset); _mode = BIOS_ME_info.Major < 4 ? Mode.TXE : Mode.ME; UpdateGUI(); Log("BIOS read successful! " + path.SafeFileName(), LogLevel.Info); Log($"The {_mode} region goes from {BIOS_ME_start_offset:X8} to {BIOS_ME_end_offset:X8}", LogLevel.Info); UpdateComboBox(); var offset = Find(BIOSfile, MSDM_table_pattern) + MSDM_offset; if (offset - MSDM_offset != -1) { stream.Seek(offset, SeekOrigin.Begin); var handle = GCHandle.Alloc(new BinaryReader(stream).ReadBytes(Marshal.SizeOf(typeof(MSDM))), GCHandleType.Pinned); var MSDM = (MSDM)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(MSDM)); handle.Free(); WinKeyTextBox.Text = new string(MSDM.WinKey); } else { WinKeyTextBox.Text = @"none"; } stream.Close(); return; } MessageBox.Show(flmap0 + " " + flmap1); stream.Close(); throw new Exception("Number of partitions in file is less than 2! " + path.SafeFileName()); } stream.Close(); ClearGUI(); BIOSfile = null; throw new Exception("Invalid input file " + path.SafeFileName()); }