public COFFHeader(AssemblyBuffer buffer, DOSHeader currentHeader) { buffer.SetIndexPointer(currentHeader.PEHeaderPointer); this.Signature = buffer.ReadDWord(); this.Machine = buffer.ReadWord(); this.SectionCount = buffer.ReadWord(); this.TimeDataStamp = buffer.ReadDWord(); this.PointerToSymbolTable = buffer.ReadDWord(); this.NumberOfSymbols = buffer.ReadDWord(); this.SizeOfOptionalHeader = buffer.ReadWord(); this.Characteristics = buffer.ReadWord(); }
public PEAssembly(StreamParser parser) { DOSHeader dosHeader = new DOSHeader(parser); parser.Seek(dosHeader.PEHeaderOffset); PEHeader peHeader = new PEHeader(parser); if (peHeader.SizeOfOptionalHeader == 0) throw new ParseFailedException("PE missing NT header"); PEOptionalHeader peOptionalHeader = new PEOptionalHeader(parser); PESectionHeader[] sectionHeaders = new PESectionHeader[peHeader.NumberOfSections]; for (int i = 0; i < peHeader.NumberOfSections; i++) sectionHeaders[i] = new PESectionHeader(parser); SectionHeaders = sectionHeaders; DataDirectory = peOptionalHeader.DataDirectory; }
public override void SaveToDisk(string fileName) { try { using (BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write))) { DOSHeader.AppendToStream(writer); writer.Write(DOS_Stub); PEHeader.AppendToStream(writer); AppendSections(writer); } } catch { // ignored } }
public virtual void VisitDOSHeader(DOSHeader header) { }
public virtual void VisitDOSHeader(DOSHeader header) { }
private void LoadPEImage() { long fileDataSize = rdr.Bytes.Length - xexData.header.header_size; BeImageReader memRdr = new BeImageReader(xexData.memoryData); DOSHeader dosHeader = memRdr.ReadStruct <DOSHeader>(); dosHeader.Validate(); memRdr.Offset = dosHeader.e_lfanew; UInt32 peSignature = memRdr.ReadUInt32(); if (peSignature != 0x50450000) { throw new BadImageFormatException("PE: Invalid or Missing PE Signature"); } COFFHeader coffHeader = memRdr.ReadStruct <COFFHeader>(); if (coffHeader.Machine != 0x1F2) { throw new BadImageFormatException($"PE: Machine type does not match Xbox360 (found 0x{coffHeader.Machine:X})"); } if ((coffHeader.Characteristics & 0x0100) == 0) { throw new BadImageFormatException("PE: Only 32-bit images are supported"); } if (coffHeader.SizeOfOptionalHeader != 224) { throw new BadImageFormatException($"PE: Invalid size of optional header (got {coffHeader.SizeOfOptionalHeader}"); } PEOptHeader optHeader = memRdr.ReadStruct <PEOptHeader>(); if (optHeader.signature != 0x10b) { throw new BadImageFormatException($"PE: Invalid signature of optional header (got 0x{optHeader.signature})"); } if (optHeader.Subsystem != IMAGE_SUBSYSTEM_XBOX) { throw new BadImageFormatException($"PE: Invalid subsystem (got {optHeader.Subsystem})"); } xexData.peHeader = optHeader; uint extendedMemorySize = 0; uint numSections = coffHeader.NumberOfSections; List <PESection> peSections = new List <PESection>(); for (uint i = 0; i < numSections; i++) { COFFSection section = memRdr.ReadStruct <COFFSection>(); string sectionName = Encoding.ASCII.GetString(section.Name).Trim('\0'); uint lastMemoryAddress = section.VirtualAddress + section.VirtualSize; if (lastMemoryAddress > extendedMemorySize) { extendedMemorySize = lastMemoryAddress; } if (section.SizeOfRawData == 0) { decompilerEventListener.Info(new NullCodeLocation(""), $"Skipping empty section {sectionName}" ); continue; } byte[] sectionData = memRdr.ReadAt <byte[]>(section.PointerToRawData, rdr => rdr.ReadBytes(section.SizeOfRawData)); AccessMode acc = AccessMode.Read; if (section.Flags.HasFlag(PESectionFlags.IMAGE_SCN_MEM_WRITE)) { acc |= AccessMode.Write; } if (section.Flags.HasFlag(PESectionFlags.IMAGE_SCN_MEM_EXECUTE)) { acc |= AccessMode.Execute; } PESection managedSection = new PESection(section); peSections.Add(managedSection); ImageSegment seg = new ImageSegment(sectionName, new MemoryArea( new Address32(managedSection.PhysicalOffset + xexData.exe_address), sectionData ), acc); segments.Add(seg); } if (extendedMemorySize > xexData.memorySize) { decompilerEventListener.Info(new NullCodeLocation(""), $"PE: Image sections extend beyond virtual memory range loaded from file ({extendedMemorySize} > {xexData.memorySize}). Extending by {extendedMemorySize - xexData.memorySize} bytes." ); UInt32 oldMemorySize = xexData.memorySize; byte[] newMemoryData = new byte[extendedMemorySize]; Array.Copy(xexData.memoryData, newMemoryData, xexData.memorySize); xexData.memorySize = extendedMemorySize; xexData.memoryData = newMemoryData; for (int i = 0; i < peSections.Count; i++) { PESection section = peSections[i]; if (section.PhysicalSize == 0) { continue; } if (section.PhysicalSize + section.PhysicalOffset > fileDataSize) { decompilerEventListener.Warn(new NullCodeLocation(""), $"PE: Section '{section.Name}' lies outside any phyisical data we have {section.PhysicalOffset} (size {section.PhysicalSize})" ); continue; } if (section.VirtualOffset >= oldMemorySize) { uint sizeToCopy = section.PhysicalSize; if (section.VirtualSize < sizeToCopy) { sizeToCopy = section.VirtualSize; } Array.Copy( xexData.memoryData, section.PhysicalOffset, newMemoryData, section.VirtualOffset, sizeToCopy); } } } }
public unsafe static IEnumerable <ProcessModule> AppendHiddenModules(this ProcessModuleCollection collection, Process process = null) { var hModules = new IntPtr[1024]; var gcHandle = GCHandle.Alloc(hModules, GCHandleType.Pinned); // Don't forget to free this later var pModules = gcHandle.AddrOfPinnedObject(); var size = (uint)(Marshal.SizeOf(typeof(IntPtr)) * (hModules.Length)); IntPtr minAddress; IntPtr maxAddress; uint hProcess; MEMORY_BASIC_INFORMATION memBasicInfo; uint regionSize = 0; var sysInfo = new SYSTEM_INFO(); var processsModuleType = typeof(ProcessModule); var moduleInfoType = processsModuleType.Assembly.GetTypes().SingleOrDefault(t => t.FullName == "System.Diagnostics.ModuleInfo"); var processModuleConstructor = processsModuleType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { moduleInfoType }, null); var list = new List <ProcessModule>(collection.Cast <ProcessModule>()); var listAddFrom = new List <ProcessModule>(); GetSystemInfo(out sysInfo); minAddress = sysInfo.MinimumApplicationAddress; maxAddress = sysInfo.MaximumApplicationAddress; if (process == null) { process = Process.GetCurrentProcess(); } hProcess = OpenProcess(ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VirtualMemoryRead, false, (uint)process.Id); memBasicInfo = new MEMORY_BASIC_INFORMATION(); while (minAddress.ToPointer() < maxAddress.ToPointer()) { uint length = 0; var builder = new StringBuilder(1024); builder.Clear(); VirtualQueryEx(hProcess, minAddress, out memBasicInfo, 28); regionSize = memBasicInfo.RegionSize; if (memBasicInfo.Protect == AllocationProtectEnum.PAGE_READONLY | memBasicInfo.Protect == AllocationProtectEnum.PAGE_READWRITE | memBasicInfo.Protect == AllocationProtectEnum.PAGE_EXECUTE_READ | memBasicInfo.Protect == AllocationProtectEnum.PAGE_EXECUTE_READWRITE) { length = GetMappedFileName(hProcess, memBasicInfo.BaseAddress, builder, 1024); if (length != 0) { uint bytesRead = 0; var buffer = new byte[memBasicInfo.RegionSize]; var deviceName = builder.ToString(); byte[] bytes; string magic; string signature; ReadProcessMemory(hProcess, memBasicInfo.BaseAddress, buffer, memBasicInfo.RegionSize, ref bytesRead); if (bytesRead >= (DOSHeader.Size + PEHeader.Size)) { var assemblyReader = new BinaryReader(buffer.ToMemory()); var dosHeader = DOSHeader.ReadDOSHeader(assemblyReader); bytes = BitConverter.GetBytes(dosHeader.MagicBytes); magic = ASCIIEncoding.ASCII.GetString(bytes, 0, 2); if (magic == "MZ") { var peheader = PEHeader.ReadPEHeader(assemblyReader, dosHeader.COFFHeaderAddress); bytes = BitConverter.GetBytes(peheader.SignatureBytes); signature = ASCIIEncoding.ASCII.GetString(bytes, 0, 2); if (signature == "PE") { string fileName; Files.ConvertDevicePathToLocalPath(deviceName, out fileName); if (!collection.Cast <ProcessModule>().Any(m => m.FileName.AsCaseless() == fileName)) { var moduleInfo = Activator.CreateInstance(moduleInfoType); string baseName; ProcessModule processModule; baseName = Path.GetFileName(fileName); moduleInfoType.SetFieldValue("baseName", moduleInfo, baseName); moduleInfoType.SetFieldValue("baseOfDll", moduleInfo, new IntPtr(memBasicInfo.BaseAddress)); moduleInfoType.SetFieldValue("entryPoint", moduleInfo, new IntPtr(peheader.AddressOfEntryPoint)); moduleInfoType.SetFieldValue("fileName", moduleInfo, fileName); moduleInfoType.SetFieldValue("sizeOfImage", moduleInfo, (int)peheader.SizeOfImage); processModule = (ProcessModule)processModuleConstructor.Invoke(new object[] { moduleInfo }); regionSize = peheader.SizeOfImage; listAddFrom.Add(processModule); } } } } } } minAddress += (int)regionSize; } return(list.Concat(listAddFrom)); }