1. 程式人生 > >Android Adb 原始碼分析

Android Adb 原始碼分析

扭起屁股得意洋洋

最近,我負責的專案因為臨近量產,把之前的userdebug版本關閉,轉成了user版本,增加selinux的許可權,大家都洋溢在專案準備量產的興奮和喜悅之中不能自拔

誰知,好景不長,user版本釋出之後,各種bug接踵而來,但是因為user版本許可權的原因,我們之前保留在/data/logs/下面的日誌不能pull出來,定位問題非常困難

 

不得不想到的解決方案

第一個辦法:我們想到的第一個辦法就是更改data目錄的許可權,改成system使用者,但是因為data下面的logs目錄的檔案是root許可權,獲取日誌是需要root許可權的,日誌還是不能pullg出來。

第二個辦法:我想到的第二個辦法就是給我們的adb命令增加一個後門,正常我們是adb root獲取root許可權,我修改成adb aaa.bbb.ccc.root 這樣不容易被別人竊取我們的後門,也不至於影響到我們的開發。

梳理Android ADB知識點

所以就加強了adb 的相關知識

google的adb 程式碼位置在(system/core/adb)目錄下面

我上傳了一份在github上面,連結如下

Android ADB原始碼​github.com

 

ADB是Android系統提供的除錯工具,整個ADB工具由三部分組成:adb client、adb service、adb daemon。

1、ADB client

提供HOST端執行的命令

2、ADB service

HOST端上的一個後臺程序

3、ADB daemom

DEVICE端(真實的機器或者模擬器)的守護程序

這三部分都是從(system/core/adb)裡面編譯出來的,我們很多時候去網上下載adb.exe來用,實際上我們的SDK程式碼下面就有adb,而且程式碼是可以修改的。

ADB程式碼位於/system/core/adb目錄下,通過檢視Android.mk,可以知道,該目錄下的程式碼生成了兩個MODULE,分別是adbadbdadb client和adb service都是由adb這個可執行檔案實現

, adb daemon由adbd實現。adb和adbd的一些原始碼檔案是用同一個的,編譯時通過LOCAL_CFLAGS的引數ADB_HOST來區分,這種你中有我我中有你的關係,對於初次接觸的朋友們,多少增加了些困擾。理清了ADB幾部分的關係,以及原始碼的結構,對ADB的認識已經有一個飛越了。

 

使用方案2來解決問題

程式碼修改如下

