2015年3月10日火曜日

IngressのGlyph Hackを自動化する ~Input Subsystem~


お蔵入り寸前だったGlyph Hackの自動化ですが、Translaterメダルやら、ハッキングボーナスやスピードボーナスの上限解放やら、なんとかモチベーションを持ち直すニュースがあったので、再チャレンジします。

ということで、今回はInput Subsystemとやらを調べてみました。

まず、Input Subsystemで利用するイベントデバイスファイルは/dev/input/にあるとのことなので確認してみます。

自分の環境では、/dev/input/配下に以下が格納されていました。

event0
event1
event2
event3
event4
mice

それぞれが何らかのデバイスに対応しているそうですが、これだけでは分からないので、BusyBoxをインストールして、hexdumpコマンドで覗いてみます。

# /system/xbin/hexdump /dev/input/event0
0000000 1d21 0003 4cbf 0004 0003 0039 69d4 0000
0000010 1d21 0003 4cbf 0004 0003 0035 023c 0000
0000020 1d21 0003 4cbf 0004 0003 0036 028a 0000
0000030 1d21 0003 4cbf 0004 0003 003a 004a 0000
0000040 1d21 0003 4cbf 0004 0003 0030 0006 0000
0000050 1d21 0003 4cbf 0004 0000 0000 0000 0000
0000060 1d21 0003 8987 0004 0003 003a 0018 0000
0000070 1d21 0003 8987 0004 0003 0030 0002 0000
0000080 1d21 0003 8987 0004 0000 0000 0000 0000
0000090 1d21 0003 c0fa 0004 0003 0039 ffff ffff
00000a0 1d21 0003 c0fa 0004 0000 0000 0000 0000

なにやら出力されてきました。
しかし、何かやろうとすると、毎回バイナリを解読させられる運命にあるようですね。

ざっと画面をタッチしたりしながら眺めていると、はじめの2byteはイベントが発生した時間のようです。

次の2byteは入力のタイプEV_ABSを表す3かと思いましたが、なんだか違いそうです。

次の2byteもx軸かy軸かを表すもの、、、じゃなさそうです。
座標は後ろから2番目の2byteのようですね。
うーん。。分からない。

ということでもうちょっと良い方法がないか調べたところありました。
これはBusyBoxのインストールも不要です。

# getevent /dev/input/event0
0003 0039 00006be2
0003 0035 0000029d
0003 0036 000002aa
0003 003a 0000004d
0003 0030 00000008
0000 0000 00000000
0003 003a 00000037
0003 0030 00000006
0000 0000 00000000
0003 0039 ffffffff
0000 0000 00000000

type、code、valueってことなんだろうけど、なんか分かりそうで分からない。

さらに色々調べたところ、geteventコマンドに素敵なオプションを発見。

# getevent -lt /dev/input/event0
[  320377.729707] EV_ABS       ABS_MT_TRACKING_ID   00009411
[  320377.729707] EV_ABS       ABS_MT_POSITION_X    00000296
[  320377.729707] EV_ABS       ABS_MT_POSITION_Y    00000348
[  320377.729707] EV_ABS       ABS_MT_PRESSURE      00000048
[  320377.729707] EV_ABS       ABS_MT_TOUCH_MAJOR   00000007
[  320377.729707] EV_SYN       SYN_REPORT           00000000
[  320377.766317] EV_ABS       ABS_MT_TRACKING_ID   ffffffff
[  320377.766317] EV_SYN       SYN_REPORT           00000000

これなら読み解こうという気になります。

では、まずは登場人物を整理します。

type
EV_ABS 3EV_SYN 0

code
SYN_REPORT 0
ABS_MT_TRACKING_ID 57
ABS_MT_POSITION_X 53
ABS_MT_POSITION_Y 54
ABS_MT_PRESSURE 58
ABS_MT_TOUCH_MAJOR 48

value
ABS_MT_TRACKING_IDのIDや、ABS_MT_POSITION_Xのx座標など。

次に、タッチイベントを発生させるための流れを整理します。

まずEV_ABSABS_MT_TRACKING_IDで一連のイベントのIDを設定します。
Android側の動きをgeteventで見ていると、1ずつインクリメントされ連番になっているようです。
ただ、適当な値でも特に文句は言われませんので、乱数とかでも大丈夫なのかも??

次に座標を送信します。
ABS_MT_POSITION_Xと、ABS_MT_POSITION_Yでイベントが発生した座標を設定します。
続いてABS_MT_PRESSUREで圧力、ABS_MT_TOUCH_MAJORで断面積ということで、いまいち良く分かりませんが設定します。
最後に、EV_SYNSYN_REPORTを送信します。
ここまでが座標送信のワンセットです。

座標、ABS_MT_PRESSUREABS_MT_TOUCH_MAJORSYN_REPORTのセットを連続で複数送信するとスワイプイベントになります。

イベント終了時にはABS_MT_TRACKING_IDにFFFFFFFFを設定して送信し、EV_SYNSYN_REPORTを送信して完了です。


ではやってみましょう。

# sendevent /dev/input/event0 3 57 3800
# sendevent /dev/input/event0 3 53 1222
# sendevent /dev/input/event0 3 54 1237
# sendevent /dev/input/event0 3 58 72
# sendevent /dev/input/event0 3 48 7
# sendevent /dev/input/event0 0 0 0
# sendevent /dev/input/event0 3 57 -1
# sendevent /dev/input/event0 0 0 0

ちゃんと動きました。

さらに複数座標を送信して、動きをつけて軌跡を描けるか試しました。

成功!ちなみに描いたのは「SUCCESS」です。
なぜこんなに滑らかな曲線になるのかは謎です。


しかし、rootとってshellからなら何でも出来てしまうってのは結構恐ろしい事だなぁ、と。
Google先生が練り上げたAndroidのセキュリティの壁も、いとも簡単に超えてしまうわけですね。

まぁ当然なんですが。

とりあえずroot系アプリ入れるときは、ちょっと注意したほうがいいなと思いましたとさ。

Read More...