Exemple #1
0
 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();
 }
Exemple #2
0
        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;
        }
Exemple #3
0
 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)
 {
 }
Exemple #6
0
        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));
        }