Androidダイナミックライブラリ逆アセンブリ

3999 ワード

Androidを移植する過程で多くのCrashに遭遇し、特にAndroidを起動する過程で発生します.一般的に、これらの問題はコードを見ることで解決できます.もちろん、いくつかの問題もあります.手がかりを見つけるのは難しいです.logcatログにもクラッシュしたスタックしか印刷されません.これらの情報は問題を特定するのに役立ちません.Android移植中の逆アセンブリの使い方を一例に挙げて紹介します.
まず、私が出会ったlogcatのCrashに関する印刷情報を見てみましょう.
I/DEBUG   ( 1417): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   ( 1417): Build fingerprint: 'generic/sdk/generic/:Eclair/ECLAIR/eng.simon.20100607.133011:eng/test-keys'
I/DEBUG   ( 1417): pid: 1434, tid: 1460  >>> system_server <<<
I/DEBUG   ( 1417): signal 11 (SIGSEGV), fault addr 00000000
I/DEBUG   ( 1417):  zr 00000000  at 00000000  v0 00007265  v1 00193228
I/DEBUG   ( 1417):  gp 7ef6fd60  sp 30564e90  s8 2fa07858  ra 7ef53470
I/DEBUG   ( 1417):  hi 0000000f  lo 04444444 bva 00007265 epc 7ef534a4
I/DEBUG   ( 1417):          #00  pc 7ef534a4  /system/lib/libc.so
I/DEBUG   ( 1417):          #01  ra 7ef53470  /system/lib/libc.so
I/DEBUG   ( 1417): code around pc:
I/DEBUG   ( 1417): 7ef53494 afa7002c afa40030 1040000b afa50028
I/DEBUG   ( 1417): 7ef534a4 8c4a0000 8c440008 8c590004 8fa2001c
I/DEBUG   ( 1417): 7ef534b4 0320f809 ac4a0034 8fa9001c 8d220034
I/DEBUG   ( 1417):     30564e78  00000000
I/DEBUG   ( 1417):     30564e7c  7ef12af4  /system/lib/libc.so
I/DEBUG   ( 1417):     30564e80  7ef6fd60
I/DEBUG   ( 1417):     30564e84  00000000
I/DEBUG   ( 1417):     30564ea4  7b10a8e8  /system/lib/libsqlite.so
I/DEBUG   ( 1417):     30564ea8  7b10a8b4  /system/lib/libsqlite.so
I/DEBUG   ( 1417):     30564ed0  7ef5d990  /system/lib/libc.so
I/DEBUG   ( 1417):     30564ed4  2fa0786c
I/DEBUG   ( 1417):     30564ed8  30465000
I/DEBUG   ( 1417):     30564edc  00100000  [heap]
I/DEBUG   ( 1417):     30564ee0  7b10a8b4  /system/lib/libsqlite.so
W/SyncManager( 1434): Updating for new accounts...

このlog情報からlibc.soが崩壊し、スタックを再研究したところlibsqilteであった.soが引き起こしたのは,具体的にどの関数が崩壊したのか.この中には情報がありません.また、カーネルロードダイナミックライブラリはダイナミックロードである、libcを逆アセンブリしても.soとlibsqlite.so、シンボルテーブルもlogのアドレスに対応できません.カーネルがlibcをロードすることを知らない限り.soとlibsqlite.soのベースアドレスは,オフセットによって対応する関数を見つけることができる.幸いなことに、Androidは確かにシステムの大部分のライブラリのカーネルロードアドレスを規定しています.ファイルの場所はbuild/coreの下にあり、対応するプラットフォームのmapファイルがあります.例えば、Armプラットフォームファイル名はprelink-linux-armと呼ばれます.map、Mipsプラットフォームはprelink-linux-mipsと呼ばれています.map.私はMipsプラットフォームで問題があったので、prelink-linux-mipsを使うべきです.mapファイルを配置します.ファイルの内容は次のとおりです.
# 0x7F100000 - 0x7FFF0000 Thread 0 stack
# 0x7F000000 - 0x7F0FFFFF Linker
# 0x70000000 - 0x7EFFFFFF Prelinked System Libraries
# core system libraries
libdl.so                0x7EFF0000
libc.so                 0x7EF00000
libstdc++.so            0x7EEF0000
libcutils.so            0x7EE000000 readelf -s libc.so           

このmapファイルから、各libライブラリのロードベースアドレスをクエリーできます.例えばlibc.soはカーネルによって0 x 7 EF 00000,libsqliteにロードされる.soは0 x 7 B 100000にロードされる.Crashのロゴ情報にも対応している上で、このファイルがAndroidロード中に機能していることを説明することができます.
次はlibcを逆アセンブリする必要があります.soとlibsqlite.so.一般的なクロスコンパイラは逆アセンブリのツールを提供し、私のmipsプラットフォームはmips-linux-gnu-objdumpコマンドを提供して逆アセンブリを行います.
mips-linux-gnu-objdump -dS libc.so > libc.dump
mips-linux-gnu-objdump -dS libsqlite.so > libsqlite.dump

Armプラットフォームシステムに付属する逆コンパイルツールandroid/prebuild/linux-86/toolchail/arm-abil-4.4.0/binディレクトリのarm_eabi-objdump逆アセンブリ
arm-eabi-objdump -dS  libc.so >/work/libc.dump
arm-eabi-objdump -dS libsqlite.so >/worl/libsqlite.dump

Armプラットフォームには、問題を直接特定するコマンドのコードも用意されています.
arm-eabi-addr2line -e ./symbols/system/lib/libc.so 0x10000000//-e=>fileName</p   0x10000000              

問題ファイルの行数が直接位置決めされます.
これによりlibcとlibsqliteのシンボルテーブルが得られる.それからシンボルテーブルを通じて、Androidはダイナミックライブラリのベースアドレスをロードして、log情報はその関数に問題が発生することを位置決めすることができて、もしあなたが対応するプラットフォームのアセンブリ言語に熟知しているならばアセンブリコードを読んで問題を見つけることができます.この3つのファイル情報をどのように利用するかは具体的には説明しません.この3つの書類があれば、少し研究するとどのように分析するかがわかります.
一般的に、CrashはAndroidソースの問題ではなく、カーネルの一部のモジュールがコンパイルされていない可能性が高い.この例では,Mutexに関連するモジュールがカーネルにコンパイルされていないことによる問題である.