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); }
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); }
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); }