私は「Android-disassembler」という逆アセンブラを開発しています。現在このELFファイルのすべての.textセクションをすべて逆アセンブルするには成功しました。

ところが、今はElfファイルのdynsymセクションとsymtabセクションの情報を利用して、シンボルの名前とアドレスを取得したいだと思います。

私はStack Overflowのいくつかの記事を見て、少し役立つ情報を見つけました。

これは、C言語で書かれていたので、

for (size_t header_index = 0; header_index < info->dlpi_phnum; header_index++)
            {

        /* Further processing is only needed if the dynamic section is reached */
                if (info->dlpi_phdr[header_index].p_type == PT_DYNAMIC)
            {

        /* Get a pointer to the first entry of the dynamic section.
         * It's address is the shared lib's address + the virtual address */
        dyn = (ElfW(Dyn)*)(info->dlpi_addr +  info->dlpi_phdr[header_index].p_vaddr);

        /* Iterate over all entries of the dynamic section until the
         * end of the symbol table is reached. This is indicated by
         * an entry with d_tag == DT_NULL.
         *
         * Only the following entries need to be processed to find the
         * symbol names:
         *  - DT_HASH   -> second word of the hash is the number of symbols
         *  - DT_STRTAB -> pointer to the beginning of a string table that
         *                 contains the symbol names
         *  - DT_SYMTAB -> pointer to the beginning of the symbols table
         */
            while(dyn->d_tag != DT_NULL)
                {
            if (dyn->d_tag == DT_HASH)
            {
                    /* Get a pointer to the hash */
                    hash = (ElfW(Word*))dyn->d_un.d_ptr;

        /* The 2nd word is the number of symbols */
                    sym_cnt = hash[1];

                }
            else if (dyn->d_tag == DT_STRTAB)
            {
                    /* Get the pointer to the string table */
                strtab = (char*)dyn->d_un.d_ptr;
        }
            else if (dyn->d_tag == DT_SYMTAB)
            {
        /* Get the pointer to the first entry of the symbol table */
        sym = (ElfW(Sym*))dyn->d_un.d_ptr;


        /* Iterate over the symbol table */
        for (ElfW(Word) sym_index = 0; sym_index < sym_cnt; sym_index++)
            {
        /* get the name of the i-th symbol.
         * This is located at the address of st_name
         * relative to the beginning of the string table. */
            sym_name = &strtab[sym[sym_index].st_name];

            symbol_names->push_back(string(sym_name));
        }
        }

        /* move pointer to the next entry */
        dyn++;
        }
        }
            }

        /* Returning something != 0 stops further iterations,
         * since only the first entry, which is the executable itself, is needed
         * 1 is returned after processing the first entry.
         *
         * If the symbols of all loaded dynamic libs shall be found,
         * the return value has to be changed to 0.
         */
        return 1;

        }

(私はしたいのは、Javaコード)私自身、Javaで翻訳してみました。それは:

    if (elf.dynamicTable != null)
        { 
            StringBuilder sb=new StringBuilder();
            Log.v(TAG, "size of dynamic table=" + elf.dynamicTable.length);
            long strtab=0L; //pointer to the string table
            long hash=0L;
            int sym_cnt=0;
            int i=0;
            for (DynamicEntry de=elf.dynamicTable[0];;++i)
            {
                if (i >= elf.dynamicTable.length)
                    i = 0;
                de = elf.dynamicTable[i];
                DynamicEntry.Tag tag=de.getTag();
                Log.v(TAG, tag.toString());
                if (tag == null)
                {
                    Log.v(TAG, "The tag is null");
                    break;
                }
                if (de.getTag().equals(DynamicEntry.Tag.NULL))  
                {
                    Log.v(TAG, "Tag is NULL tag");
                    break;
                }
                if (tag.equals(DynamicEntry.Tag.HASH))
                {
                    hash = de.getValue();
                    /* Get a pointer to the hash */
                    //          hash = (ElfW(Word*))dyn->d_un.d_ptr;
//
                    /* The 2nd word is the number of symbols */
                    //          sym_cnt = hash[1];
                    //int hashvalue=fileContents[(int)hash]
                    sym_cnt = (fileContents[(int)hash + 1] << 8 | fileContents[(int)hash]);
                    Log.v(TAG, "Hash=" + hash + "cnt=" + sym_cnt);
                }
                else if (tag.equals(DynamicEntry.Tag.STRTAB))
                {
                    strtab = de.getValue();
                    Log.i(TAG, "strtab=" + strtab);
                }
                else if (tag.equals(DynamicEntry.Tag.SYMTAB))
                {
                    if (sym_cnt == 0 || strtab == 0)
                    {
                        continue;
                    }
                    long sym=de.getValue();
                    Log.i(TAG, "sym=" + sym);
                    //      int sym_index=0;
                    for (int sym_index=0;sym_index < sym_cnt;sym_index++)
                    {
                   String sym_name=Elf.getZString(fileContents,(int)strtab + fileContents[(int)(sym + sym_index * 16)]); //get string that ends with NULL from byte array from the offset
                        sb.append(sym_name).append("\n");
                        Log.v(TAG, "sym_nmae=" + sym_name);
                    }
                    break;
                }
            }
            info = sb.toString();
            Log.i(TAG, "info=" + info);
        }

期待し、上記のコードを実行させた結果がちょっと変です。

__cxa_finalize�
__cxa_atexit�
_ZN7_JNIEnv14GetObjectClassEP8_jobject�
__aeabi_unwind_cpp_pr1�
_ZN7_JNIEnv10GetFieldIDEP7_jclassPKcS3_� � Z� � it�
_unwind_cpp_pr1� etFieldIDEP7_jclassPKcS3_� � � �
__cxa_finalize� sEP8_jobject� object� eabi_unwind_cpp_pr1� nd_cpp_pr1� p_pr1� N7_JNIEnv10GetFieldIDEP7_jclassPKcS3_� ldIDEP7_jclassPKcS3_�
�(� Z� � � lize� cxa_atexit� 4GetObjectClassEP8_jobject� r1�
IEnv10GetFieldIDEP7_jclassPKcS3_� tFieldIDEP7_jclassPKcS3_�
DEP7_jclassPKcS3_� lassPKcS3_� � � � � � � � u� � � exit�
nv14GetObjectClassEP8_jobject� lassEP8_jobject� � ind_cpp_pr1�
ZN7_JNIEnv10GetFieldIDEP7_jclassPKcS3_� 0GetFieldIDEP7_jclassPKcS3_�
EP7_jclassPKcS3_� sPKcS3_�

変だと思います。

どのようにすればelfファイル内の関数の名前とアドレスを(ファイルオフセット)得とHashMap <Long, String>に置くことができますか?

これを試してみたい方は、以下のファイルをダウンロードしてください(apk)

Githubリリース
テスト対象のファイル(hello-jni.so)

追記

自己回答しましたが、少しでもより良い回答にはお礼を授与します。私が使用される方法はDynsymセクションで有効ですが、###SymtabセクションはStringIndexOutOfBoundsExceptionで発生したり、ビットを切り捨てます。良い解決策があるかどうか確認してください。ありがとうございます。