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); }
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); } }