備忘録

備忘録

Android 5.x PIE チェックを回避する

Ⅰ. 概要

Android 5.xからPIE以外の実行ファルが実行できなくなりました。
PIEのチェックは /system/bin/linker によって行われています。
セキュリティの強化の為に存在するチェックですが、邪魔な場合があるので回避方法についてのメモです。
また、制限されている場合は以下のように表示されます。

# ./android_server
error: only position independent executables (PIE) are supported.

Ⅱ. 回避のアプローチ

1. PIE チェック処理を削除した linker を自分でコンパイルする

環境構築などが面倒(本記事で紹介しません)

2. バイナリを書き換える

簡単

Ⅲ. バイナリ書き換えの場合、どこを書き換えるか

AndroidOSSなので、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」で検索する

f:id:kagasu:20161209052431p:plain

5. 「error: only position...」の文字列を参照している所に移動する

※画像の場合は __dl__linker_init+3D6 です
f:id:kagasu:20161209053714p:plain

6. 「error: only position...」の文字列を出力する直前の分岐を探す

※画像の場合は 0000387C です。
f:id:kagasu:20161209054004p:plain

7. 命令を書き換える

今回は BEQ を B に変更して強制的にジャンプするように変更するので、
0000387C を 0x07 0xD0 から 0x07 0xE0 に変更する
※書き換えは メニューの Edit → Patch program → Change byte から行えます
f:id:kagasu:20161209054440p:plain

8. 書き換えた内容をファイルに出力する

f:id:kagasu:20161209054754p:plain

9. Androidに書き換えた linker をコピーする
adb push linker /sdcard/
10. /system/bin/linker にコピーする

Androidのファイルエクスプローラで /sdcard/linker を /system/bin/linkerにコピーする

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 して確認する