예제 #1
0
        public override Program LoadProgram(Address?addrLoad)
        {
            var cfgSvc   = Services.RequireService <IConfigurationService>();
            var arch     = cfgSvc.GetArchitecture("arm-64") !;
            var platform = cfgSvc.GetEnvironment("switch").Load(Services, arch);

            NroStart  start  = rdr.ReadStruct <NroStart>();
            NroHeader header = rdr.ReadStruct <NroHeader>();

            if (header.magic != MAGIC)
            {
                throw new BadImageFormatException("Invalid NRO Magic.");
            }

            HandleSegment(NroSegmentType.Text, header.segments0[0]);
            HandleSegment(NroSegmentType.Ro, header.segments0[1]);
            HandleSegment(NroSegmentType.Data, header.segments0[2]);

            HandleSegment(NroSegmentType.ApiInfo, header.segments1[0]);
            HandleSegment(NroSegmentType.DynStr, header.segments1[1]);
            HandleSegment(NroSegmentType.DynSym, header.segments1[2]);

            SegmentMap segMap  = new SegmentMap(PreferredBaseAddress, segments.ToArray());
            Program    program = new Program(segMap, arch, platform);

            return(program);
        }
예제 #2
0
        private void ReadMod0(byte[] dcmpTextData, SegmentMap map)
        {
            var f    = new LeImageReader(dcmpTextData);
            var mod0 = f.ReadStruct <Mod0>();

            if (!map.TryFindSegment(mod0.DynamicOffset, out var dynseg))
            {
                return;
            }

            var offset = mod0.DynamicOffset - dynseg.MemoryArea.BaseAddress.ToLinear();

            offset += mod0.MagicOffset;
            var rdr    = dynseg.MemoryArea.CreateLeReader((int)offset);
            var elfHdr = new Elf32_EHdr {
                e_machine = (ushort)ElfMachine.EM_ARM
            };
            var elfLoader = new ElfLoader32(Services, elfHdr, 0, EndianServices.Little, RawImage);

            var(deps, entries) = elfLoader.LoadDynamicSegment(rdr);

            var dynEntries = entries.ToDictionary(e => e.Tag, e => e.UValue);
            var syms       = LoadSymbols(map, dynEntries);

            LoadRelocations(map, dynEntries, syms);
        }
예제 #3
0
        public void Sr_ReadLeInt32_Field()
        {
            var rdr  = new LeImageReader(new byte[] { 0x34, 0x12, 0xAB, 0xCD, 0x78, 0x56, 0x34, 0x12 });
            var test = rdr.ReadStruct <TestStruct2>();

            Assert.AreEqual((int)0x12345678, test.lField);
        }
예제 #4
0
        public void Sr_ReadLeUInt16_Field()
        {
            var rdr  = new LeImageReader(new byte[] { 0x34, 0x12 });
            var test = rdr.ReadStruct <TestStruct>();

            Assert.AreEqual((ushort)0x1234, test.usField);
        }
예제 #5
0
        public override Program Load(Address?addrLoad)
        {
            addrLoad ??= PreferredBaseAddress;
            var cfgSvc = Services.RequireService <IConfigurationService>();

            this.arch     = cfgSvc.GetArchitecture("x86-protected-32") !;
            this.platform = cfgSvc.GetEnvironment("ms-dos-386")
                            .Load(Services, arch);
            var rdr        = new LeImageReader(RawImage, FileHeaderOffset);
            var fileHeader = rdr.ReadStruct <FileHeader>();
            var image      = new ByteMemoryArea(Address.Ptr32(fileHeader.base_load_offset), new byte[fileHeader.memory_requirements]);

            if ((fileHeader.flags & FlagImagePacked) != 0)
            {
                UnpackImage(fileHeader, image);
            }
            var loadseg = new ImageSegment("DOSX_PROG", image, AccessMode.ReadWriteExecute);

            this.segmentMap = new SegmentMap(addrLoad);
            var seg = this.segmentMap.AddSegment(loadseg);

            this.program = new Program(this.segmentMap, this.arch, platform);
            var ep = ImageSymbol.Procedure(
                this.arch,
                Address.Ptr32(fileHeader.initial_EIP),
                "_start");

            this.program.EntryPoints.Add(ep.Address, ep);
            return(program);
        }
