2012年02月02日
Androidのadbのメモ(8) Android以外でadbを使う実験
ARM Ubuntu 11.10でadbdを動かして使用することができたので、そのメモ。
adbdはスタティックリンクされているので、そのままARM Ubuntu 11.10にコピーして動かしてみます。無理やりですが、とりあえず実験として。
カーネルはAndroidパッチがあたったものを使用します。
ARM Ubuntuとx86_64 UbuntuはUSBケーブルで接続しています。
以下、arm# はARM Ubuntuのプロンプト、host$はx86_64 Ubuntuのプロンプトです。
arm# ./adbd
host$ adb devices List of devices attached
残念ながら反応無し。しかしSEGVなどで落ちたわけではないようです。
straceで見てみます。
arm# strace ./adbd execve("./adbd", ["./adbd"], [/* 19 vars */]) = 0 gettid() = 2897 set_tls(0x32c44, 0x32c08, 0x32d40, 0x40, 0x32c08) = 0 clock_gettime(CLOCK_MONOTONIC, {736, 206473395}) = 0 open("/dev/urandom", O_RDONLY|O_LARGEFILE) = 3 read(3, "\310\232\324I", 4) = 4 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40000000 mprotect(0x40000000, 4096, PROT_READ) = 0 mprotect(0x40000000, 4096, PROT_READ|PROT_WRITE) = 0 mprotect(0x40000000, 4096, PROT_READ) = 0 mprotect(0x40000000, 4096, PROT_READ|PROT_WRITE) = 0 mprotect(0x40000000, 4096, PROT_READ) = 0 sigaction(SIGPIPE, {SIG_IGN, , {SIG_DFL, , 0x4007cd50) = 0 socketpair(PF_FILE, SOCK_STREAM, 0, [3, 4]) = 0 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 fcntl64(4, F_SETFD, FD_CLOEXEC) = 0 fcntl64(4, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 brk(0) = 0x35000 brk(0x35000) = 0x35000 brk(0x36000) = 0x36000 prctl(PR_SET_KEEPCAPS, 1) = 0 setgroups32(10, [1011, 1007, 1004, 3003, 1003, 3002, 3001, 1015, 1009, 3006]) = 0 setgid32(2000) = 0 open("/acct/uid/2000/tasks", O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 ENOENT (No such file or directory) mkdir("/acct/uid/2000", 0775) = -1 ENOENT (No such file or directory) setuid32(2000) = 0 capset(0x19980330, 0, {CAP_SYS_BOOT, CAP_SYS_BOOT, 0}) = 0 access("/dev/android_adb", F_OK) = 0 open("/dev/android_adb_enable", O_RDWR|O_LARGEFILE) = -1 EACCES (Permission denied) mmap2(0x10000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x10000000 mprotect(0x10000000, 4096, PROT_NONE) = 0 clone(child_stack=0x100fff00, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_DETACHED) = 2898 socket(PF_FILE, SOCK_STREAM, 0) = 5 bind(5, {sa_family=AF_FILE, path=@"jdwp-control"}, 15) = 0 listen(5, 4) = 0 fcntl64(5, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 fcntl64(5, F_SETFD, FD_CLOEXEC) = 0 socketpair(PF_FILE, SOCK_STREAM, 0, [6, 7]) = 0 fcntl64(6, F_SETFD, FD_CLOEXEC) = 0 fcntl64(7, F_SETFD, FD_CLOEXEC) = 0 fcntl64(7, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 select(8, [4 5 7], , , NULL
/dev/android_adb_enableのopenがPermission deniedになっています。
Androidのadbのメモ(2) adbdの観察のときのログと比較しても、このファイルがopenできないのはおかしいです。
arm# ls -l /dev/android_adb* crw------- 1 root root 10, 62 2000-01-02 15:59 /dev/android_adb crw------- 1 root root 10, 61 2000-01-02 15:59 /dev/android_adb_enable arm# chmod 666 /dev/android_adb* arm# ls -l /dev/android_adb* crw-rw-rw- 1 root root 10, 62 2000-01-02 15:59 /dev/android_adb crw-rw-rw- 1 root root 10, 61 2000-01-02 15:59 /dev/android_adb_enable arm#
root権限でadbdを動かしているはずですが、とりあえずchmodで変えてみました。
再度トライ。
arm# strace ./adbd execve("./adbd", ["./adbd"], [/* 19 vars */]) = 0 gettid() = 2938 set_tls(0x32c44, 0x32c08, 0x32d40, 0x40, 0x32c08) = 0 clock_gettime(CLOCK_MONOTONIC, {1070, 935558586}) = 0 open("/dev/urandom", O_RDONLY|O_LARGEFILE) = 3 read(3, "E\250\265a", 4) = 4 close(3) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40000000 mprotect(0x40000000, 4096, PROT_READ) = 0 mprotect(0x40000000, 4096, PROT_READ|PROT_WRITE) = 0 mprotect(0x40000000, 4096, PROT_READ) = 0 mprotect(0x40000000, 4096, PROT_READ|PROT_WRITE) = 0 mprotect(0x40000000, 4096, PROT_READ) = 0 sigaction(SIGPIPE, {SIG_IGN, , {SIG_DFL, , 0x4007cd50) = 0 socketpair(PF_FILE, SOCK_STREAM, 0, [3, 4]) = 0 fcntl64(3, F_SETFD, FD_CLOEXEC) = 0 fcntl64(4, F_SETFD, FD_CLOEXEC) = 0 fcntl64(4, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 brk(0) = 0x35000 brk(0x35000) = 0x35000 brk(0x36000) = 0x36000 prctl(PR_SET_KEEPCAPS, 1) = 0 setgroups32(10, [1011, 1007, 1004, 3003, 1003, 3002, 3001, 1015, 1009, 3006]) = 0 setgid32(2000) = 0 open("/acct/uid/2000/tasks", O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = -1 ENOENT (No such file or directory) mkdir("/acct/uid/2000", 0775) = -1 ENOENT (No such file or directory) setuid32(2000) = 0 capset(0x19980330, 0, {CAP_SYS_BOOT, CAP_SYS_BOOT, 0}) = 0 access("/dev/android_adb", F_OK) = 0 open("/dev/android_adb_enable", O_RDWR|O_LARGEFILE) = 5 fcntl64(5, F_SETFD, FD_CLOEXEC) = 0 mmap2(0x10000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x10000000 mprotect(0x10000000, 4096, PROT_NONE) = 0 clone(child_stack=0x100fff00, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_DETACHED) = 2939 socket(PF_FILE, SOCK_STREAM, 0) = 7 bind(7, {sa_family=AF_FILE, path=@"jdwp-control"}, 15) = 0 listen(7, 4) = 0 fcntl64(7, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 fcntl64(7, F_SETFD, FD_CLOEXEC) = 0 socketpair(PF_FILE, SOCK_STREAM, 0, [8, 9]) = 0 fcntl64(8, F_SETFD, FD_CLOEXEC) = 0 fcntl64(9, F_SETFD, FD_CLOEXEC) = 0 fcntl64(9, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 select(10, [4 7 9], , , NULL) = 1 (in [4]) read(4, "`T\3\0\1\0\0\0", 8) = 8 socketpair(PF_FILE, SOCK_STREAM, 0, [10, 11]) = 0 fcntl64(10, F_SETFD, FD_CLOEXEC) = 0 fcntl64(11, F_SETFD, FD_CLOEXEC) = 0 fcntl64(10, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 mmap2(0x10000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x40001000 mprotect(0x40001000, 4096, PROT_NONE) = 0 clone(child_stack=0x40100f00, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_DETACHED) = 2940 mmap2(0x10000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x40101000 mprotect(0x40101000, 4096, PROT_NONE) = 0 clone(child_stack=0x40200f00, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_DETACHED) = 2941 select(11, [4 7 9 10], , , NULL) = 1 (in [10]) read(10, "\230U\3\0", 4) = 4 write(10, "\230U\3\0", 4) = 4 select(11, [4 7 9 10], , , NULL) = 1 (in [10]) read(10, "\230U\3\0", 4) = 4 write(10, "\230U\3\0", 4) = 4 select(11, [4 7 9 10], , , NULL) = 1 (in [4]) read(4, "\300e\3\0\1\0\0\0", 8) = 8 socketpair(PF_FILE, SOCK_STREAM, 0, [12, 13]) = 0 fcntl64(12, F_SETFD, FD_CLOEXEC) = 0 fcntl64(13, F_SETFD, FD_CLOEXEC) = 0 fcntl64(12, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 mmap2(0x10000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x40001000 mprotect(0x40001000, 4096, PROT_NONE) = 0 clone(child_stack=0x40100f00, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_DETACHED) = 2942 mmap2(0x10000000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x40101000 mprotect(0x40101000, 4096, PROT_NONE) = 0 clone(child_stack=0x40200f00, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_DETACHED) = 2943 select(13, [4 7 9 10 12], , , NULL) = 1 (in [4]) read(4, "`T\3\0\0\0\0\0", 8) = 8 close(10) = 0 close(11) = 0 select(13, [4 7 9 12], , , NULL) = 1 (in [12]) read(12, "\230U\3\0", 4) = 4 write(12, "\230U\3\0", 4) = 4 select(13, [4 7 9 12], , , NULL) = 1 (in [12]) read(12, "8f\3\0", 4) = 4 brk(0x39000) = 0x39000 write(12, "`v\3\0", 4) = 4 select(13, [4 7 9 12], , , NULL
さっきより先に進んだようです。
host$ adb devices List of devices attached 0123456789ABCDEF device
ホスト側から認識できるようになりました!
host$ adb shell - exec '/system/bin/sh' failed: No such file or directory (2) - host$
/system/bin/shが無い。ソースを修正して再コンパイルしてもいいのですが、とりあえずディレクトリを作って /bin/shをシンボリックリンクします。
arm$ sudo mkdir -p /system/bin arm$ sudo ln -s /bin/sh /system/bin/sh
これで再トライ。
host$ adb shell $ uname -a Linux arm-oneiric 2.6.35.7 #11 SMP PREEMPT Wed Jan 25 13:42:43 JST 2012 armv7l armv7l armv7l GNU/Linux $
うまくいきました!
straceのログをよく見てみると、setuidでルート権限を手放しています。system propertyの値が読めないのでsecureモードで動作していたわけです。また、/dev/android_adb* のデバイスファイルのpermissionもudevdのルールに無いために最小限のpermissionになっているのでしょう。
/tmpディレクトリに対してのadb push/pullでファイルが転送できることも確認できました。
USBでTCPをブリッジするというadbのもっとも重要な部分は動いているようです。
あとはAndroid固有のものに依存している部分を修正すればいけそうです。
とりあえずソースコードを全く修正せずにここまで動作確認できたのにはびっくりです。
関連するページ
Android Builders SummitでADBの話をしました
Androidのadbのメモ(1) adb serverの観察
Androidのadbのメモ(5) adb shell lsを実行したときのログ
Androidのemulator consoleに簡単にコマンドを送る方法
Androidのadbのメモ(6) 直接adb serverと通信するrubyスクリプト
Androidのadbのメモ(7) Androidデバイス側でadbを動かす
Androidのadbのメモ(8) Android以外でadbを使う実験
Androidのadbのメモ(9) Android端末同士をadbでつなぐ
Androidのadbのメモ(10) adbdの起動のトリガー
Androidのadbのメモ(11) adbdのsecureモード