http://blog.csdn.net/a345017062/article/details/6254402
adbd源碼位於system/core/adb/目錄下,可執行文件位於/sbin/adbd。通過adb執行ps命令,結果如下:
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 296 212 c00b0124 0000d9ec S /init
... ...
shell 2183 1 3372 184 ffffffff 0000eca4 S /sbin/adbd
root 2204 1859 832 336 00000000 afe0c7dc R ps
看一下倒數第二行,adbd所在進程的父進程是root,本身的user是shell。對於一個發布狀態的產品,這個是最正常不過了。但現在開發中遇到這樣一個需求,產品已經處在發布狀態(編譯模式已經改成user)的情況下,因為BSP需要處理一些內核上的東西,需要在PC上執行adb shell后具有root權限。也就是這種效果:
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 296 212 c00b0124 0000d9ec S /init
... ...
root 1911 1 3376 184 ffffffff 0000eca4 S /sbin/adbd
root 2198 2197 828 332 00000000 afe0c7dc R ps
要達到這個效果,就是要在啟動adbd時,以root用戶啟動。那么,先看一下在Android中怎么啟動adbd。
可以看一下Android系統根目錄下的/init.rc的片段:
... ...
# adbd is controlled by the persist.service.adb.enable system property
service adbd /sbin/adbd
disabled
# adbd on at boot in emulator
on property:ro.kernel.qemu=1
start adbd
on property:persist.service.adb.enable=1
start adbd
on property:persist.service.adb.enable=0
stop adbd
... ...
這里定義了一個觸發器,只要persist.service.adb.enable值被置為1,就會啟動/sbin/adbd。
怎么樣設置persist.service.adb.enable的值呢?這里涉及到一個屬性服務/system/core/init/property_service.c。看下面的東西之前先看一下我之前翻譯過來的這篇StevGuo的文檔,他對屬性服務描述得很仔細,也很有條理。
http://blog.csdn.net/a345017062/archive/2010/12/17/6083026.aspx
今天搜資料的時候才發現網上N多人翻譯了這篇文章,有點兒暈暈的。。。
我們繼續。。。
通過閱讀上面的文檔,我們知道了屬性服務啟動時加載了四個文件,這四個文件里面都可以設置系統屬性,還可以通過APK設置系統屬性。但我把這些方式都,結果都一樣,adbd是啟動起來了,用戶都是shell,還是沒有root權限的。看來差異應該在編譯模式上,是改為user編譯模式后,系統改變了adbd啟動時的權限。在build目錄下搜索一下,發現了main.mk中有這樣的代碼片段
## user/userdebug ##
user_variant := $(filter userdebug user,$(TARGET_BUILD_VARIANT))
enable_target_debugging := true
ifneq (,$(user_variant))
# Target is secure in user builds.
ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1
tags_to_install := user
ifeq ($(user_variant),userdebug)
# Pick up some extra useful tools
tags_to_install += debug
else
# Disable debugging in plain user builds.
enable_target_debugging :=
endif
# TODO: Always set WITH_DEXPREOPT (for user builds) once it works on OSX.
# Also, remove the corresponding block in config/product_config.make.
ifeq ($(HOST_OS)-$(WITH_DEXPREOPT_buildbot),linux-true)
WITH_DEXPREOPT := true
endif
# Disallow mock locations by default for user builds
ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=0
else # !user_variant
# Turn on checkjni for non-user builds.
ADDITIONAL_BUILD_PROPERTIES += ro.kernel.android.checkjni=1
# Set device insecure for non-user builds.
ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=0
# Allow mock locations by default for non user builds
ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=1
endif # !user_variant
ifeq (true,$(strip $(enable_target_debugging)))
# Target is more debuggable and adbd is on by default
ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=1 persist.service.adb.enable=1
# Include the debugging/testing OTA keys in this build.
INCLUDE_TEST_OTA_KEYS := true
else # !enable_target_debugging
# Target is less debuggable and adbd is off by default
ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=0 persist.service.adb.enable=0
endif # !enable_target_debugging
這段代碼我大致解釋一下:
主要通過判斷當前的編譯模式來給幾個屬性賦予不同的值,然后把屬性存儲在ADDITIONAL_DEFAULT_PROPERTIES這個變量中,這個變量在后面是要寫到根目錄下的/default.prop中去,在系統啟動時被屬性服務加載的。也就是說我們在/default.prop中看到的幾個屬性的值是在這里設置的。
只看兩個屬性ro.secure,persist.service.adb.enable。當前是user模式的話,編譯系統會把ro.secure置為1,把persist.service.adb.enable置為0.也就是說,用user模式編譯出來的系統運行在安全模式下,adbd默認關閉。即使通過設置屬性的方式打開,adbd進程的用戶也是shell,不具有root權限。這樣,普通用戶或者開發者拿到一個機器后,通過PC運行adb shell時,是以shell用戶登錄機器的。
好了,現在把ro.secure置為0,再重新編譯,只要設置屬性persist.service.adb.enable的值為1,adbd進程就會以root用戶的身份啟動。