예제 #1
0
        Segment[] LoadSegmentTable()
        {
            var objectTableEntries     = new ObjectTableEntry[hdr.obj_no];
            var objectPageTableEntries = new ObjectPageTableEntry[hdr.module_pages_no];

            var rdr = new LeImageReader(RawImage, hdr.obj_table_off + lfaNew);
            var objTblEntryReader = new StructureReader <ObjectTableEntry>(rdr);

            for (int i = 0; i < hdr.obj_no; i++)
            {
                objectTableEntries[i] = objTblEntryReader.Read();
            }

            rdr = new LeImageReader(RawImage, hdr.obj_page_table_off + lfaNew);

            if (hdr.signature == SIGNATURE16)
            {
                var objPageTblEntry16Reader = new StructureReader <ObjectPageTableEntry16>(rdr);

                for (int i = 0; i < hdr.module_pages_no; i++)
                {
                    ObjectPageTableEntry16 page16 = objPageTblEntry16Reader.Read();

                    int pageNo = (page16.High << 8) + page16.Low;

                    objectPageTableEntries[i] = new ObjectPageTableEntry
                    {
                        DataSize       = (ushort)hdr.page_size,
                        Flags          = (PageTableAttributes)page16.Flags,
                        PageDataOffset = (uint)((pageNo - 1) * hdr.page_size)
                    };
                }
            }
            else
            {
                var objPageTblEntryReader = new StructureReader <ObjectPageTableEntry>(rdr);
                for (int i = 0; i < hdr.module_pages_no; i++)
                {
                    objectPageTableEntries[i] = objPageTblEntryReader.Read();
                }
            }

            int debugSections   = 0;
            int winrsrcSections = 0;

            if (hdr.debug_info_len > 0)
            {
                debugSections = 1;
            }
            if (hdr.win_res_len > 0)
            {
                winrsrcSections = 1;
            }

            Segment[] sections = new Segment[objectTableEntries.Length + debugSections + winrsrcSections];
            for (int i = 0; i < objectTableEntries.Length; i++)
            {
                sections[i] = new Segment {
                    Flags = objectTableEntries[i].ObjectFlags
                };
                if (objectTableEntries[i].ObjectFlags.HasFlag(ObjectFlags.Resource))
                {
                    sections[i].Name = ".rsrc";
                }
                else if (objectTableEntries[i].ObjectFlags.HasFlag(ObjectFlags.Executable))
                {
                    sections[i].Name = ".text";
                }
                else if (!objectTableEntries[i].ObjectFlags.HasFlag(ObjectFlags.Writable))
                {
                    sections[i].Name = ".rodata";
                }
                else if (new LeImageReader(objectTableEntries[i].Name).ReadCString(PrimitiveType.Char, Encoding.ASCII).ToString().ToLower() == "bss")
                {
                    sections[i].Name = ".bss";
                }
                else if (!string.IsNullOrWhiteSpace(new LeImageReader(objectTableEntries[i].Name).ReadCString(PrimitiveType.Char, Encoding.ASCII).ToString().Trim()))
                {
                    sections[i].Name = new LeImageReader(objectTableEntries[i].Name).ReadCString(PrimitiveType.Char, Encoding.ASCII).ToString().Trim();
                }
                else
                {
                    sections[i].Name = ".data";
                }

                if (objectTableEntries[i].PageTableEntries == 0 ||
                    objectTableEntries[i].PageTableIndex > objectPageTableEntries.Length)
                {
                    sections[i].DataLength = objectTableEntries[i].VirtualSize;
                    continue;
                }

                int shift = (int)(hdr.signature == SIGNATURE16 ? 0 : hdr.page_off_shift);

                if (objectPageTableEntries[objectTableEntries[i].PageTableIndex - 1]
                    .Flags.HasFlag(PageTableAttributes.IteratedDataPage))
                {
                    sections[i].DataOffset =
                        (objectPageTableEntries[objectTableEntries[i].PageTableIndex - 1].PageDataOffset << shift) +
                        hdr.obj_iter_pages_off;
                }
                else if (objectPageTableEntries[objectTableEntries[i].PageTableIndex - 1]
                         .Flags.HasFlag(PageTableAttributes.LegalPhysicalPage))
                {
                    sections[i].DataOffset =
                        (objectPageTableEntries[objectTableEntries[i].PageTableIndex - 1].PageDataOffset << shift) +
                        hdr.data_pages_off;
                }
                else
                {
                    sections[i].DataOffset = 0;
                }

                sections[i].DataLength = 0;
                for (int j = 0; j < objectTableEntries[i].PageTableEntries; j++)
                {
                    sections[i].DataLength += objectPageTableEntries[j + objectTableEntries[i].PageTableIndex - 1].DataSize;
                }

                if (sections[i].DataOffset + sections[i].DataLength > RawImage.Length)
                {
                    sections[i].DataLength = (uint)RawImage.Length - sections[i].DataOffset;
                }

                sections[i].BaseAddress = objectTableEntries[i].RelocationBaseAddress;
            }

            if (winrsrcSections > 0)
            {
                sections[sections.Length - debugSections - winrsrcSections] = new Segment
                {
                    Name       = ".rsrc",
                    DataLength = hdr.win_res_len,
                    DataOffset = hdr.win_res_off
                }
            }
            ;

            if (debugSections > 0)
            {
                sections[sections.Length - debugSections] = new Segment
                {
                    Name       = ".debug",
                    DataLength = hdr.debug_info_len,
                    DataOffset = hdr.debug_info_off
                }
            }
            ;

            return(sections);
        }
