1

Android 以外の Linux マシンで apk から取得した x86 共有ライブラリを実行したいと考えています。

Android libc に対してリンクされているためlibc.so、Android ndk から取得しました。しばらくセグメンテーション違反をデバッグした後、これlibc.soは「チート」であり、多くのライブラリ関数の nop 実装しか含まれていないことがわかりました。

$ objdump -d libc.so | grep memalign -A 8
0000bf82 <memalign>:
    bf82:       55                      push   %ebp
    bf83:       89 e5                   mov    %esp,%ebp
    bf85:       5d                      pop    %ebp
    bf86:       c3                      ret    

現在、ndk にlibc.aはこれらの関数の実際の実装を含む a も含まれていますが、プロセスでこれらをロードして libc.so の nop 関数をオーバーライドするにはどうすればよいですか? Androidがこのトリックを実行している理由と、オーバーライドがそこでどのように機能するかについて、さらにいくつかのコンテキストにも興味があります。

4

1 に答える 1

3

ご覧のとおりlibc.so、NDK から取得したものにはスタブのみが含まれています。その目的は、独自の共有ライブラリまたは実行可能ファイルの作成中にリンカーに必要な情報を提供することです。これは、スタブ ライブラリが必要な理由のわかりやすい説明です。

libc.soしたがって、実際のバイナリが必要な場合は、2 つの選択肢があります。

  1. Android デバイスから直接取得します。

    $ adb pull /system/lib/libc.so <local_destination>
    
  2. デバイスの工場出荷時の ROM イメージをダウンロードして解凍し、ローカル ファイルシステムにマウントしてから、マウントされたパーティションsystem.imgから再度コピーします。/system/lib

しかし、適切なバイナリを取得したとしても、それをデスクトップ Linux で動作させるには、非常に骨の折れる作業です。少なくとも 2 つの理由があります。

  1. Android とデスクトップの Linux ELF には、異なるインタープリターが必要です。次の方法で確認できますreadelf

    $ readelf --all <android_binary> | grep interpreter
    [Requesting program interpreter: /system/bin/linker]
    $ readelf --all <linux_x64_binary> | grep interpreter
    [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
    

    (インタープリターは、バイナリの実際の読み込みを実行し、カーネルによって読み込まれる小さなプログラムです) 明らかに、Linux システムには何もなく/system/bin/linker、カーネルはそのようなバイナリの読み込みを拒否します。したがって、何らかの方法でセクションを適切にロードし、すべての依存関係を自分で解決する必要があります。

  2. Android カーネルはデスクトップ カーネルとはlibc.so異なり、依存する追加機能がいくつかあるため、何らかの方法で ELF をロードしてもカーネルと互換性がなく、いつか問題が発生することは間違いありません。

さらに言えば、同じハードウェア アーキテクチャを対象としている場合でも、デスクトップ GNU/Linux で Android バイナリを再利用することは事実上不可能です。

于 2016-08-26T08:38:51.553 に答える