예제 #1
0
 public static object ReadLeaf(LeImageReader rdr)
 {
     var b = rdr.ReadByte();
     var lt = (LeafType) b;
     switch (lt)
     {
     default:
         throw new NotImplementedException($"CodeView leaf type {lt} {(int)lt:X2} not implemented yet.");
     case LeafType.Int8:
         return rdr.ReadSByte();
     case LeafType.UInt16:
         return rdr.ReadLeUInt16();
     case LeafType.ARRAY:
         return ReadArray(rdr);
     case LeafType.INDEX:    // Type index
         return rdr.ReadLeUInt16();
     case LeafType.LABEL:
         return ReadLabel(rdr);
     case LeafType.LIST:
         return ReadList(rdr);
     case LeafType.POINTER:
         return ReadPointer(rdr);
     case LeafType.PROCEDURE:
         return ReadProcedure(rdr);
     case LeafType.STRING:
         return ReadString(rdr);
     case LeafType.STRUCTURE:
         return ReadStructure(rdr);
     case LeafType.Nil:
     case LeafType.C_FAR:
     case LeafType.C_NEAR:
     case LeafType.FAR:
     case LeafType.NEAR:
     case LeafType.UNPACKED:
     case (LeafType) 0x81:   //$REVIEW: void?
         return lt;
     }
 }
예제 #2
0
        public override RelocationResults Relocate(Program program, Address addrLoad)
        {
            ImageMap    imageMap    = imgLoadedMap;
            ImageReader rdr         = new LeImageReader(exe.RawImage, (uint)exe.e_lfaRelocations);
            var         relocations = new RelocationDictionary();
            int         i           = exe.e_cRelocations;

            while (i != 0)
            {
                uint   offset    = rdr.ReadLeUInt16();
                ushort segOffset = rdr.ReadLeUInt16();
                offset += segOffset * 0x0010u;

                ushort seg = (ushort)(imgLoaded.ReadLeUInt16(offset) + addrLoad.Selector.Value);
                imgLoaded.WriteLeUInt16(offset, seg);
                relocations.AddSegmentReference(offset, seg);

                imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute, 0);
                --i;
            }

            // Found the start address.

            Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector.Value), exe.e_ip);

            imageMap.AddSegment(
                Address.SegPtr(addrStart.Selector.Value, 0),
                addrStart.Selector.Value.ToString("X4"),
                AccessMode.ReadWriteExecute, 0);
            return(new RelocationResults(
                       new List <EntryPoint> {
                new EntryPoint(addrStart, arch.CreateProcessorState())
            },
                       relocations,
                       new List <Address>()));
        }
예제 #3
0
 public TypeDefinition ReadTypeDefinition()
 {
     var linkage = rdr.ReadByte();
     var length = rdr.ReadLeUInt16();
     var rdrLeaves = new LeImageReader(rdr.ReadBytes(length));
     var leaves = new List<object>();
     while (rdrLeaves.IsValid)
     {
         leaves.Add(ReadLeaf(rdrLeaves));
     }
     return new TypeDefinition
     {
         linkage = linkage,
         Leaves = leaves.ToArray()
     };
 }
예제 #4
0
 void LoadModuleTable(uint offset, int cModules)
 {
     var rdr = new LeImageReader(RawImage, offset);
     this.moduleNames = new List<string>();
     for (int i = 0; i < cModules; ++i)
     {
         uint nameOffset = rdr.ReadLeUInt16();
         if (nameOffset == 0)
             break;
         nameOffset += lfaNew + this.offImportedNamesTable;
         var rdrName = new LeImageReader(RawImage, nameOffset);
         byte length = rdrName.ReadByte();
         byte[] abModuleName = rdrName.ReadBytes(length);
         var moduleName = Encoding.ASCII.GetString(abModuleName);
         moduleNames.Add(moduleName);
     }
 }