예제 #6
0
        }     // GetResource

        private static void LSet <T>(out T d, byte[] cs, int offset)
            where T : struct
        {
            var rdr = new LeImageReader(cs, offset);

            d = rdr.ReadStruct <T>();
        }
예제 #7
0
파일: XbeLoader.cs 프로젝트: claunia/reko
        private List <ImageSegment> LoadPrimarySections()
        {
            List <ImageSegment> segments = new List <ImageSegment>((int)hdr.NumberOfSections + 1);

            int i;

            for (i = 0; i < hdr.NumberOfSections; i++)
            {
                XbeSectionHeader sectionHeader = rdr.ReadStruct <XbeSectionHeader>();
                XbeSection       section       = new XbeSection(sectionHeader);

                string sectionName = rdr.ReadAt <string>(section.NameAddress - ctx.BaseAddress, (rdr) =>
                {
                    return(rdr.ReadCString(PrimitiveType.Char, Encoding.ASCII).ToString());
                });

                long sectionOffset = section.Address - ctx.EntryPointAddress;

                AccessMode accessFlgs = AccessMode.Read;
                if (sectionHeader.Flags.HasFlag(XbeSectionFlags.Executable))
                {
                    accessFlgs |= AccessMode.Execute;
                }
                if (sectionHeader.Flags.HasFlag(XbeSectionFlags.Writable))
                {
                    accessFlgs |= AccessMode.Write;
                }

                ImageSegment segment = new ImageSegment(
                    sectionName,
                    new ByteMemoryArea(section.Address, rdr.ReadAt <byte[]>(sectionOffset, (rdr) =>
                {
                    return(rdr.CreateBinaryReader().ReadBytes((int)sectionHeader.RawSize));
                })), accessFlgs);

                segments.Add(segment);
            }

            return(segments);
        }
예제 #8
0
        public override Program Load(Address?addrLoad)
        {
            var       @in       = new LeImageReader(RawImage);
            NSOHeader nsoHeader = @in.ReadStruct <NSOHeader>();

            byte[] dcmpText = new byte[nsoHeader.dcmpSize_text];
            LZ4Codec.Decode(
                RawImage, (int)nsoHeader.fileOffset_text, (int)nsoHeader.cmpSize_text,
                dcmpText, 0, (int)nsoHeader.dcmpSize_text);

            byte[] dcmpRodata = new byte[nsoHeader.dcmpSize_rodata];
            LZ4Codec.Decode(
                RawImage, (int)nsoHeader.fileOffset_rodata, (int)nsoHeader.cmpSize_rodata,
                dcmpRodata, 0, (int)nsoHeader.dcmpSize_rodata);

            byte[] dcmpDataData = new byte[nsoHeader.dcmpSize_data];
            LZ4Codec.Decode(
                RawImage, (int)nsoHeader.fileOffset_data, (int)nsoHeader.cmpSize_data,
                dcmpDataData, 0, (int)nsoHeader.dcmpSize_data);

            var segText = MakeSeg(".text", nsoHeader.memoryOffset_text, dcmpText, AccessMode.ReadExecute);
            var segRo   = MakeSeg(".rodata", nsoHeader.memoryOffset_rodata, dcmpRodata, AccessMode.Read);
            var segData = MakeSeg(".data", nsoHeader.memoryOffset_data, dcmpDataData, AccessMode.ReadWrite);

            var segmap = new SegmentMap(segText, segRo, segData);

            ReadMod0(dcmpText, segmap);

            var cfg  = Services.RequireService <IConfigurationService>();
            var arch = cfg.GetArchitecture("arm");

            if (arch is null)
            {
                throw new InvalidOperationException("Unable to load arm-thumb architecture.");
            }
            var platform = cfg.GetEnvironment("switch").Load(Services, arch);

            return(new Program(segmap, arch, platform));
        }
