Example #1
0
 //$TODO: move this to HunkFile
 public bool BuildUnit()
 {
     var force_unit = true;
     var in_hunk = false;
     string name = null;
     List<Hunk> segment = null;
     Unit unit = null;
     this.hunkFile.units = new List<Unit>();
     var unit_no = 0;
     int hunk_no = 0;
     foreach (var e in this.hunkFile.hunks)
     {
         var hunk_type = e.HunkType;
         // optional unit as first entry
         if (hunk_type == HunkType.HUNK_UNIT)
         {
             unit = new Unit
             {
                 name = e.Name,
                 unit_no = unit_no,
                 segments = new List<List<Hunk>>(),
                 unit = e,
             };
             ++unit_no;
             this.hunkFile.units.Add(unit);
             force_unit = false;
             hunk_no = 0;
         }
         else if (force_unit)
             throw new BadImageFormatException(string.Format("Expected name hunk in unit: {0} {1}/{1:X}.", e.HunkType, (int) hunk_type));
         else if (!in_hunk)
         {
             // begin a named hunk
             if (hunk_type == HunkType.HUNK_NAME)
             {
                 name = e.Name;
                 // main hunk block
             }
             else if (unit_valid_main_hunks.Contains(hunk_type))
             {
                 segment = new List<Hunk> {
                     e
                 };
                 unit.segments.Add(segment);
                 // give main block the NAME
                 if (name != null)
                 {
                     e.Name = name;
                     name = null;
                 }
                 e.hunk_no = hunk_no;
                 hunk_no += 1;
                 in_hunk = true;
                 // broken hunk: ignore multi ENDs
             }
             else if (hunk_type == HunkType.HUNK_END)
             {
             }
             else
                 throw new BadImageFormatException(string.Format("Expected main hunk in unit: {0} {1}/{1:X}.", e.HunkType, hunk_type));
         }
         else
         {
             // a hunk is finished
             if (hunk_type == HunkType.HUNK_END)
             {
                 in_hunk = false;
                 // contents of hunk
             }
             else if (HunkLoader.unit_valid_extra_hunks.Contains(hunk_type))
             {
                 segment.Add(e);
                 // unecpected hunk?!
             }
             else
                 throw new BadImageFormatException(string.Format("Unexpected hunk in unit: {0} {1}/{1:X}", e.HunkType, hunk_type));
         }
     }
     return true;
 }
Example #2
0
		public void hunktool_signature()
        {
            // # 48  UNIT  
            //#3   CODE  size 00000000  alloc size 00000028  file header @  'romhunks'
            //       48 E7 00 3A 26 6F 00 14 20 6F 00 18 43 EF 00 1C
            //       45 FA 00 12 2C 79 00 00 00 00 4E AE 00 00 4C DF
            //       5C 00 4E 75 16 C0 4E 75
            //	ext       ext
            //		00000000  _sprintf                          def
            //		00000016  _AbsExecBase                      absref32
            //		0000001C  _LVORawDoFmt                      relref16
            //	symbol    symbol
            //		00000000  _sprintf                          
            //		00000024  stuffChar  

            var unit = new Unit
            {
                segments = new List<List<Hunk>>
                {
                    new List<Hunk>
                    {
                        new Hunk
                        {
                            HunkType = HunkType.HUNK_CODE,
                            Data = MakeBytes(
                                "48 E7 00 3A 26 6F 00 14 20 6F 00 18 43 EF 00 1C" +
                                "45 FA 00 12 2C 79 00 00 00 00 4E AE 00 00 4C DF" +
                                "5C 00 4E 75 16 C0 4E 75"),
                        },
                        new ExtHunk
                        {
                            ext_def = new List<ExtObject>
                            {
                                new ExtObject { def = 0, type = ExtType.EXT_DEF, name = "_sprintf" }
                            },
                            ext_ref = new List<ExtObject>
                            {
                                new ExtObject {type = ExtType.EXT_ABSREF32, name= "_AbsExecBase", refs = new List<uint> { 0x16 } },
                                new ExtObject {type = ExtType.EXT_RELREF16, name= "_LVORawDoFmt", refs = new List<uint> { 0x1C } }
                            }
                        }
                    }
                }
            };

            var file = new HunkFile
            {
				type = FileType.TYPE_UNIT,
                units = new List<Unit> { unit }
            };
            
            var sw = new StringWriter();
            var segs = new SignatureGenerator(new Dictionary<string, ValueObject>());
            segs.Output = sw;
            segs.handle_hunk_file("foo.lib", file);
            var sGen = sw.ToString();
            var sExp =
"48E7003A266F0014206F001843EF001C45FA00122C79........4EAE....4CDF _sprintf" + nl;
            if (sExp != sGen)
                Debug.Print(sGen);
            Assert.AreEqual(sExp, sGen);
        }