예제 #5
0
        private FileHeader LoadHeader()
        {
            var rdr   = new LeImageReader(RawImage, 0);
            var magic = rdr.ReadLeUInt16();

            switch (magic)
            {
            case 0x014C: arch = new IntelArchitecture(ProcessorMode.Protected32); break;

            default: throw new NotSupportedException();
            }
            return(new FileHeader
            {
                f_magic = magic,
                f_nscns = rdr.ReadUInt16(),
                f_timdat = rdr.ReadUInt32(),
                f_symptr = rdr.ReadUInt32(),
                f_nsyms = rdr.ReadUInt32(),
                f_opthdr = rdr.ReadUInt16(),
                f_flags = rdr.ReadUInt16(),
            });
        }
예제 #6
0
        private FileHeader LoadHeader()
        {
            var rdr    = new LeImageReader(RawImage, 0);
            var magic  = rdr.ReadLeUInt16();
            var cfgSvc = Services.RequireService <IConfigurationService>();

            switch (magic)
            {
            case 0x014C: arch = cfgSvc.GetArchitecture("x86-real-16"); break;

            default: throw new NotSupportedException();
            }
            return(new FileHeader
            {
                f_magic = magic,
                f_nscns = rdr.ReadUInt16(),
                f_timdat = rdr.ReadUInt32(),
                f_symptr = rdr.ReadUInt32(),
                f_nsyms = rdr.ReadUInt32(),
                f_opthdr = rdr.ReadUInt16(),
                f_flags = rdr.ReadUInt16(),
            });
        }
예제 #7
0
        public ExePackLoader(MsdosImageLoader loader)
            : base(loader.Services, loader.Filename, loader.RawImage)
        {
            var cfgSvc = Services.RequireService <IConfigurationService>();

            arch     = cfgSvc.GetArchitecture("x86-real-16") !;
            platform = cfgSvc.GetEnvironment("ms-dos")
                       .Load(Services, arch);

            var exe = loader.ExeLoader;

            this.exeHdrSize = (uint)(exe.e_cparHeader * 0x10U);
            this.hdrOffset  = (uint)(exe.e_cparHeader + exe.e_cs) * 0x10U;
            EndianImageReader rdr = new LeImageReader(RawImage, hdrOffset);

            this.ip = rdr.ReadLeUInt16();
            this.cs = rdr.ReadLeUInt16();
            rdr.ReadLeUInt16();
            this.cbExepackHeader = rdr.ReadLeUInt16();
            this.sp             = rdr.ReadLeUInt16();
            this.ss             = rdr.ReadLeUInt16();
            this.cpUncompressed = rdr.ReadLeUInt16();

            int offset = ExePackHeaderOffset(loader.ExeLoader);

            if (ByteMemoryArea.CompareArrays(loader.RawImage, offset, signature, signature.Length))
            {
                relocationsOffset = 0x012D;
            }
            else if (ByteMemoryArea.CompareArrays(loader.RawImage, offset, signature2, signature2.Length))
            {
                relocationsOffset = 0x0125;
            }
            else
            {
                throw new ApplicationException("Not a recognized EXEPACK image.");
            }
            this.imgU       = null !;
            this.segmentMap = null !;
        }
예제 #8
0
        public ExePackLoader(IServiceProvider services, string filename, byte[] imgRaw)
            : base(services, filename, imgRaw)
        {
            var cfgSvc = services.RequireService <IConfigurationService>();

            arch     = cfgSvc.GetArchitecture("x86-real-16");
            platform = cfgSvc.GetEnvironment("ms-dos")
                       .Load(Services, arch);

            var exe = new ExeImageLoader(services, filename, imgRaw);

            this.exeHdrSize = (uint)(exe.e_cparHeader * 0x10U);
            this.hdrOffset  = (uint)(exe.e_cparHeader + exe.e_cs) * 0x10U;
            EndianImageReader rdr = new LeImageReader(RawImage, hdrOffset);

            this.ip = rdr.ReadLeUInt16();
            this.cs = rdr.ReadLeUInt16();
            rdr.ReadLeUInt16();
            this.cbExepackHeader = rdr.ReadLeUInt16();
            this.sp             = rdr.ReadLeUInt16();
            this.ss             = rdr.ReadLeUInt16();
            this.cpUncompressed = rdr.ReadLeUInt16();

            int offset = ExePackHeaderOffset(exe);

            if (MemoryArea.CompareArrays(imgRaw, offset, signature, signature.Length))
            {
                relocationsOffset = 0x012D;
            }
            else if (MemoryArea.CompareArrays(imgRaw, offset, signature2, signature2.Length))
            {
                relocationsOffset = 0x0125;
            }
            else
            {
                throw new ApplicationException("Not a recognized EXEPACK image.");
            }
        }
