public bool GetDetails(Stream fs) { using (var binReader = new BinaryReader(fs)) { if (fs.Length < 0x40) { return(false); } fs.Position = 0x3C; var headerOffset = binReader.ReadUInt32(); if (headerOffset > fs.Length - 5) { return(false); } fs.Position = headerOffset; var signature = binReader.ReadUInt32(); if (signature != 0x00004550) { return(false); } fs.Position += 2; NumberOfSections = binReader.ReadUInt16(); Sections = new List <MiniSection>(); TimeStamp = binReader.ReadUInt32(); fs.Position += 8; secOff = binReader.ReadUInt16(); fs.Position += 2; var magic = binReader.ReadInt16(); Is64 = magic == 0x20b; if (Is64) { fs.Position += 22; ImageBaseOffset = fs.Position; ImageBase = binReader.ReadUInt64(); } else { fs.Position += 26; ImageBaseOffset = fs.Position; ImageBase = binReader.ReadUInt32(); } SectionAlignment = binReader.ReadUInt32(); FileAlignment = binReader.ReadUInt32(); fs.Position += 16; SizeOfImage = binReader.ReadUInt32(); SizeOfHeaders = binReader.ReadUInt32(); var CurrEnd = SizeOfHeaders; /// implicit section for header Sections.Add(new MiniSection { VirtualSize = 0x1000, RawFileSize = CurrEnd, RawFilePointer = 0, VirtualAddress = 0, Name = ".PEHeader", Characteristics = 0x20000000 }); // get to sections fs.Position = headerOffset + (Is64 ? 0x108 : 0xF8); for (int i = 0; i < NumberOfSections; i++) { var secName = binReader.ReadBytes(8); var rawStr = Encoding.ASCII.GetString(secName); var secStr = new string(rawStr.Where(c => char.IsLetterOrDigit(c) || char.IsPunctuation(c)).ToArray()); var Size = binReader.ReadUInt32(); var Pos = binReader.ReadUInt32(); var rawSize = binReader.ReadUInt32(); var rawPos = binReader.ReadUInt32(); fs.Position += 0xC; var characteristic = binReader.ReadUInt32(); var currSecNfo = new MiniSection { VirtualSize = Size, VirtualAddress = Pos, RawFileSize = rawSize, RawFilePointer = rawPos, Name = secStr, Characteristics = characteristic }; Sections.Add(currSecNfo); if (Verbose > 2) { Write($" section [{secStr}] "); } if (secStr.StartsWith(@".reloc", StringComparison.Ordinal)) { RelocSize = Size; RelocPos = Pos; } fs.Position += 0x4; } } return(true); }
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 = 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 bool GetDetails(Stream Input) { using (var binReader = new BinaryReader(fs)) { if (fs.Length < 0x40) return false; fs.Position = 0x3C; var headerOffset = binReader.ReadUInt32(); if (headerOffset > fs.Length - 5) return false; fs.Position = headerOffset; var signature = binReader.ReadUInt32(); if (signature != 0x00004550) return false; fs.Position += 2; NumberOfSections = binReader.ReadInt16(); SectionPosOffsets = new List<MiniSection>(); TimeStamp = binReader.ReadUInt32(); fs.Position += 8; secOff = binReader.ReadUInt16(); fs.Position += 2; var magic = binReader.ReadInt16(); Is64 = magic == 0x20b; if (Is64) { fs.Position += 22; ImageBaseOffset = fs.Position; ImageBase = binReader.ReadUInt64(); } else { fs.Position += 26; ImageBaseOffset = fs.Position; ImageBase = binReader.ReadUInt32(); } SectionAlignment = binReader.ReadUInt32(); FileAlignment = binReader.ReadUInt32(); fs.Position += 16; SizeOfImage = binReader.ReadUInt32(); SizeOfHeaders = binReader.ReadUInt32(); var CurrEnd = SizeOfHeaders; /// implicit section for header SectionPosOffsets.Add(new MiniSection { VirtualSize = 0x1000, RawFileSize = 0x400, RawFilePointer = 0, VirtualOffset = 0, Name = "PE Header" }); // get to sections fs.Position = headerOffset + (Is64 ? 0x108 : 0xF8); for (int i = 0; i < NumberOfSections; i++) { var secName = binReader.ReadBytes(8); var rawStr = Encoding.ASCII.GetString(secName); var secStr = new string(rawStr.Where(c => char.IsLetterOrDigit(c) || char.IsPunctuation(c)).ToArray()); var Size = binReader.ReadUInt32(); var Pos = binReader.ReadUInt32(); var rawSize = binReader.ReadUInt32(); var rawPos = binReader.ReadUInt32(); var currSecNfo = new MiniSection { VirtualSize = Size, VirtualOffset = Pos, RawFileSize = rawSize, RawFilePointer = rawPos, Name = secStr }; SectionPosOffsets.Add(currSecNfo); if (Verbose > 2) Write($" section [{secStr}] "); if (secStr.StartsWith(@".reloc", StringComparison.Ordinal)) { RelocSize = Size; RelocPos = Pos; } fs.Position += 0x10; } } }
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 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 += 14; extracted_struct.EntryPoint = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.BaseOfCode = BitConverter.ToUInt32(block, pos); pos += 4; extracted_struct.ImageBaseOffset = pos; 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; 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); }