Example #3
0
        public virtual void ParseIndex(Action<Hunk> h)
        {
            var hunk = new IndexHunk();
            h(hunk);
            var index_size = this.read_long();
            var total_size = index_size * 4;

            // First read string table
            var strtab_size = f.ReadBeInt16();
            var strtab = f.ReadBytes(strtab_size);
            total_size -= strtab_size + 2;

            // Read units
            var units = new List<Unit>();
            hunk.units = units;
            var unit_no = 0;
            while (total_size > 2)
            {
                // Read name of unit
                var name_offset = f.ReadBeInt16();
                total_size -= 2;
                if (name_offset == 0)
                    break;
                
                var unit = new Unit { unit_no = unit_no };
                units.Add(unit);
                ++unit_no;

                // Generate unit name
                unit.name = this.get_index_name(strtab, name_offset);

                // hunks in unit
                var hunk_begin = f.ReadBeInt16();
                var num_hunks = f.ReadBeInt16();
                total_size -= 4;
                unit.hunk_begin_offset = hunk_begin;

                // For all hunks in unit
                var ihunks = new List<IHunk>();
                unit.hunk_infos = ihunks;
                for (var a = 0; a < num_hunks; ++a)
                {
                    var ihunk = new IHunk();
                    ihunks.Add(ihunk);
                    // get hunk info
                    name_offset = f.ReadBeInt16();
                    var hunk_size = f.ReadBeInt16();
                    var hunk_type = f.ReadBeInt16();
                    total_size -= 6;
                    ihunk.name = this.get_index_name(strtab, name_offset);
                    ihunk.size = hunk_size;
                    ihunk.type = hunk_type & 16383;
                    ihunk.memf = this.SetMemoryFlags(hunk_type & 49152, 14);
                    // get references
                    var num_refs = f.ReadBeInt16();
                    total_size -= 2;
                    if (num_refs > 0)
                    {
                        var refs = new List<Reference>();
                        ihunk.refs = refs;
                        for (var b = 0; b < num_refs; ++b)
                        {
                            var @ref = new Reference();
                            name_offset = f.ReadBeInt16();
                            total_size -= 2;
                            var name = this.get_index_name(strtab, name_offset);
                            if (name == "")
                            {
                                // 16 bit refs point to the previous zero byte before the string entry...
                                name = this.get_index_name(strtab, name_offset + 1);
                                @ref.bits = 16;
                            }
                            else
                            {
                                @ref.bits = 32;
                            }
                            @ref.name = name;
                            refs.Add(@ref);
                            // get definitions
                        }
                    }
                    var num_defs = f.ReadBeInt16();
                    total_size -= 2;
                    if (num_defs > 0)
                    {
                        var defs = new List<Definition>();
                        ihunk.defs = defs;
                        for (var b = 0; b < num_defs; ++b)
                        {
                            name_offset = f.ReadBeInt16();
                            var def_value = f.ReadBeInt16();
                            var def_type_flags = f.ReadBeInt16();
                            var def_type = def_type_flags & 16383;
                            var def_flags = def_type_flags & 49152;
                            total_size -= 6;
                            var name = this.get_index_name(strtab, name_offset);
                            var d = new Definition
                            {
                                name = name,
                                value = def_value,
                                type = def_type
                            };
                            d.memf = this.SetMemoryFlags(def_flags, 14);
                            defs.Add(d);
                        }
                    }
                }
            }
            // Align hunk to long-word.
            if (total_size == 2)
            {
                f.ReadBeInt16();
            }
            else if (total_size != 0)
                throw new BadImageFormatException(string.Format("{0} has invalid padding.", hunk.HunkType));
        }