예제 #9
0
        public override RelocationResults Relocate(Program program, Address addrLoad)
        {
            SegmentMap        imageMap = segmentMap;
            EndianImageReader rdr      = new LeImageReader(exe.RawImage, exe.e_lfaRelocations);
            var relocations            = imgLoaded.Relocations;
            int i        = exe.e_cRelocations;
            var segments = new Dictionary <Address, ushort>();
            var linBase  = addrLoad.ToLinear();

            while (i != 0)
            {
                uint   offset    = rdr.ReadLeUInt16();
                ushort segOffset = rdr.ReadLeUInt16();
                offset += segOffset * 0x0010u;

                ushort seg = (ushort)(imgLoaded.ReadLeUInt16(offset) + addrLoad.Selector.Value);
                imgLoaded.WriteLeUInt16(offset, seg);
                relocations.AddSegmentReference(offset + linBase, seg);

                var segment = new ImageSegment(
                    seg.ToString("X4"),
                    Address.SegPtr(seg, 0),
                    imgLoaded,
                    AccessMode.ReadWriteExecute);
                segment = segmentMap.AddSegment(segment);
                segments[segment.Address] = seg;
                --i;
            }

            // Create an identifier for each segment.
            foreach (var de in segments)
            {
                var tmp = new TemporaryStorage(
                    string.Format("seg{0:X4}", de.Value),
                    0,
                    PrimitiveType.SegmentSelector);
                segmentMap.Segments[de.Key].Identifier = new Identifier(
                    tmp.Name,
                    PrimitiveType.SegmentSelector,
                    tmp);
            }

            // Found the start address.

            Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector.Value), exe.e_ip);

            segmentMap.AddSegment(new ImageSegment(
                                      addrStart.Selector.Value.ToString("X4"),
                                      Address.SegPtr(addrStart.Selector.Value, 0),
                                      imgLoaded,
                                      AccessMode.ReadWriteExecute));
            DumpSegments(imageMap);

            var ep = new ImageSymbol(addrStart)
            {
                Type           = SymbolType.Procedure,
                ProcessorState = arch.CreateProcessorState()
            };
            var sym     = platform.FindMainProcedure(program, addrStart);
            var results = new RelocationResults(
                new List <ImageSymbol> {
                ep
            },
                new SortedList <Address, ImageSymbol> {
                { ep.Address, ep }
            });

            if (sym != null)
            {
                results.Symbols[sym.Address] = sym;
                ep.NoDecompile = true;
            }

            try
            {
                LoadDebugSymbols(results.Symbols, addrLoad);
            }
            catch (Exception ex)
            {
                var listener = Services.RequireService <DecompilerEventListener>();
                listener.Error(
                    new NullCodeLocation(Filename),
                    ex,
                    "Detected Borland debug symbols but failed to load them.");
            }
            return(results);
        }
