コード例 #1
0
ファイル: ExeUtils.cs プロジェクト: haise0/dnSurgeon
        public static bool TryGetTextSectionInfo(BinaryReader exe, out int textOffset, out int textSize)
        {
            textOffset = 0;
            textSize   = 0;

            try {
                var f     = exe.BaseStream;
                var magic = exe.ReadUInt32();
                if (!CheckMagic(magic))
                {
                    return(false);
                }
                bool is32           = magic == 0xFEEDFACE;
                bool isLittleEndian = true;
                var  cputype        = ExeUtils.ReadUInt32(exe, isLittleEndian);
                var  cpusubtype     = ExeUtils.ReadUInt32(exe, isLittleEndian);
                var  filetype       = ExeUtils.ReadUInt32(exe, isLittleEndian);
                var  ncmds          = ExeUtils.ReadUInt32(exe, isLittleEndian);
                var  sizeofcmds     = ExeUtils.ReadUInt32(exe, isLittleEndian);
                var  flags          = ExeUtils.ReadUInt32(exe, isLittleEndian);
                if (!is32)
                {
                    ExeUtils.ReadUInt32(exe, isLittleEndian);
                }

                for (uint i = 0; i < ncmds; i++)
                {
                    var pos     = f.Position;
                    var cmd     = ExeUtils.ReadUInt32(exe, isLittleEndian);
                    var cmdsize = ExeUtils.ReadUInt32(exe, isLittleEndian);

                    if (cmd == 0x19)
                    {
                        // LC_SEGMENT_64
                        var segname   = GetStringZ(exe.ReadBytes(16));
                        var vmaddr    = ExeUtils.ReadUInt64(exe, isLittleEndian);
                        var vmsize    = ExeUtils.ReadUInt64(exe, isLittleEndian);
                        var fileoff   = ExeUtils.ReadUInt64(exe, isLittleEndian);
                        var filesize  = ExeUtils.ReadUInt64(exe, isLittleEndian);
                        var maxprot   = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var initprot  = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var nsects    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var seg_flags = ExeUtils.ReadUInt32(exe, isLittleEndian);

                        for (uint j = 0; j < nsects; j++)
                        {
                            var sect_name    = GetStringZ(exe.ReadBytes(16));
                            var sect_segname = GetStringZ(exe.ReadBytes(16));
                            var sect_addr    = ExeUtils.ReadUInt64(exe, isLittleEndian);
                            var sect_size    = ExeUtils.ReadUInt64(exe, isLittleEndian);
                            var sect_offset  = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_align   = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_reloff  = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_nreloc  = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_flags   = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_res1    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_res2    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_res3    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            if (sect_name == "__text" && sect_segname == "__TEXT")
                            {
                                textOffset = (int)sect_offset;
                                textSize   = (int)sect_size;
                                return(true);
                            }
                        }
                    }
                    else if (cmd == 1)
                    {
                        // LC_SEGMENT
                        var segname   = GetStringZ(exe.ReadBytes(16));
                        var vmaddr    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var vmsize    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var fileoff   = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var filesize  = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var maxprot   = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var initprot  = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var nsects    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                        var seg_flags = ExeUtils.ReadUInt32(exe, isLittleEndian);

                        for (uint j = 0; j < nsects; j++)
                        {
                            var sect_name    = GetStringZ(exe.ReadBytes(16));
                            var sect_segname = GetStringZ(exe.ReadBytes(16));
                            var sect_addr    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_size    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_offset  = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_align   = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_reloff  = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_nreloc  = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_flags   = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_res1    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            var sect_res2    = ExeUtils.ReadUInt32(exe, isLittleEndian);
                            if (sect_name == "__text" && sect_segname == "__TEXT")
                            {
                                textOffset = (int)sect_offset;
                                textSize   = (int)sect_size;
                                return(true);
                            }
                        }
                    }

                    f.Position = pos + cmdsize;
                }
            }
            catch (IOException) {
            }

            return(false);
        }
