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モード