예제 #10
0
        public ByteMemoryArea Unpack(byte [] abC, Address addrLoad)
        {
            // Extract the LZ stuff.

            EndianImageReader rdr = new LeImageReader(abC, (uint)lzHdrOffset);

            lzIp = rdr.ReadLeUInt16();
            lzCs = rdr.ReadLeUInt16();
            ushort lzSp             = rdr.ReadLeUInt16();
            ushort lzSs             = rdr.ReadLeUInt16();
            ushort lzcpCompressed   = rdr.ReadLeUInt16();
            ushort lzcpDecompressed = rdr.ReadLeUInt16();

            // Find the start of the compressed stream.

            int ifile = lzHdrOffset - (lzcpCompressed << 4);

            // Allocate space for the decompressed goo.

            int cbUncompressed = ((int)lzcpDecompressed + lzcpDecompressed) << 4;

            byte [] abU = new byte[cbUncompressed];

            // Decompress this sorry mess.

            int       len;
            int       span;
            int       p    = 0;
            BitStream bits = new BitStream(abC, ifile);

            for (;;)
            {
                if (bits.GetBit() != 0)
                {
                    // 1....
                    abU[p++] = bits.GetByte();
                    continue;
                }

                if (bits.GetBit() == 0)
                {
                    // 00.....
                    len  = bits.GetBit() << 1;
                    len |= bits.GetBit();
                    len += 2;
                    span = bits.GetByte() | ~0xFF;
                }
                else
                {
                    // 01.....

                    span  = bits.GetByte();
                    len   = bits.GetByte();;
                    span |= ((len & ~0x07) << 5) | ~0x1FFF;
                    len   = (len & 0x07) + 2;
                    if (len == 2)
                    {
                        len = bits.GetByte();

                        if (len == 0)
                        {
                            break;                                // end mark of compressed load module
                        }
                        if (len == 1)
                        {
                            continue;                             // segment change
                        }
                        else
                        {
                            ++len;
                        }
                    }
                }
                for ( ; len > 0; --len, ++p)
                {
                    abU[p] = abU[p + span];
                }
            }

            // Create a new image based on the uncompressed data.

            this.imgLoaded  = new ByteMemoryArea(addrLoad, abU);
            this.segmentMap = new SegmentMap(
                addrLoad,
                new ImageSegment("", this.imgLoaded, AccessMode.ReadWriteExecute));
            return(imgLoaded);
        }
예제 #11
0
        public void ReadCommonExeFields()
        {
            EndianImageReader rdr = new LeImageReader(RawImage, 0);

            e_magic             = rdr.ReadLeUInt16();
            e_cbLastPage        = rdr.ReadLeUInt16();
            e_cpImage           = rdr.ReadLeUInt16();
            this.e_cRelocations = rdr.ReadLeUInt16();
            e_cparHeader        = rdr.ReadLeUInt16();
            e_minalloc          = rdr.ReadLeUInt16();
            e_maxalloc          = rdr.ReadLeUInt16();
            e_ss             = rdr.ReadLeUInt16();
            e_sp             = rdr.ReadLeUInt16();
            e_csum           = rdr.ReadLeUInt16();
            e_ip             = rdr.ReadLeUInt16();
            e_cs             = rdr.ReadLeUInt16();
            e_lfaRelocations = rdr.ReadLeUInt16();
            e_ovno           = rdr.ReadLeUInt16();
        }