コード例 #2
0
        internal static bool TryGetAppHostEmbeddedDotNetDllPath(string apphostFilename, out bool couldBeAppHost, [NotNullWhen(true)] out string?dotNetDllPath)
        {
            dotNetDllPath  = null;
            couldBeAppHost = false;
            if (!File.Exists(apphostFilename))
            {
                return(false);
            }
            if (PortableExecutableFileHelpers.IsPE(apphostFilename, out _, out var hasDotNetMetadata) && hasDotNetMetadata)
            {
                return(false);
            }
            try {
                var data = ReadBytes(apphostFilename, MaxAppHostExeSize);
                if (GetOffset(data, AppHostExeUnpatchedSignature) >= 0)
                {
                    couldBeAppHost = true;
                    return(false);
                }
                if (GetOffset(data, AppHostExeSignature) < 0)
                {
                    return(false);
                }
                couldBeAppHost = true;
                if (!ExeUtils.TryGetTextSectionInfo(new BinaryReader(new MemoryStream(data)), out _, out _))
                {
                    return(false);
                }

                var basePath = Path.GetDirectoryName(apphostFilename) !;
                foreach (var info in GetAppHostInfos(data))
                {
                    if (!TryGetUtf8StringZ(data, (int)info.RelPathOffset, AppHostInfo.MaxAppHostRelPathLength, out var relPath))
                    {
                        continue;
                    }
                    if (relPath == AppHostExeUnpatched)
                    {
                        continue;
                    }
                    string dotnetFile;
                    try {
                        dotnetFile = Path.Combine(basePath, relPath);
                    }
                    catch (ArgumentException) {
                        continue;
                    }
                    if (!PortableExecutableFileHelpers.IsPE(dotnetFile, out _, out hasDotNetMetadata))
                    {
                        continue;
                    }
                    if (!hasDotNetMetadata)
                    {
                        continue;
                    }
                    dotNetDllPath = dotnetFile;
                    return(true);
                }
            }
            catch (IOException) {
            }
            return(false);
        }
コード例 #3
0
ファイル: ExeUtils.cs プロジェクト: haise0/dnSurgeon
        public static bool TryGetTextSectionInfo(BinaryReader exe, out int textOffset, out int textSize)
        {
            textOffset = 0;
            textSize   = 0;

            try {
                var f = exe.BaseStream;
                if (!CheckMagic(exe.ReadUInt32()))
                {
                    return(false);
                }
                var eiClass = exe.ReadByte();
                if (eiClass != 1 && eiClass != 2)
                {
                    return(false);
                }
                var eiData = exe.ReadByte();
                if (eiData != 1 && eiData != 2)
                {
                    return(false);
                }
                bool isLittleEndian = eiData == 1;
                if (exe.ReadByte() != 1)
                {
                    return(false);
                }
                f.Position += 1 + 1 + 7;
                f.Position += 2;                // e_type
                f.Position += 2;                // e_machine
                if (ExeUtils.ReadUInt32(exe, isLittleEndian) != 1)
                {
                    return(false);
                }
                f.Position += 4 * eiClass;
                var ePhoff = eiClass == 1 ? ExeUtils.ReadUInt32(exe, isLittleEndian) : ExeUtils.ReadUInt64(exe, isLittleEndian);
                var sShoff = eiClass == 1 ? ExeUtils.ReadUInt32(exe, isLittleEndian) : ExeUtils.ReadUInt64(exe, isLittleEndian);
                f.Position += 4 + 2 + 2 + 2;
                var eShentsize = ExeUtils.ReadUInt16(exe, isLittleEndian);
                if (eShentsize < (eiClass == 1 ? 0x28 : 0x40))
                {
                    return(false);
                }
                var eShnum    = ExeUtils.ReadUInt16(exe, isLittleEndian);
                var eShstrndx = ExeUtils.ReadUInt16(exe, isLittleEndian);
                if (eShstrndx >= eShnum)
                {
                    return(false);
                }

                f.Position  = (long)(sShoff + (uint)eShstrndx * (uint)eShentsize);
                f.Position += eiClass == 1 ? 0x10 : 0x18;
                var stringOffset = eiClass == 1 ? ExeUtils.ReadUInt32(exe, isLittleEndian) : ExeUtils.ReadUInt64(exe, isLittleEndian);
                f.Position = (long)sShoff;
                var sb = new StringBuilder();
                for (int i = 0; i < eShnum; i++)
                {
                    var sectPos = f.Position;

                    var nameOffset = stringOffset + ExeUtils.ReadUInt32(exe, isLittleEndian);
                    ExeUtils.ReadUInt32(exe, isLittleEndian);
                    var flags = eiClass == 1 ? ExeUtils.ReadUInt32(exe, isLittleEndian) : ExeUtils.ReadUInt64(exe, isLittleEndian);
                    _ = eiClass == 1 ? ExeUtils.ReadUInt32(exe, isLittleEndian) : ExeUtils.ReadUInt64(exe, isLittleEndian);
                    var offset = eiClass == 1 ? ExeUtils.ReadUInt32(exe, isLittleEndian) : ExeUtils.ReadUInt64(exe, isLittleEndian);
                    var size   = eiClass == 1 ? ExeUtils.ReadUInt32(exe, isLittleEndian) : ExeUtils.ReadUInt64(exe, isLittleEndian);

                    if (size != 0 && (flags & 6) == 6 && ReadName(sb, exe, nameOffset) == ".text")
                    {
                        textOffset = (int)offset;
                        textSize   = (int)size;
                        return(true);
                    }

                    f.Position = sectPos + eShentsize;
                }
            }
            catch (IOException) {
            }

            return(false);
        }