public void Read(bool read_references) { // Determine the typeinfo object ulong vt_vaddr = ehdr.ReadPointer(file_offset); ulong vt_offset = ehdr.VaddrToOffset(vt_vaddr); ulong ti_vaddr = ehdr.ReadPointer(vt_offset); Layout = ehdr.stab.lm.Layouts[ti_vaddr]; LayoutName = Layout.Name; foreach (Layout.Field f in Layout.Fields) { object o = ReadFieldData(f, file_offset, ehdr, read_references); Fields.Add(f.Name, o); } }
public static object ReadReference(ulong vaddr, Elf64Reader.ElfHeader ehdr) { // Try and read the vaddr as a reference long old_pos = ehdr.r.BaseStream.Position; try { ulong file_offset = ehdr.VaddrToOffset(vaddr); ulong vt = ehdr.ReadPointer(file_offset); string vt_name = ehdr.stab.GetSymbolName(vt); foreach (ObjectToName otn in obj_to_name) { if (otn.VTName == vt_name) { Reference ret = new Reference(); ret.Address = vaddr; ret.file_offset = file_offset; ret.Type = vt_name; //ulong ti_vaddr = ehdr.ReadPointer(ehdr.VaddrToOffset(vt)); MetadataObject r = ReadVaddr(vaddr, ehdr, false); ret.Name = ParseName(r, otn.NameExp); return(ret); } } return(vaddr); } catch (ParseException) { throw; } catch (Exception) { return(vaddr); } finally { ehdr.r.BaseStream.Seek(old_pos, System.IO.SeekOrigin.Begin); } }
private object ReadFieldData(CMExpLib.Layout.Field f, ulong file_offset, Elf64Reader.ElfHeader ehdr, bool read_references) { long old_pos = ehdr.r.BaseStream.Position; object ret = null; bool is_obj = false; ehdr.r.BaseStream.Seek((long)file_offset + (long)f.Offset, System.IO.SeekOrigin.Begin); if (f.ftype == CMExpLib.Layout.Field.FType.Value) { if (f.FieldType == null) { // It's an unknown field type, load it as a signed integer switch (f.Length) { case 1: ret = ehdr.r.ReadSByte(); break; case 2: ret = ehdr.r.ReadInt16(); break; case 4: ret = ehdr.r.ReadInt32(); is_obj = true; break; case 8: ret = ehdr.r.ReadInt64(); is_obj = true; break; default: ret = ehdr.r.ReadBytes(f.Length); break; } } else { if (f.FieldType == "I") { ret = ehdr.ReadPointer((ulong)ehdr.r.BaseStream.Position); is_obj = true; } else if (f.FieldType == "U") { ret = ehdr.ReadPointer((ulong)ehdr.r.BaseStream.Position); is_obj = true; } else if (f.FieldType == "I1") { ret = ehdr.r.ReadSByte(); } else if (f.FieldType == "I2") { ret = ehdr.r.ReadInt16(); } else if (f.FieldType == "I4") { ret = ehdr.r.ReadInt32(); } else if (f.FieldType == "I8") { ret = ehdr.r.ReadInt64(); } else if (f.FieldType == "U1") { ret = ehdr.r.ReadByte(); } else if (f.FieldType == "U2") { ret = ehdr.r.ReadUInt16(); } else if (f.FieldType == "U4") { ret = ehdr.r.ReadUInt32(); } else if (f.FieldType == "U8") { ret = ehdr.r.ReadUInt64(); } else if (f.FieldType == "Boolean") { if (ehdr.r.ReadByte() == 0) { ret = false; } ret = true; } else if (f.FieldType == "Char") { ret = (char)ehdr.r.ReadUInt16(); } else if (f.FieldType == "R4") { ret = ehdr.r.ReadSingle(); } else if (f.FieldType == "R8") { ret = ehdr.r.ReadDouble(); } else if (f.FieldType == "String") { ulong str_ptr = ehdr.ReadPointer((ulong)ehdr.r.BaseStream.Position); ulong str_offset = ehdr.VaddrToOffset(str_ptr); ehdr.r.BaseStream.Seek((long)str_offset + (long)ehdr.stab.ass.GetStringFieldOffset(libtysila.Assembler.StringFields.length), System.IO.SeekOrigin.Begin); int str_len = ehdr.r.ReadInt32(); ehdr.r.BaseStream.Seek((long)str_offset + (long)ehdr.stab.ass.GetStringFieldOffset(libtysila.Assembler.StringFields.data_offset), System.IO.SeekOrigin.Begin); byte[] str_data = ehdr.r.ReadBytes(str_len * 2); ret = Encoding.Unicode.GetString(str_data); } else { // It's an unknown field type, load it as a signed integer switch (f.Length) { case 1: ret = ehdr.r.ReadSByte(); break; case 2: ret = ehdr.r.ReadInt16(); break; case 4: ret = ehdr.r.ReadInt32(); is_obj = true; break; case 8: ret = ehdr.r.ReadInt64(); is_obj = true; break; default: ret = ehdr.r.ReadBytes(f.Length); break; } } } } else if (f.ftype == CMExpLib.Layout.Field.FType.NTArray) { ulong list_vaddr = ehdr.ReadPointer(); if (list_vaddr == 0) { return new object[] {} } ; ulong list_offset = ehdr.VaddrToOffset(list_vaddr); ehdr.r.BaseStream.Seek((long)list_offset, System.IO.SeekOrigin.Begin); ulong cur_item; List <object> items = new List <object>(); do { cur_item = ehdr.ReadPointer(); if (cur_item != 0) { if (read_references) { items.Add(ReadReference(cur_item, ehdr)); } else { items.Add(cur_item); } // The Interfaces list in TysosType is special in that each item is interspersed // with the pointer to the vtable for that interface if ((f.l.Name == "_ZX9TysosTypeTI") && (f.Name == "Interfaces")) { ehdr.ReadPointer(); } } } while (cur_item != 0); ret = items.ToArray(); } if (is_obj && read_references) { ret = ReadReference(Convert.ToUInt64(ret), ehdr); } ehdr.r.BaseStream.Seek(old_pos, System.IO.SeekOrigin.Begin); return(ret); }