예제 #9
0
        // ***************************************
        //  gets TypeLib data from a PE file's resource section
        unsafe int GetTypeLibData(string ccs, string fs)
        {
            //#Register All
            FileStream    ff;// file handle
            int           n;
            int           fTlb = 0;
            DosHeader     DosHdr;
            PEHeader      pPH;
            SectionInfo   si = new SectionInfo();
            OptHeader     pOH;
            SectionHeader pSH;
            DataDir       pDD;


            // --------------------------------------
            // get the Typelib data
            try
            {
                ff = new FileStream(fs, FileMode.Open, FileAccess.Read, FileShare.Read);

                byte[] cs = new byte[2048];
                ff.Read(cs, 0, cs.Length);

                // ----------------------------------
                // get PE signature if present
                var rdr = new LeImageReader(cs, 0);
                DosHdr = rdr.ReadStruct <DosHeader>();
                uint lfanew = DosHdr.lfaNew;
                if (DosHdr.Magic == 0x5A4D &&
                    cs[lfanew] == 'P' && cs[lfanew + 1] == 'E' && cs[lfanew + 2] == 0 && cs[lfanew + 3] == 0)
                {
                    --fTlb;     // disable loading the file below
                    rdr = new LeImageReader(cs, lfanew);
                    pPH = rdr.ReadStruct <PEHeader>();
                    pOH = rdr.ReadStruct <OptHeader>();

                    // "pOH.NumberOfRvaAndSizes" is the number of entries, not the size of the array, as someone once wrote
                    if (ResourceSection > @pOH.NumberOfRvaAndSizes)
                    {
                        return(0);
                    }

                    LSet(out pDD, cs, (int)rdr.Offset + ((ResourceSection - 1) * sizeof(DataDir)));
                    si.dRVA  = @pDD.RVA;
                    si.dSize = @pDD.DirSize;


                    // find the section which matches si.dRVA in the section table
                    int ish = (int)rdr.Offset + (int)@pOH.NumberOfRvaAndSizes * sizeof(DataDir);
                    for (n = 1; n <= @pPH.NumberOfSections; ++n)
                    {
                        LSet(out pSH, cs, ish);
                        if ((si.dRVA >= @pSH.RVA) && (si.dRVA < @pSH.RVA + @pSH.SizeOfRawData))
                        {
                            si.SectName        = @pSH.SectName;
                            si.VirtSize        = @pSH.VirtSize;                          // size of unpadded section
                            si.RVA             = @pSH.RVA;                               // @pSH.RVA is the offset to section when loaded
                            si.RamAdd          = @pOH.ImageBase + @pSH.RVA;              // section// s RAM address (for example: &H401000)
                            si.SizeOfRawData   = @pSH.SizeOfRawData;                     // size after padding to section alignment
                            si.PtrToRawData    = @pSH.PtrToRawData;                      // zero-based file offset to section
                            si.StrPos          = @pSH.PtrToRawData + 1;                  // one-based file offset to section
                            si.EndPos          = si.StrPos + si.SizeOfRawData;
                            si.Delta           = si.RVA - si.PtrToRawData;               // value to subtract from RVAs to get file offsets
                            si.Characteristics = @pSH.Characteristics;
                            break;
                        }
                        ish = ish + sizeof(SectionHeader);         // advance pSH to next section header
                    }

                    // get TypeLib resource
                    ff.Position = (int)si.PtrToRawData;
                    cs          = new byte[si.SizeOfRawData];
                    ff.Read(cs, 0, cs.Length);
                    fixed(byte *pcs = cs)
                    {
                        if (GetResource(pcs, si.Delta, si.SizeOfRawData, si.PtrToRawData) == 0)
                        {
                            UpdateLog("No TypeLib data found in: " + fs);
                        }
                    }
                }


                if (Encoding.ASCII.GetString(cs, 0, 4) == "MSFT")   // it's a "tlb" (TypeLib) file
                {
                    ++fTlb;
                    return(1);
                }
                else if (Encoding.ASCII.GetString(cs, 0, 4) == "SLTG")
                {
                    ++fTlb;
                    return(2);
                }

                if (fTlb > 0)
                {
                    ff.Position = 0;
                    cs          = new byte[ff.Length];
                    ff.Read(cs, 0, cs.Length);
                }

                ff.Close();
            } catch
            {
                UpdateLog("Error opening input file: " + fs);
                return(-1);
            }
        }