예제 #2
0
        private void FindObjectTable()
        {
            Objects = new List<ObjectTableEntry>();
            ObjectTableAddress = 0;
            ObjectCount = 0;

            EntranceTableAddress = 0;

            if (!HasZ64TablesHack)
            {
                int inc = 8;
                for (int i = (int)ActorTableAddress; i < CodeData.Length - (8 * 8); i += inc)
                {
                    ObjectCount = Endian.SwapUInt16(BitConverter.ToUInt16(CodeData, i - 2));
                    if (ObjectCount < 0x100 || ObjectCount > 0x300) continue;

                    ObjectTableEntry obj1 = new ObjectTableEntry(this, i, true);
                    ObjectTableEntry obj2 = new ObjectTableEntry(this, i + 8, true);
                    ObjectTableEntry obj3 = new ObjectTableEntry(this, i + 16, true);

                    if (obj1.IsEmpty == true && obj2.IsValid == true && obj3.IsValid == true && Objects.Count == 0)
                    {
                        ObjectTableAddress = i;
                        break;
                    }
                }

                if (ObjectTableAddress != 0 && ObjectCount != 0)
                {
                    int i, j = 0;
                    for (i = ObjectTableAddress; i < (ObjectTableAddress + (ObjectCount * 8)); i += 8)
                    {
                        Objects.Add(new ObjectTableEntry(this, i, true, (ushort)j));
                        j++;
                    }

                    if (!IsMajora)
                        EntranceTableAddress = i + (i % 16);
                }
            }
            else
            {
                ObjectTableAddress = Endian.SwapInt32(BitConverter.ToInt32(Data, Z64TablesAdrOffset + 8));
                ObjectCount = (ushort)Endian.SwapInt32(BitConverter.ToInt32(Data, Z64TablesAdrOffset + 12));
                for (int i = 0; i < ObjectCount; i++)
                {
                    Objects.Add(new ObjectTableEntry(this, ObjectTableAddress + i * 8, false, (ushort)i));
                }
            }

            ObjectNameACStrings = new System.Windows.Forms.AutoCompleteStringCollection();
            foreach (ObjectTableEntry obj in Objects)
            {
                ObjectNameACStrings.Add(obj.Name);
            }
        }