Reloc.Extract.IsBlockaPE C# (CSharp) Method

IsBlockaPE() public static method

public static IsBlockaPE ( byte block ) : Extract
block byte
return Extract
        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;
        }

Usage Example

コード例 #1
0
ファイル: extract.cs プロジェクト: Team-Firebugs/HashServer
        // 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);
            }
        }