예제 #1
0
        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);
        }
예제 #2
0
        /// <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;
                    }
                }
            }
        }
예제 #3
0
        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;
        }
예제 #4
0
        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);
        }