public static Extract IsBlockaPE(byte[] block) { Extract extracted_struct = new Extract(); if (BitConverter.ToInt16(block, 0) != 0x5A4D) return null; var headerOffset = BitConverter.ToInt32(block, 0x3C); if (headerOffset > 3000) { // bad probably return null; } if (BitConverter.ToInt32(block, headerOffset) != 0x00004550) return null; var pos = headerOffset + 6; extracted_struct.NumberOfSections = BitConverter.ToInt16(block, pos); pos += 2; extracted_struct.SectionPosOffsets = new List<MiniSection>(); //pos += 2; extracted_struct.TimeStamp = BitConverter.ToUInt32(block, pos); pos += 4; pos += 8; extracted_struct.secOff = BitConverter.ToUInt16(block, pos); pos += 2; pos += 2; var magic = BitConverter.ToUInt16(block, pos); pos += 2; extracted_struct.Is64 = magic == 0x20b; if (extracted_struct.Is64) { pos += 22; extracted_struct.ImageBaseOffset = pos; extracted_struct.ImageBase = BitConverter.ToUInt64(block, pos); pos += 8; } else { pos += 26; extracted_struct.ImageBaseOffset = pos; extracted_struct.ImageBase = BitConverter.ToUInt32(block, pos); pos += 4; } extracted_struct.SectionAlignment = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.FileAlignment = BitConverter.ToUInt32(block, pos); pos += 4; pos += 16; extracted_struct.SizeOfImage = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.SizeOfHeaders = BitConverter.ToUInt32(block, pos); pos += 4; // checksum pos += 4; // subsys/characteristics pos += 4; // SizeOf/Stack/Heap/Reserve/Commit if (extracted_struct.Is64) pos += 32; else pos += 16; // LoaderFlags pos += 4; // NumberOfRvaAndSizes pos += 4; // 16 DataDirectory entries, each is 8 bytes 4byte VA, 4byte Size // we care about #6 since it's where we will find the GUID pos += 6 * 8; extracted_struct.DebugDirPos = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.DebugDirSize = BitConverter.ToUInt32(block, pos); pos += 4; var CurrEnd = extracted_struct.SizeOfHeaders; /// implicit section for header extracted_struct.SectionPosOffsets.Add(new MiniSection { VirtualSize = 0x1000, RawFileSize = 0x400, RawFilePointer = 0, VirtualOffset = 0, Name = "PEHeader" }); // get to sections pos = headerOffset + (extracted_struct.Is64 ? 0x108 : 0xF8); for (int i = 0; i < extracted_struct.NumberOfSections; i++) { /*var rawStr = BitConverter.ToString(block, pos, 8); */ var rawStr = new String( new char[8] { (char) block[pos], (char) block[pos + 1], (char) block[pos + 2], (char) block[pos + 3], (char) block[pos + 4], (char) block[pos + 5], (char) block[pos + 6], (char) block[pos + 7] }); pos += 8; var secStr = new string(rawStr.Where(c => char.IsLetterOrDigit(c) || char.IsPunctuation(c)).ToArray()); var Size = BitConverter.ToUInt32(block, pos); pos += 4; var Pos = BitConverter.ToUInt32(block, pos); pos += 4; var rawSize = BitConverter.ToUInt32(block, pos); pos += 4; var rawPos = BitConverter.ToUInt32(block, pos); pos += 4; var currSecNfo = new MiniSection { VirtualSize = Size, VirtualOffset = Pos, RawFileSize = rawSize, RawFilePointer = rawPos, Name = secStr }; extracted_struct.SectionPosOffsets.Add(currSecNfo); if (Verbose > 2) Write($" section [{secStr}] "); if (secStr.StartsWith(@".reloc", StringComparison.Ordinal)) { extracted_struct.RelocSize = Size; extracted_struct.RelocPos = Pos; } pos += 0x10; } return extracted_struct; }
public async Task<string> DeLocateFile(string fPath, string RelocFile, ulong CurrBase, string SaveTo, bool is64 = false, bool FixHeader = false, bool ScaleFileAlignment = false) { var hdrFix = new Extract(); var rv = string.Empty; ulong OrigImageBase=0; bool Is64 = is64; byte[] readBuffer = null; var bytesRead = 0; var PAGE_SIZE = 4096; var ScaleFactor = 0u; if (!File.Exists(fPath) || !File.Exists(RelocFile)) { WriteLine($"Can not find input file {fPath}"); return rv; } hdrFix.FileName = fPath; // reloc file specifies the ImageBase by convention // [memory-region-name-(a.k.a. module name)]-[0xImageBase]-[TimeDateStamp].reloc var split = RelocFile.Split('-'); OrigImageBase = ulong.Parse(split[1], NumberStyles.HexNumber, CultureInfo.InvariantCulture); var Delta = CurrBase - OrigImageBase; if (FixHeader || ScaleFileAlignment) { hdrFix.GetDetails(); ScaleFactor = hdrFix.SectionAlignment - hdrFix.FileAlignment; } // should be relatively small var relocData = File.ReadAllBytes(RelocFile); var prepared = ProcessRelocs(relocData).ToArray(); using(var fsRelocted = new FileStream(fPath, FileMode.Open, FileAccess.Read, FileShare.Read, PAGE_SIZE, true)) { var WriteSize = PAGE_SIZE; var fsLen = fsRelocted.Length; var Chunks = fsLen / PAGE_SIZE; var CurrSec = 0; var CurrSize = hdrFix.SectionPosOffsets[CurrSec].RawFileSize; var CurrEnd = hdrFix.SectionPosOffsets[CurrSec].RawFilePointer + CurrSize; using (var fsWriteOut = new FileStream(SaveTo, FileMode.Create, FileAccess.Write, FileShare.Write, PAGE_SIZE, true)) { readBuffer = new Byte[PAGE_SIZE]; for (uint i=0; i < Chunks; i++) { bytesRead = await fsRelocted.ReadAsync(readBuffer, 0, PAGE_SIZE).ConfigureAwait(false); var offset = i*PAGE_SIZE; if (i == 0 && FixHeader) DelocateHeader(readBuffer, OrigImageBase, hdrFix.ImageBaseOffset, hdrFix.Is64); if (is64) DeLocateBuff64(readBuffer, Delta, (ulong) offset, prepared); else DeLocateBuff32(readBuffer, (uint) Delta, (uint) offset, prepared); if (ScaleFileAlignment) { if (fsWriteOut.Position + 4096 >= CurrEnd && CurrSec < hdrFix.NumberOfSections) { WriteSize = (int)((long)CurrEnd - fsWriteOut.Position); WriteLine($"Finishing up {hdrFix.SectionPosOffsets[CurrSec].Name}, emit final {WriteSize:X} bytes to move our position to {(fsWriteOut.Position + WriteSize):X}"); CurrSec++; if (CurrSec < hdrFix.NumberOfSections) { CurrSize = hdrFix.SectionPosOffsets[CurrSec].RawFileSize; CurrEnd = hdrFix.SectionPosOffsets[CurrSec].RawFilePointer + CurrSize; } } else WriteSize = 4096; } await fsWriteOut.WriteAsync(readBuffer, 0, WriteSize).ConfigureAwait(false); if (WriteSize != 4096 && CurrSec < hdrFix.NumberOfSections) { fsWriteOut.Position = hdrFix.SectionPosOffsets[CurrSec].RawFilePointer; /// ensure read position is aligned with us fsRelocted.Position = hdrFix.SectionPosOffsets[CurrSec].VirtualOffset; } } rv = SaveTo; } } return rv; }
/// <summary> /// Prefer symbol loading. /// </summary> /// <param name="dp"></param> /// <param name="ext"></param> /// <param name="cv_data"></param> /// <param name="SymbolCache"></param> /// <returns></returns> public bool GetKernelDebuggerData(DetectedProc dp, Extract ext, CODEVIEW_HEADER cv_data, string SymbolCache) { DebugHelp.SYMBOL_INFO symInfo = new DebugHelp.SYMBOL_INFO(); bool rv = false; bool GotData = false; // Locate and extract some data points symInfo.SizeOfStruct = 0x58; symInfo.MaxNameLen = 1024; rv = DebugHelp.SymFromName(hCurrentProcess, "KdpDataBlockEncoded", ref symInfo); if(!rv) { WriteLine($"Symbol Find : {new Win32Exception(Marshal.GetLastWin32Error()).Message }."); return rv; } KernelProc = dp; // at this point we should return true if it's encoded or not rv = true; return rv; #if FALSE I'm leaving this in for now just to show the use of DecodePointer if needed since it could be uswed in a scenerio where symbols fail var KdpDataBlockEncoded = dp.GetByteValue(symInfo.Address); // Convention is to use *Address for addresses or the simple name is the value it is assumed to be a pointer dp.SymbolStore["KdDebuggerDataBlockAddress"] = GetSymAddress(dp, "KdDebuggerDataBlock"); if (KdpDataBlockEncoded == 0) WriteColor(ConsoleColor.Green, $"Kernel KdDebuggerDataBlock @ {dp.SymbolStore["KdDebuggerDataBlockAddress"]:X16} not encoded."); else { #if FALSE_NOT_NEEDED_IF_WE_USE_SYMBOLS var KdDebuggerDataBlock = dp.VGetBlockLong(dp.KdDebuggerDataBlockAddress, ref GotData); if (!GotData) WriteColor(ConsoleColor.Red, "Unable to read debuggerdatablock array"); // Windbg tells us the diff for loaded modules is 0x48 and active proc is 0x50 var EncLoadedModuleList = KdDebuggerDataBlock[9]; var EncActiveProcessList = KdDebuggerDataBlock[0xA]; var PsLoadedModuleList = (long) DecodePointer((ulong) dp.KdDebuggerDataBlockAddress, (ulong)dp.KiWaitAlways, (ulong)dp.KiWaitNever,(ulong) EncLoadedModuleList); var PsActiveProcessHead = (long) DecodePointer((ulong) dp.KdDebuggerDataBlockAddress, (ulong)dp.KiWaitAlways, (ulong)dp.KiWaitNever, (ulong) EncActiveProcessList); WriteColor(ConsoleColor.Cyan, $"Decoded LoadedModuleList {PsLoadedModuleList}, ActiveProcessList {PsActiveProcessHead}"); #endif } return rv; #endif }
// We don't really need a reloc folder if were wharehousing the whole binary anyhow public static RelocSection ExtractRelocData(string PE, string RelocBase = null, bool NoExtraRelocFolder = true) { using (var fs = new FileStream(PE, FileMode.Open, FileAccess.Read)) { var buff = new byte[4096]; fs.Read(buff, 0, 4096); var e = Extract.IsBlockaPE(buff); if (e == null) { return(null); } e.FileName = PE; if (e.RelocSize == 0) { return(null); } RelocSection rv = new RelocSection(); int RelocPos = 0, RelocSize = 0; rv.FullPath = PE; rv.Name = Path.GetFileName(PE); rv.Is64 = e.Is64; rv.VirtualSize = e.SizeOfImage; rv.TimeStamp = e.TimeStamp; rv.OriginalBase = e.ImageBase; rv.OrigBaseOffset = (int)e.ImageBaseOffset; for (int i = 0; i < e.Sections.Count(); i++) { if (e.Sections[i].Name == ".reloc") { RelocPos = (int)e.Sections[i].RawFilePointer; RelocSize = (int)e.Sections[i].RawFileSize; break; } } if (RelocPos == 0 && RelocSize == 0) { return(null); } rv.RelocSecOffset = RelocPos; rv.RelocLength = RelocSize; var readBuffer = new byte[RelocSize]; if (RelocSize != 0) { fs.Position = RelocPos; fs.Read(readBuffer, 0, RelocSize); if (!NoExtraRelocFolder && !string.IsNullOrWhiteSpace(RelocBase) && !File.Exists(rv.FullPath)) { var relocDir = e.Is64 ? Path.Combine(RelocBase, "64") : Path.Combine(RelocBase, "32"); var sb = $"{Path.GetFileName(e.FileName)}-{e.ImageBase.ToString("X")}-{e.TimeStamp.ToString("X")}.reloc"; var outFile = Path.Combine(relocDir, sb); using (FileStream stream = new FileStream(outFile, FileMode.CreateNew, FileAccess.Write, FileShare.Read)) stream.Write(readBuffer, 0, RelocSize); } } rv.RawRelocBuffer = readBuffer; return(rv); } }
public static Extract IsBlockaPE(byte[] block, int blockOffset = 0) { Extract extracted_struct = new Extract(); if (block[blockOffset] != 0x4d || block[blockOffset + 1] != 0x5a) { return(null); } var headerOffset = BitConverter.ToInt32(block, blockOffset + 0x3C); // bad probably if (headerOffset > 3000) { return(null); } if (BitConverter.ToInt32(block, blockOffset + headerOffset) != 0x00004550) { return(null); } var pos = blockOffset + headerOffset + 6; extracted_struct.NumberOfSections = BitConverter.ToUInt16(block, pos); pos += 2; extracted_struct.Sections = new List <MiniSection>(); //pos += 2; extracted_struct.TimeStamp = BitConverter.ToUInt32(block, pos); pos += 4; pos += 8; extracted_struct.secOff = BitConverter.ToUInt16(block, pos); pos += 2; pos += 2; var magic = BitConverter.ToUInt16(block, pos); pos += 2; extracted_struct.Is64 = magic == 0x20b; // sizeofcode, sizeofinit, sizeofuninit, pos += 14; extracted_struct.EntryPoint = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.BaseOfCode = BitConverter.ToUInt32(block, pos); pos += 4; if (extracted_struct.Is64) { // we wan't this to be page aligned to typical small page size extracted_struct.ImageBaseOffset = pos & 0xfff; extracted_struct.ImageBase = BitConverter.ToUInt64(block, pos); pos += 8; } else { // baseofdata pos += 4; // imagebase extracted_struct.ImageBaseOffset = pos & 0xfff; extracted_struct.ImageBase = BitConverter.ToUInt32(block, pos); pos += 4; } extracted_struct.SectionAlignment = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.FileAlignment = BitConverter.ToUInt32(block, pos); pos += 4; pos += 16; extracted_struct.SizeOfImage = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.SizeOfHeaders = BitConverter.ToUInt32(block, pos); pos += 4; // checksum extracted_struct.CheckSumPos = pos; extracted_struct.CheckSum = BitConverter.ToUInt32(block, pos); pos += 4; // subsys pos += 2; ///characteristics extracted_struct.Characteristics = BitConverter.ToUInt16(block, pos); pos += 2; // SizeOf/Stack/Heap/Reserve/Commit if (extracted_struct.Is64) { pos += 32; } else { pos += 16; } // LoaderFlags pos += 4; // NumberOfRvaAndSizes pos += 4; extracted_struct.Directories = new List <Tuple <int, int> >(16); // collect a list of all directories in a table for (int i = 0; i < 0x10; i++) { extracted_struct.Directories.Add(Tuple.Create <int, int>(BitConverter.ToInt32(block, pos + (i * 8)), BitConverter.ToInt32(block, pos + (i * 8) + 4))); } extracted_struct.ClrAddress = (uint)extracted_struct.Directories[0xf].Item1; extracted_struct.ClrSize = (uint)extracted_struct.Directories[0xf].Item2; if (extracted_struct.ClrAddress != 0) { extracted_struct.IsCLR = true; } var CurrEnd = extracted_struct.SizeOfHeaders; /// implicit section for header extracted_struct.Sections.Add(new MiniSection { VirtualSize = CurrEnd, RawFileSize = CurrEnd, RawFilePointer = 0, VirtualAddress = 0, Name = ".PEHeader", Characteristics = PECaricteristicFlags.Code }); // get to sections pos = blockOffset + headerOffset + (extracted_struct.Is64 ? 0x108 : 0xF8); for (int i = 0; i < extracted_struct.NumberOfSections; i++) { /*var rawStr = BitConverter.ToString(block, pos, 8); */ var rawStr = new String( new char[8] { (char)block[pos], (char)block[pos + 1], (char)block[pos + 2], (char)block[pos + 3], (char)block[pos + 4], (char)block[pos + 5], (char)block[pos + 6], (char)block[pos + 7] }); pos += 8; var secStr = new string(rawStr.Where(c => char.IsLetterOrDigit(c) || char.IsPunctuation(c)).ToArray()); var Size = BitConverter.ToUInt32(block, pos); pos += 4; var Pos = BitConverter.ToUInt32(block, pos); pos += 4; var rawSize = BitConverter.ToUInt32(block, pos); pos += 4; var rawPos = BitConverter.ToUInt32(block, pos); pos += 0x10; var characteristic = (PECaricteristicFlags)BitConverter.ToUInt32(block, pos); pos += 4; var currSecNfo = new MiniSection { VirtualSize = Size, VirtualAddress = Pos, RawFileSize = rawSize, RawFilePointer = rawPos, Name = secStr, Characteristics = characteristic }; extracted_struct.Sections.Add(currSecNfo); if (Verbose > 2) { Write($" section [{secStr}] "); } //optimize reloc for easy access if (secStr.StartsWith(@".reloc", StringComparison.Ordinal)) { extracted_struct.RelocSize = Size; extracted_struct.RelocPos = Pos; } } return(extracted_struct); }
public static Extract IsBlockaPE(byte[] block, int blockOffset = 0) { Extract extracted_struct = new Extract(); if (block[blockOffset] != 0x4d || block[blockOffset + 1] != 0x5a) { return(null); } var headerOffset = BitConverter.ToInt32(block, blockOffset + 0x3C); // bad probably if (headerOffset > 3000) { return(null); } if (BitConverter.ToInt32(block, blockOffset + headerOffset) != 0x00004550) { return(null); } var pos = blockOffset + headerOffset + 6; extracted_struct.NumberOfSections = BitConverter.ToInt16(block, pos); pos += 2; extracted_struct.Sections = new List <MiniSection>(); //pos += 2; extracted_struct.TimeStamp = BitConverter.ToUInt32(block, pos); pos += 4; pos += 8; extracted_struct.secOff = BitConverter.ToUInt16(block, pos); pos += 2; pos += 2; var magic = BitConverter.ToUInt16(block, pos); pos += 2; extracted_struct.Is64 = magic == 0x20b; if (extracted_struct.Is64) { pos += 14; extracted_struct.EntryPoint = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.BaseOfCode = BitConverter.ToUInt32(block, pos); pos += 4; // we wan't this to be page aligned to typical small page size extracted_struct.ImageBaseOffset = pos & 0xfff; extracted_struct.ImageBase = BitConverter.ToUInt64(block, pos); pos += 8; } else { pos += 18; extracted_struct.EntryPoint = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.BaseOfCode = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.ImageBaseOffset = pos & 0xfff; extracted_struct.ImageBase = BitConverter.ToUInt32(block, pos); pos += 4; } extracted_struct.SectionAlignment = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.FileAlignment = BitConverter.ToUInt32(block, pos); pos += 4; pos += 16; extracted_struct.SizeOfImage = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.SizeOfHeaders = BitConverter.ToUInt32(block, pos); pos += 4; // checksum pos += 4; // subsys/characteristics pos += 4; // SizeOf/Stack/Heap/Reserve/Commit if (extracted_struct.Is64) { pos += 32; } else { pos += 16; } // LoaderFlags pos += 4; // NumberOfRvaAndSizes pos += 4; // 16 DataDirectory entries, each is 8 bytes 4byte VA, 4byte Size // we care about #6 since it's where we will find the GUID pos += 6 * 8; extracted_struct.DebugDirPos = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.DebugDirSize = BitConverter.ToUInt32(block, pos); pos += 4; // move to IAT directory pos += 5 * 8; extracted_struct.ImportDirPos = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.ImportDirSize = BitConverter.ToUInt32(block, pos); pos += 4; // move to "COM" directory (.net PE check) pos += 8; extracted_struct.ClrAddress = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.ClrSize = BitConverter.ToUInt32(block, pos); pos += 4; if (extracted_struct.ClrAddress != 0) { extracted_struct.IsCLR = true; } var CurrEnd = extracted_struct.SizeOfHeaders; /// implicit section for header extracted_struct.Sections.Add(new MiniSection { VirtualSize = CurrEnd, RawFileSize = CurrEnd, RawFilePointer = 0, VirtualAddress = 0, Name = ".PEHeader", Characteristics = 0x20000000 }); // get to sections pos = blockOffset + headerOffset + (extracted_struct.Is64 ? 0x108 : 0xF8); for (int i = 0; i < extracted_struct.NumberOfSections; i++) { /*var rawStr = BitConverter.ToString(block, pos, 8); */ var rawStr = new String( new char[8] { (char)block[pos], (char)block[pos + 1], (char)block[pos + 2], (char)block[pos + 3], (char)block[pos + 4], (char)block[pos + 5], (char)block[pos + 6], (char)block[pos + 7] }); pos += 8; var secStr = new string(rawStr.Where(c => char.IsLetterOrDigit(c) || char.IsPunctuation(c)).ToArray()); var Size = BitConverter.ToUInt32(block, pos); pos += 4; var Pos = BitConverter.ToUInt32(block, pos); pos += 4; var rawSize = BitConverter.ToUInt32(block, pos); pos += 4; var rawPos = BitConverter.ToUInt32(block, pos); pos += 0x10; var characteristic = BitConverter.ToUInt32(block, pos); pos += 4; var currSecNfo = new MiniSection { VirtualSize = Size, VirtualAddress = Pos, RawFileSize = rawSize, RawFilePointer = rawPos, Name = secStr, Characteristics = characteristic }; extracted_struct.Sections.Add(currSecNfo); if (Verbose > 2) { Write($" section [{secStr}] "); } //optimize reloc for easy access if (secStr.StartsWith(@".reloc", StringComparison.Ordinal)) { extracted_struct.RelocSize = Size; extracted_struct.RelocPos = Pos; } } return(extracted_struct); }
public static Extract IsBlockaPE(byte[] block) { Extract extracted_struct = new Extract(); if (BitConverter.ToInt16(block, 0) != 0x5A4D) { return(null); } var headerOffset = BitConverter.ToInt32(block, 0x3C); if (headerOffset > 3000) { // bad probably return(null); } if (BitConverter.ToInt32(block, headerOffset) != 0x00004550) { return(null); } var pos = headerOffset + 6; extracted_struct.NumberOfSections = BitConverter.ToInt16(block, pos); pos += 2; extracted_struct.SectionPosOffsets = new List <MiniSection>(); //pos += 2; extracted_struct.TimeStamp = BitConverter.ToUInt32(block, pos); pos += 4; pos += 8; extracted_struct.secOff = BitConverter.ToUInt16(block, pos); pos += 2; pos += 2; var magic = BitConverter.ToUInt16(block, pos); pos += 2; extracted_struct.Is64 = magic == 0x20b; if (extracted_struct.Is64) { pos += 22; extracted_struct.ImageBaseOffset = pos; extracted_struct.ImageBase = BitConverter.ToUInt64(block, pos); pos += 8; } else { pos += 26; extracted_struct.ImageBaseOffset = pos; extracted_struct.ImageBase = BitConverter.ToUInt32(block, pos); pos += 4; } extracted_struct.SectionAlignment = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.FileAlignment = BitConverter.ToUInt32(block, pos); pos += 4; pos += 16; extracted_struct.SizeOfImage = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.SizeOfHeaders = BitConverter.ToUInt32(block, pos); pos += 4; // checksum pos += 4; // subsys/characteristics pos += 4; // SizeOf/Stack/Heap/Reserve/Commit if (extracted_struct.Is64) { pos += 32; } else { pos += 16; } // LoaderFlags pos += 4; // NumberOfRvaAndSizes pos += 4; // 16 DataDirectory entries, each is 8 bytes 4byte VA, 4byte Size // we care about #6 since it's where we will find the GUID pos += 6 * 8; extracted_struct.DebugDirPos = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.DebugDirSize = BitConverter.ToUInt32(block, pos); pos += 4; var CurrEnd = extracted_struct.SizeOfHeaders; /// implicit section for header extracted_struct.SectionPosOffsets.Add(new MiniSection { VirtualSize = 0x1000, RawFileSize = 0x400, RawFilePointer = 0, VirtualOffset = 0, Name = "PEHeader" }); // get to sections pos = headerOffset + (extracted_struct.Is64 ? 0x108 : 0xF8); for (int i = 0; i < extracted_struct.NumberOfSections; i++) { /*var rawStr = BitConverter.ToString(block, pos, 8); */ var rawStr = new String( new char[8] { (char)block[pos], (char)block[pos + 1], (char)block[pos + 2], (char)block[pos + 3], (char)block[pos + 4], (char)block[pos + 5], (char)block[pos + 6], (char)block[pos + 7] }); pos += 8; var secStr = new string(rawStr.Where(c => char.IsLetterOrDigit(c) || char.IsPunctuation(c)).ToArray()); var Size = BitConverter.ToUInt32(block, pos); pos += 4; var Pos = BitConverter.ToUInt32(block, pos); pos += 4; var rawSize = BitConverter.ToUInt32(block, pos); pos += 4; var rawPos = BitConverter.ToUInt32(block, pos); pos += 4; var currSecNfo = new MiniSection { VirtualSize = Size, VirtualOffset = Pos, RawFileSize = rawSize, RawFilePointer = rawPos, Name = secStr }; extracted_struct.SectionPosOffsets.Add(currSecNfo); if (Verbose > 2) { Write($" section [{secStr}] "); } if (secStr.StartsWith(@".reloc", StringComparison.Ordinal)) { extracted_struct.RelocSize = Size; extracted_struct.RelocPos = Pos; } pos += 0x10; } return(extracted_struct); }