Ⅰ. 概要
Android 5.xからPIE以外の実行ファルが実行できなくなりました。
PIEのチェックは /system/bin/linker によって行われています。
セキュリティの強化の為に存在するチェックですが、邪魔な場合があるので回避方法についてのメモです。
また、制限されている場合は以下のように表示されます。
# ./android_server error: only position independent executables (PIE) are supported.
Ⅲ. バイナリ書き換えの場合、どこを書き換えるか
AndroidはOSSなので、PIE チェックの処理をソースコードから確認することが出来ます。
ソースコードを見ると、ELFファイルのe_type(オブジェクトファイルタイプ)がET_DYN(#define ET_DYN 3)かどうかの比較をしているので、この条件を満たさずに、if文を抜けるように書き換えれば良いことがわかります。
※linker のPIEチェック部分のソースコード
linker/linker.cpp
Ⅳ. やり方(バイナリ書き換え)
1. linkerのバイナリをPCにコピーする
adb pull /system/bin/linker
2. IDAでlinkerを読み込む
3. Shift + F12でstring windowを開く
4. 「pie」で検索する
5. 「error: only position...」の文字列を参照している所に移動する
※画像の場合は __dl__linker_init+3D6 です
6. 「error: only position...」の文字列を出力する直前の分岐を探す
※画像の場合は 0000387C です。
7. 命令を書き換える
今回は BEQ を B に変更して強制的にジャンプするように変更するので、
0000387C を 0x07 0xD0 から 0x07 0xE0 に変更する
※書き換えは メニューの Edit → Patch program → Change byte から行えます
8. 書き換えた内容をファイルに出力する
9. Androidに書き換えた linker をコピーする
adb push linker /sdcard/
11. 動作チェック
# ./android_server IDA Android 32-bit remote debug server(ST) v1.17. Hex-Rays (c) 2004-2014 Listening on port #23946...
以上です。
Ⅴ. トラブルシューティング
Q. linker の書き換えには成功したが、permission denied と出る
A. setenforce 0 した後に getenforce して確認する