예제 #12
0
        public bool SetupLibCheck(IServiceProvider services, string fpath, byte[] bytes)
        {
            var listener = services.RequireService<DecompilerEventListener>();
            var rdr = new LeImageReader(bytes);
            ushort w, len;
            int i;

            //readProtoFile();

            /* Read the parameters */
            if (!rdr.TryReadLeUInt32(out uint fileSig) || fileSig != 0x73636364) // "dccs"
            {
                listener.Warn(string.Format("{0} is not a DCC signature file.", fpath));
                return false;
            }

            numKeys = rdr.ReadLeUInt16();
            numVert = rdr.ReadLeUInt16();
            PatLen = rdr.ReadLeUInt16();
            SymLen = rdr.ReadLeUInt16();
            if ((PatLen != PATLEN) || (SymLen != SYMLEN))
            {
                listener.Warn(string.Format("Can't use signature file with sym and pattern lengths of {0} and {1}.", SymLen, PatLen));
                return false;
            }

            // Initialise the perfhlib stuff. Also allocates T1, T2, g, etc
            // Set the parameters for the hash table
            g_pattern_hasher.setHashParams(
                            numKeys,                // The number of symbols
                            PatLen,                 // The length of the pattern to be hashed
                            256,                    // The character set of the pattern (0-FF)
                            (char)0,                // Minimum pattern character value
                            numVert);               // Specifies c, the sparseness of the graph. See Czech, Havas and Majewski for details
            T1base = g_pattern_hasher.readT1();
            T2base = g_pattern_hasher.readT2();
            g = g_pattern_hasher.readG();

            /* Read T1 and T2 tables */
            ushort ww;
            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x3154)    // "T1"
            {
                Debug.Print("Expected 'T1'");
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            len = (ushort) (PatLen * 256u * 2);        // 2 = sizeof ushort
            w = rdr.ReadLeUInt16();
            if (w != len)
            {
                Debug.Print("Problem with size of T1: file {0}, calc {1}", w, len);
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            readFileSection(T1base, len, rdr);

            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x3254)    // "T2"
            {
                Debug.Print("Expected 'T2'");
                return false;
            }
            w = rdr.ReadLeUInt16();
            if (w != len)
            {
                Debug.Print("Problem with size of T2: file %d, calc %d\n", w, len);
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            readFileSection(T2base, len, rdr);

            /* Now read the function g[] */
            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x6767)    // "gg"
            {
                Debug.Print("Expected 'gg'");
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            len = (ushort) (numVert * 2); //  sizeof(uint16_t));
            w = rdr.ReadLeUInt16();
            if (w != len)
            {
                Debug.Print("Problem with size of g[]: file {0}, calc {1}", w, len);
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            readFileSection(g, len, rdr);

            /* This is now the hash table */
            /* First allocate space for the table */
            ht = new HT[numKeys];
            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x7468)    // "ht"
            {
                Debug.Print("Expected 'ht'");
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            w = rdr.ReadLeUInt16();
            if (w != numKeys * (SymLen + PatLen + 2)) // sizeof(uint16_t)))
            {
                Debug.Print("Problem with size of hash table: file {0}, calc {1}", w, len);
                listener.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }

            ht = new HT[numKeys];
            for (i = 0; i < numKeys; i++)
            {
                var aSym = rdr.ReadBytes(SymLen)
                    .TakeWhile(b => b != 0).ToArray();

                ht[i] = new HT
                {
                    htSym = Encoding.ASCII.GetString(aSym),
                    htPat = rdr.ReadBytes(PatLen)
                };
            }
            return true;
        }
예제 #13
0
        /*  DCCLIBS.DAT is a data file sorted on function name containing names and
            return types of functions found in include files, and the names and types
            of arguements. Only functions in this list will be considered library
            functions; others (like LXMUL@) are helper files, and need to be analysed
            by dcc, rather than considered as known functions. When a prototype is
            found (in searchPList()), the parameter info is written to the proc struct.
        */
        void readProtoFile(IServiceProvider services)
        {
            var diagSvc = services.RequireService<IDiagnosticsService>();
            var cfgSvc = services.RequireService<IConfigurationService>();
            var szProFName = cfgSvc.GetInstallationRelativePath("msdos", DCCLIBS); /* Full name of dclibs.lst */
            var fsSvc = services.RequireService<IFileSystemService>();
            if (fsSvc.FileExists(szProFName))
            {
                diagSvc.Warn(string.Format("Cannot open library prototype data file {0}.", szProFName));
                return;
            }
            var bytes = fsSvc.ReadAllBytes(szProFName);
            var fProto = new LeImageReader(bytes);
            int i;

            uint fileSig = fProto.ReadLeUInt32();
            if (fileSig != 0x70636364)      // "dccp"
            {
                diagSvc.Warn(string.Format("{0} is not a dcc prototype file.", szProFName));
                return;
            }

            ushort sectionID = fProto.ReadLeUInt16();
            if (sectionID != 0x4E46)        // "FN"
            {
                Debug.Print("FN (Function) subsection expected in {0}", szProFName);
                diagSvc.Warn(string.Format("{0} is not a dcc prototype file.", szProFName));
                return;
            }
            numFunc = fProto.ReadLeUInt16();    /* Num of entries to allocate */

            /* Allocate exactly correct # entries */
            pFunc = new PH_FUNC_STRUCT[numFunc];

            for (i = 0; i < numFunc; i++)
            {
                var symbuf = fProto.ReadBytes(SYMLEN);
                if (symbuf.Length != SYMLEN)
                    break;
                pFunc[i].typ = (hlType)fProto.ReadLeUInt16();
                pFunc[i].numArg = fProto.ReadLeUInt16();
                pFunc[i].firstArg = fProto.ReadLeUInt16();
                int c = fProto.ReadByte();
                pFunc[i].bVararg = (c != 0); //fread(&pFunc[i].bVararg, 1, 1, fProto);
            }

            sectionID = fProto.ReadLeUInt16();
            if (sectionID != 0x4D50)    // "PM"
            {
                Debug.Print("PM (Parameter) subsection expected in {0}", szProFName);
                return;
            }

            numArg = fProto.ReadLeUInt16();     /* Num of entries to allocate */

            /* Allocate exactly correct # entries */
            pArg = new hlType[numArg];

            for (i = 0; i < numArg; i++)
            {
                //      fread(&pArg[i], 1, SYMLEN, fProto);     /* No names to read as yet */
                pArg[i] = (hlType)fProto.ReadLeUInt16();
            }
        }
예제 #14
0
        public void ReadCommonExeFields()
        {
            ImageReader rdr = new LeImageReader(RawImage, 0);

            e_magic             = rdr.ReadLeUInt16();
            e_cbLastPage        = rdr.ReadLeUInt16();
            e_cpImage           = rdr.ReadLeUInt16();
            this.e_cRelocations = rdr.ReadLeUInt16();
            e_cparHeader        = rdr.ReadLeUInt16();
            e_minalloc          = rdr.ReadLeUInt16();
            e_maxalloc          = rdr.ReadLeUInt16();
            e_ss             = rdr.ReadLeUInt16();
            e_sp             = rdr.ReadLeUInt16();
            e_csum           = rdr.ReadLeUInt16();
            e_ip             = rdr.ReadLeUInt16();
            e_cs             = rdr.ReadLeUInt16();
            e_lfaRelocations = rdr.ReadLeUInt16();
            e_ovno           = rdr.ReadLeUInt16();
            e_res            = new ushort[4];
            for (int i = 0; i != 4; ++i)
            {
                e_res[i] = rdr.ReadLeUInt16();
            }
            e_oemid   = rdr.ReadLeUInt16();
            e_oeminfo = rdr.ReadLeUInt16();
            e_res2    = new ushort[10];
            for (int i = 0; i != 10; ++i)
            {
                e_res2[i] = rdr.ReadLeUInt16();
            }
            e_lfanew = rdr.ReadLeUInt32();
        }
예제 #15
0
파일: VmsExeLoader.cs 프로젝트: qcyb/reko
        private Header LoadHeader(LeImageReader rdr)
        {
            var header = new Header
            {
                HdrSize      = rdr.ReadLeUInt16(),
                RvaTaa       = rdr.ReadLeUInt16(),
                RvaSymbols   = rdr.ReadLeUInt16(),
                RvaIdent     = rdr.ReadLeUInt16(),
                RvaPatchData = rdr.ReadLeUInt16(),
                Spare0A      = rdr.ReadLeUInt16(),
                IdMajor      = rdr.ReadLeUInt16(),
                IdMinor      = rdr.ReadLeUInt16(),

                HeaderBlocks = rdr.ReadByte(),
                ImageType    = rdr.ReadByte(),
                Spare12      = rdr.ReadLeUInt16(),

                RequestedPrivilegeMask = rdr.ReadLeUInt64(),
                IoChannels             = rdr.ReadLeUInt16(),
                IoSegPages             = rdr.ReadLeUInt16(),
                ImageFlags             = rdr.ReadLeUInt32(),
                GlobalSectionID        = rdr.ReadLeUInt32(),
                SystemVersionNumber    = rdr.ReadLeUInt32(),
            };

            return(header);
        }