diff --git a/adb/commandline.cpp b/adb/commandline.cpp
old mode 100644
new mode 100755
index 51d828a..32b2c09
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -83,6 +83,7 @@ static void help() {
     fprintf(stderr, "%s\n", adb_version().c_str());
     // clang-format off
     fprintf(stderr,
+    	"ADB use for weiqifa nan Product\n"
         " -a                            - directs adb to listen on all interfaces for a connection\n"
         " -d                            - directs command to the only connected USB device\n"
         "                                 returns an error if more than one USB device is present.\n"
@@ -1083,6 +1084,7 @@ static bool adb_root(const char* command) {
     std::string error;
     ScopedFd fd;
 
+	fprintf(stderr, "weiqifa adb root \n");
     fd.Reset(adb_connect(android::base::StringPrintf("%s:", command), &error));
     if (!fd.valid()) {
         fprintf(stderr, "adb: unable to connect for %s: %s\n", command, error.c_str());
@@ -1625,12 +1627,12 @@ int adb_commandline(int argc, const char **argv) {
         } else if (argc == 2 && !strcmp(argv[1], "-l")) {
             listopt = argv[1];
         } else {
-            fprintf(stderr, "Usage: adb devices [-l]\n");
+            fprintf(stderr, "weiqifa Usage: adb devices [-l]\n");
             return 1;
         }
 
         std::string query = android::base::StringPrintf("host:%s%s", argv[0], listopt);
-        printf("List of devices attached\n");
+        printf("weiqifa List of devices attached\n");
         return adb_query_command(query);
     }
     else if (!strcmp(argv[0], "connect")) {
@@ -1732,7 +1734,7 @@ int adb_commandline(int argc, const char **argv) {
             command = android::base::StringPrintf("%s:", argv[0]);
         }
         return adb_connect_command(command);
-    } else if (!strcmp(argv[0], "root") || !strcmp(argv[0], "unroot")) {
+    } else if (!strcmp(argv[0], "weiqifa.nan.root") || !strcmp(argv[0], "unroot")) {
         return adb_root(argv[0]) ? 0 : 1;
     } else if (!strcmp(argv[0], "bugreport")) {
         Bugreport bugreport;
diff --git a/adb/services.cpp b/adb/services.cpp
old mode 100644
new mode 100755
index 3b212e9..5a82246
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -69,7 +69,7 @@ static void service_bootstrap_func(void* x) {
 
 void restart_root_service(int fd, void *cookie) {
     if (getuid() == 0) {
-        WriteFdExactly(fd, "adbd is already running as root\n");
+        WriteFdExactly(fd, "weiqifa.nan adbd is already running as root\n");
         adb_close(fd);
     } else {
         char value[PROPERTY_VALUE_MAX];
@@ -81,7 +81,7 @@ void restart_root_service(int fd, void *cookie) {
         }
 
         property_set("service.adb.root", "1");
-        WriteFdExactly(fd, "restarting adbd as root\n");
+        WriteFdExactly(fd, "weiqifa.nan restarting adbd as root\n");
         adb_close(fd);
     }
 }
@@ -327,7 +327,8 @@ int service_to_fd(const char* name, const atransport* transport) {
         void* arg = strdup(name + 7);
         if (arg == NULL) return -1;
         ret = create_service_thread(reboot_service, arg);
-    } else if(!strncmp(name, "root:", 5)) {
+    } else if(!strncmp(name, "weiqifa.nan.root:", 17)) {
+    	fprintf(stderr, "services adb root");
         ret = create_service_thread(restart_root_service, NULL);
     } else if(!strncmp(name, "unroot:", 7)) {
         ret = create_service_thread(restart_unroot_service, NULL);
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 63b7df6..1cb0b5e 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -418,11 +418,11 @@ asocket* create_local_service_socket(const char* name, const atransport* transpo
 
 #if !ADB_HOST
     char debug[PROPERTY_VALUE_MAX];
-    if (!strncmp(name, "root:", 5)) {
+    if (!strncmp(name, "weiqifa.nan.root:", 17)) {
         property_get("ro.debuggable", debug, "");
     }
 
-    if ((!strncmp(name, "root:", 5) && getuid() != 0 && strcmp(debug, "1") == 0) ||
+    if ((!strncmp(name, "weiqifa.nan.root:", 17) && getuid() != 0 && strcmp(debug, "1") == 0) ||
         (!strncmp(name, "unroot:", 7) && getuid() == 0) ||
         !strncmp(name, "usb:", 4) ||
         !strncmp(name, "tcpip:", 6)) {

 

編譯

Android sdk編譯請看連結

嵌入式Linux:Android7.1 howto_build_SDK​zhuanlan.zhihu.com

 

1、一個是編譯生成adb.exe,這個拷貝到windows下面使用

Android 7.1使用 編譯指令使用" make host_cross_adb -j40 "

Android 7.0 之前使用 make USE_MINGW=y adb

但是之前要先

source build/envsetup.sh

lunch

建立Android 編譯環境

 

2、編譯adbd 服務,這個是燒錄到機器裡面去,直接編譯整個韌體就好了

source build/envsetup.sh; lunch rk3399_mid-userdebug; make -j128

adbd 在init.rc裡面初始化,具體程式碼在devices/rockchip/下面找

 

# for Internet adb 
on property:persist.internet.adb.enable=1
    setprop service.adb.tcp.port 5555
    restart adbd

# for Internet adb 
on property:persist.internet.adb.enable=0
    setprop service.adb.tcp.port 0
    restart adbd

# for telephony function
on property:ro.boot.noril=true
    setprop ro.radio.noril true
    stop ril-daemon

 

這一章先大概說下程式碼,只有寫下root的原理~~

 

如果覺得不錯,幫忙關注微信公眾號,嵌入式Linux