private void GenerateEditorPanel(ElfType type = ElfType.Main, int tabIndex = 0) { EditorPanel panel = new EditorPanel { Type = loadedDataType, DefaultType = loadedStructType, Objects = new List <Element <object> >(loadedBinary.Data[type]), DataOffsets = loadedBinary.DataOffsets, SymbolTable = loadedBinary.SymbolTable, }; panel.HyperlinkClick += (sender, e) => { tabControl.SelectedIndex = (int)e.type - 1; editors[(int)e.type - 1].FocusObject(e.index); }; if (loadedDataType == GameDataType.Maplink) { panel.Objects.Add(loadedBinary.Data[ElfType.MaplinkHeader][0]); } panel.OnUnsavedChanges += (sender, e) => hasUnsavedChanges = true; ((TabItem)tabControl.Items[tabIndex]).Content = panel; editors.Add(panel); }
/// <summary>ELFヘッダ情報</summary> public Elf32_Header(string ProgramFilePath) : this() { this.ProgramFilePath = ProgramFilePath; long fileSize = 0; using (BinaryReader br = new BinaryReader(File.Open(this.ProgramFilePath, FileMode.Open))) { int ptr = 0; e_ident = new char[16]; byte[] ehBytes = new byte[52]; fileSize = br.BaseStream.Length; br.Read(ehBytes, 0, ehBytes.Length); foreach (byte b in ehBytes.Take(16)) { e_ident[ptr++] = (char)b; } ei_class = (ElfIdClass)e_ident[4]; ei_data = (ElfIdData)e_ident[5]; e_type = (ElfType)BitConverter.ToUInt16(ehBytes, ptr); ptr += 2; e_machine = (ElfMachine)BitConverter.ToUInt16(ehBytes, ptr); ptr += 2; e_version = (ElfVersion)BitConverter.ToUInt32(ehBytes, ptr); ptr += 4; e_entry = BitConverter.ToUInt32(ehBytes, ptr); ptr += 4; e_phoff = BitConverter.ToUInt32(ehBytes, ptr); ptr += 4; e_shoff = BitConverter.ToUInt32(ehBytes, ptr); ptr += 4; e_flags = BitConverter.ToUInt32(ehBytes, ptr); ptr += 4; e_ehsize = BitConverter.ToUInt16(ehBytes, ptr); ptr += 2; e_phentsize = BitConverter.ToUInt16(ehBytes, ptr); ptr += 2; e_phnum = BitConverter.ToUInt16(ehBytes, ptr); ptr += 2; e_shentsize = BitConverter.ToUInt16(ehBytes, ptr); ptr += 2; e_shnum = BitConverter.ToUInt16(ehBytes, ptr); ptr += 2; e_shstrndx = BitConverter.ToUInt16(ehBytes, ptr); ptr += 2; ehBytes = null; // プログラムヘッダテーブル if (e_phoff != br.BaseStream.Position) { // 現在のファイル内の位置が e_phoff と違っている場合は、e_phoff までシークする br.BaseStream.Seek(e_phoff, SeekOrigin.Begin); } e_phdrtab = new Elf32_Phdr[e_phnum]; for (int i = 0; i < e_phnum; i++) { byte[] e_ph = new byte[e_phentsize]; br.Read(e_ph, 0, e_ph.Length); e_phdrtab[i] = new Elf32_Phdr(e_ph); } // セクションヘッダテーブル if (e_shoff != br.BaseStream.Position) { // 現在のファイル内の位置が e_shoff と違っている場合は、e_shoff までシークする br.BaseStream.Seek(e_shoff, SeekOrigin.Begin); } e_shdrtab = new Elf32_Shdr[e_shnum]; for (int i = 0; i < e_shnum; i++) { byte[] e_sh = new byte[e_shentsize]; br.Read(e_sh, 0, e_sh.Length); e_shdrtab[i] = new Elf32_Shdr(e_sh); e_sh = null; } char[] sh_strtab = null; // セクションヘッダ名文字列テーブルを検索 Encoding enc = Encoding.ASCII; foreach (Elf32_Shdr shdr in e_shdrtab) { if (shdr.sh_type == ShType.SHT_STRTAB) { sh_strtab = new char[shdr.sh_size]; if (shdr.sh_offset != br.BaseStream.Position) { // 現在のファイル内の位置が sh_offset と違っている場合は、sh_offset までシークする br.BaseStream.Seek(shdr.sh_offset, SeekOrigin.Begin); } br.Read(sh_strtab, 0, sh_strtab.Length); // 読み出したセクションヘッダ名文字列テーブルで自信のセクションヘッダ名をチェック if (new string(sh_strtab.Skip((int)shdr.sh_nameidx).TakeWhile(c => c != '\0').ToArray()).Equals(".shstrtab")) { break; } sh_strtab = null; } } // 各セクションテーブルにセクション名(string)を付与 if (sh_strtab != null) { for (int i = 0; i < e_shdrtab.Length; i++) { e_shdrtab[i].sh_name = new string(sh_strtab.Skip((int)e_shdrtab[i].sh_nameidx).TakeWhile(c => c != '\0').ToArray()); } } // シンボルテーブル foreach (Elf32_Shdr shdr in e_shdrtab) { if (shdr.sh_type == ShType.SHT_SYMTAB) { // シンボル名文字列テーブル char[] sym_strtab = null; foreach (Elf32_Shdr shdr_strtab in e_shdrtab) { if (shdr_strtab.sh_name.Equals(".strtab")) { sym_strtab = new char[shdr_strtab.sh_size]; br.BaseStream.Seek(shdr_strtab.sh_offset, SeekOrigin.Begin); br.Read(sym_strtab, 0, sym_strtab.Length); } } // シンボルを作成 List <Elf32_Sym> symtab = new List <Elf32_Sym>(); br.BaseStream.Seek(shdr.sh_offset, SeekOrigin.Begin); for (int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) { byte[] e_sym = new byte[shdr.sh_entsize]; br.Read(e_sym, 0, e_sym.Length); symtab.Add(new Elf32_Sym(e_sym, sym_strtab)); } sym_strtab = null; // 作成したシンボルのうち、セクションに紐付くものは紐付け List <Elf32_Sym> l = new List <Elf32_Sym>(); for (int i = 0; i < e_shdrtab.Length; i++) { for (int j = 0; j < symtab.Count(); j++) { if (symtab[j].st_shndx == i) { l.Add(symtab[j]); symtab.RemoveAt(j--); } } e_shdrtab[i].sh_symtab = l.ToArray(); l.Clear(); } e_symtab = symtab.ToArray(); symtab = null; } } } }
protected bool LoadElf( BinaryReader reader ) { NativeElfEhdr ehdr = new NativeElfEhdr( reader ); if( ehdr.Magic != NativeElfEhdr.ElfMagic ) { Debug.WriteLine( "ElfFile: elf magic number invalid" ); return false; } if( ehdr.Machine != ElfMachineMips ) { Debug.WriteLine( "ElfFile: machine version invalid" ); return false; } _programType = ( ElfType )ehdr.Type; _entryAddress = ehdr.Entry; // Easy test for relocation: if( _entryAddress < 0x08000000 ) _needsRelocation = true; reader.BaseStream.Seek( ehdr.Phoff, SeekOrigin.Begin ); List<NativeElfPhdr> phdrs = new List<NativeElfPhdr>(); for( int n = 0; n < ehdr.Phnum; n++ ) { NativeElfPhdr phdr = new NativeElfPhdr( reader ); phdrs.Add( phdr ); } for( int n = 0; n < ehdr.Shnum; n++ ) { reader.BaseStream.Seek( ehdr.Shoff + ( n * ehdr.Shentsize ), SeekOrigin.Begin ); NativeElfShdr shdr = new NativeElfShdr( reader ); ElfSection section = new ElfSection(); section.NameIndex = shdr.Name; section.ElfOffset = shdr.Offset; section.Flags = ( ElfSectionFlags )shdr.Flags; section.LinkInfo = shdr.Info; section.SectionType = ( ElfSectionType )shdr.Type; section.Address = shdr.Address; section.AddressAlignment = shdr.AddressAlignment; section.Length = shdr.Size; _sections.Add( section ); if( ( section.Flags & ElfSectionFlags.Alloc ) == ElfSectionFlags.Alloc ) _allocSections.Add( section ); if( ( ( _programType == ElfType.Executable ) && ( section.SectionType == ElfSectionType.Relocation ) ) || ( ( _programType == ElfType.Prx ) && ( section.SectionType == ElfSectionType.PrxReloc ) ) ) _relocSections.Add( section ); } uint nameBase = _sections[ ehdr.Shstrndx ].ElfOffset; foreach( ElfSection section in _sections ) { reader.BaseStream.Seek( nameBase + section.NameIndex, SeekOrigin.Begin ); section.Name = ReadString( reader ); if( ( ( section.SectionType == ElfSectionType.Relocation ) || ( section.SectionType == ElfSectionType.PrxReloc ) ) && ( ( _sections[ ( int )section.LinkInfo ].Flags & ElfSectionFlags.Alloc ) != 0 ) ) { section.Reference = _sections[ ( int )section.LinkInfo ]; //_needsRelocation = true; } if( ( section.Name != null ) && ( section.Name.Length > 0 ) ) _sectionLookup.Add( section.Name, section ); } // Not sure if this is important if( _sectionLookup.ContainsKey( ".init" ) == true ) _initAddress = _sectionLookup[ ".init" ].Address; else _initAddress = 0x0; if( _sectionLookup.ContainsKey( ".symtab" ) == true ) { ElfSection symtab = _sectionLookup[ ".symtab" ]; ElfSection strtab = _sectionLookup[ ".strtab" ]; for( int n = 0; n < symtab.Length / 16; n++ ) { reader.BaseStream.Seek( symtab.ElfOffset + ( 16 * n ), SeekOrigin.Begin ); NativeElfSym sym = new NativeElfSym( reader ); ElfSymbol symbol = new ElfSymbol(); symbol.Index = sym.SectionIndex; // May be ElfAbsoluteSymbol symbol.Size = sym.Size; symbol.Value = sym.Value; symbol.Binding = ( ElfSymbolBinding )( sym.Info >> 4 ); symbol.SymbolType = ( ElfSymbolType )( sym.Info & 0xF ); reader.BaseStream.Seek( strtab.ElfOffset + sym.Name, SeekOrigin.Begin ); symbol.Name = ReadString( reader ); _symbols.Add( symbol ); if( symbol.Index != ElfAbsoluteSymbol ) { ElfSection symbolParent = _sections[ ( int )symbol.Index ]; List<ElfSymbol> syms; if( _symbolLookup.ContainsKey( symbolParent ) == true ) syms = _symbolLookup[ symbolParent ]; else { syms = new List<ElfSymbol>(); _symbolLookup.Add( symbolParent, syms ); } syms.Add( symbol ); } } } //foreach( ElfSection section in _sections ) //{ // Debugger.Break(); // if( ( _programType == ElfType.Executable ) && // ( section.SectionType != ElfSectionType.Relocation ) ) // continue; // if( ( _programType == ElfType.Prx ) && // ( section.SectionType != ElfSectionType.PrxReloc ) ) // continue; // for( int n = 0; n < section.Length / 8; n++ ) // { // reader.BaseStream.Seek( section.ElfOffset + ( 8 * n ), SeekOrigin.Begin ); // NativeElfRel rel = new NativeElfRel( reader ); // ElfRelocation relocation = new ElfRelocation(); // relocation.Section = section; // relocation.Offset = rel.Offset; // relocation.BaseAddress = ( rel.Info >> 16 ) & 0xFF; // relocation.Symbol = rel.Info >> 8; // relocation.RelocationType = ( ElfRelocationType )( byte )( rel.Info & 0xFF ); // _relocations.Add( relocation ); // } //} return true; }
protected bool LoadElf(BinaryReader reader) { NativeElfEhdr ehdr = new NativeElfEhdr(reader); if (ehdr.Magic != NativeElfEhdr.ElfMagic) { Debug.WriteLine("ElfFile: elf magic number invalid"); return(false); } if (ehdr.Machine != ElfMachineMips) { Debug.WriteLine("ElfFile: machine version invalid"); return(false); } _programType = ( ElfType )ehdr.Type; _entryAddress = ehdr.Entry; // Easy test for relocation: if (_entryAddress < 0x08000000) { _needsRelocation = true; } reader.BaseStream.Seek(ehdr.Phoff, SeekOrigin.Begin); List <NativeElfPhdr> phdrs = new List <NativeElfPhdr>(); for (int n = 0; n < ehdr.Phnum; n++) { NativeElfPhdr phdr = new NativeElfPhdr(reader); phdrs.Add(phdr); } for (int n = 0; n < ehdr.Shnum; n++) { reader.BaseStream.Seek(ehdr.Shoff + (n * ehdr.Shentsize), SeekOrigin.Begin); NativeElfShdr shdr = new NativeElfShdr(reader); ElfSection section = new ElfSection(); section.NameIndex = shdr.Name; section.ElfOffset = shdr.Offset; section.Flags = ( ElfSectionFlags )shdr.Flags; section.LinkInfo = shdr.Info; section.SectionType = ( ElfSectionType )shdr.Type; section.Address = shdr.Address; section.AddressAlignment = shdr.AddressAlignment; section.Length = shdr.Size; _sections.Add(section); if ((section.Flags & ElfSectionFlags.Alloc) == ElfSectionFlags.Alloc) { _allocSections.Add(section); } if (((_programType == ElfType.Executable) && (section.SectionType == ElfSectionType.Relocation)) || ((_programType == ElfType.Prx) && (section.SectionType == ElfSectionType.PrxReloc))) { _relocSections.Add(section); } } uint nameBase = _sections[ehdr.Shstrndx].ElfOffset; foreach (ElfSection section in _sections) { reader.BaseStream.Seek(nameBase + section.NameIndex, SeekOrigin.Begin); section.Name = ReadString(reader); if (((section.SectionType == ElfSectionType.Relocation) || (section.SectionType == ElfSectionType.PrxReloc)) && ((_sections[( int )section.LinkInfo].Flags & ElfSectionFlags.Alloc) != 0)) { section.Reference = _sections[( int )section.LinkInfo]; //_needsRelocation = true; } if ((section.Name != null) && (section.Name.Length > 0)) { _sectionLookup.Add(section.Name, section); } } // Not sure if this is important if (_sectionLookup.ContainsKey(".init") == true) { _initAddress = _sectionLookup[".init"].Address; } else { _initAddress = 0x0; } if (_sectionLookup.ContainsKey(".symtab") == true) { ElfSection symtab = _sectionLookup[".symtab"]; ElfSection strtab = _sectionLookup[".strtab"]; for (int n = 0; n < symtab.Length / 16; n++) { reader.BaseStream.Seek(symtab.ElfOffset + (16 * n), SeekOrigin.Begin); NativeElfSym sym = new NativeElfSym(reader); ElfSymbol symbol = new ElfSymbol(); symbol.Index = sym.SectionIndex; // May be ElfAbsoluteSymbol symbol.Size = sym.Size; symbol.Value = sym.Value; symbol.Binding = ( ElfSymbolBinding )(sym.Info >> 4); symbol.SymbolType = ( ElfSymbolType )(sym.Info & 0xF); reader.BaseStream.Seek(strtab.ElfOffset + sym.Name, SeekOrigin.Begin); symbol.Name = ReadString(reader); _symbols.Add(symbol); if (symbol.Index != ElfAbsoluteSymbol) { ElfSection symbolParent = _sections[( int )symbol.Index]; List <ElfSymbol> syms; if (_symbolLookup.ContainsKey(symbolParent) == true) { syms = _symbolLookup[symbolParent]; } else { syms = new List <ElfSymbol>(); _symbolLookup.Add(symbolParent, syms); } syms.Add(symbol); } } } //foreach( ElfSection section in _sections ) //{ // Debugger.Break(); // if( ( _programType == ElfType.Executable ) && // ( section.SectionType != ElfSectionType.Relocation ) ) // continue; // if( ( _programType == ElfType.Prx ) && // ( section.SectionType != ElfSectionType.PrxReloc ) ) // continue; // for( int n = 0; n < section.Length / 8; n++ ) // { // reader.BaseStream.Seek( section.ElfOffset + ( 8 * n ), SeekOrigin.Begin ); // NativeElfRel rel = new NativeElfRel( reader ); // ElfRelocation relocation = new ElfRelocation(); // relocation.Section = section; // relocation.Offset = rel.Offset; // relocation.BaseAddress = ( rel.Info >> 16 ) & 0xFF; // relocation.Symbol = rel.Info >> 8; // relocation.RelocationType = ( ElfRelocationType )( byte )( rel.Info & 0xFF ); // _relocations.Add( relocation ); // } //} return(true); }