Exemple #1
0
        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;
        }
Exemple #2
0
        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;
        }
Exemple #3
0
        /// <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
        }
Exemple #4
0
        // 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);
            }
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
        }