引言
公司某行招标软件版本是userdebug,需要关闭adb root功能,保留安装应用等功能
刚开始修改系统属性值ro.secure=1,没有效果,只得去撸源码,最后修改成功,特此记录源码分析过程
“解决方案”
这个需求,不是很简单嘛,就是一个系统属性值的问题
diff --git a/build/make/core/main.mk b/build/make/core/main.mk
index fedddff3df..c2e0a82f04 100755
--- a/build/make/core/main.mk
+++ b/build/make/core/main.mk
@@ -294,7 +294,7 @@ 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
+ ADDITIONAL_DEFAULT_PROPERTIES += ro.secure=1
# Allow mock locations by default for non user builds
ADDITIONAL_DEFAULT_PROPERTIES += ro.allow.mock.location=1
endif # !user_variant
编译,烧机,adb connect,adb root,adb remount
C:\Users\lc\Desktop
$ adb remount
remount succeeded
纳尼!!居然root成功了
分析源码过程
没办法,撸adb源码吧,源码见真章
/system/core/adb/daemon/main.cpp
int main(int argc, char** argv) {
240 while (true) {
241 static struct option opts[] = {
242 {"root_seclabel", required_argument, nullptr, 's'},
243 {"device_banner", required_argument, nullptr, 'b'},
244 {"version", no_argument, nullptr, 'v'},
245 };
246
247 int option_index = 0;
//解析命令行参数
248 int c = getopt_long(argc, argv, "", opts, &option_index);
249 if (c == -1) {
250 break;
251 }
253 switch (c) {
254 case 's':
//安全标签,adbd的权限说明
255 root_seclabel = optarg;
256 break;
257 case 'b':
//设备类型:android设备,主机
258 adb_device_banner = optarg;
259 break;
260 case 'v':
261 printf("Android Debug Bridge Daemon version %d.%d.%d\n", ADB_VERSION_MAJOR,
262 ADB_VERSION_MINOR, ADB_SERVER_VERSION);
263 return 0;
264 default:
265 // getopt already prints "adbd: invalid option -- %c" for us.
266 return 1;
267 }
268 }
269 //关闭标准输入
//指向标准输出文件描述结构体的STDIN_FILENO指向标准输出文件"/dev/null"
270 close_stdin();
271 //程序异常退出诊断
272 debuggerd_init(nullptr);
//获取系统属性persist.adb.trace_mask,调用setup_trace_mask()设置为trace掩码
273 adb_trace_init(argv);
274
275 D("Handling main()");
//adbd默认通信端口:5037
276 return adbd_main(DEFAULT_ADB_PORT);
277}
着重看下adbd_main()方法
int adbd_main(int server_port) {
//设置新建文件的默认值
//这个与chmod相反,这里相当于新建文件后的权限为666
176 umask(0);
177 //SIG_IGN,表示忽略SIGPIPE信号
178 signal(SIGPIPE, SIG_IGN);
179 //初始化adbd的传输连接
180 init_transport_registration();
182 //保证文件操作安全
184 adbd_cloexec_auth_socket();
185
186 if (ALLOW_ADBD_NO_AUTH && !android::base::GetBoolProperty("ro.adb.secure", false)) {
187 auth_required = false;
188 }
189 //adbd授权初始化
190 adbd_auth_init();
191
192 // Our external storage path may be different than apps, since
193 // we aren't able to bind mount after dropping root.
194 const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");
195 if (adb_external_storage != nullptr) {
196 setenv("EXTERNAL_STORAGE", adb_external_storage, 1);
197 } else {
198 D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE"
199 " unchanged.\n");
200 }
201 //降低特权
202 drop_privileges(server_port);
203
204 bool is_usb = false;
205 if (access(USB_FFS_ADB_EP0, F_OK) == 0) {
206 // Listen on USB.
207 usb_init();
208 is_usb = true;
209 }
210
211 // If one of these properties is set, also listen on that port.
212 // If one of the properties isn't set and we couldn't listen on usb, listen
213 // on the default port.
214 std::string prop_port = android::base::GetProperty("service.adb.tcp.port", "");
215 if (prop_port.empty()) {
216 prop_port = android::base::GetProperty("persist.adb.tcp.port", "");
217 }
218
219 int port;
220 if (sscanf(prop_port.c_str(), "%d", &port) == 1 && port > 0) {
221 D("using port=%d", port);
222 // Listen on TCP port specified by service.adb.tcp.port property.
223 setup_port(port);
224 } else if (!is_usb) {
225 // Listen on default port.
226 setup_port(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
227 }
228
229 D("adbd_main(): pre init_jdwp()");
230 init_jdwp();
231 D("adbd_main(): post init_jdwp()");
232
233 D("Event loop starting");
234 fdevent_loop();
235
236 return 0;
237}
ro.adb.secure
主要来看下这段代码,分析一下ro.adb.secure属性值的作用
186 if (ALLOW_ADBD_NO_AUTH && !android::base::GetBoolProperty("ro.adb.secure", false)) {
187 auth_required = false;
188 }
用grep命令查一下ALLOW_ADBD_NO_AUTH 在哪里初始化
****@****:~/work/mt8788_9$ grep -inr "ALLOW_ADBD_NO_AUTH" system/core/adb/
system/core/adb/Android.mk:347:LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)
获取当前编译环境中的编译版本属性TARGET_BUILD_VARIANT,
如果是userdebug或eng的话,ALLOW_ADBD_NO_AUTH为1,否者为0。
继续查一下auth_required初始化之后在哪里用到
/system/core/adb/adb.cpp
static void handle_new_connection(atransport* t, apacket* p) {
320 if (t->GetConnectionState() != kCsOffline) {
321 t->SetConnectionState(kCsOffline);
322 handle_offline(t);
323 }
324
325 t->update_version(p->msg.arg0, p->msg.arg1);
326 parse_banner(p->payload, t);
327
328#if ADB_HOST
329 handle_online(t);
330#else
331 if (!auth_required) {
332 handle_online(t);
333 send_connect(t);
334 } else {
335 send_auth_request(t);
336 }
337#endif
338
339 update_transports();
340}
当auth_required=true时,设置online标志位为1,调用send_connect()去连接,往下走流程
当auth_required=false时,输出需要认证的消息到终端
在这里做个测试,设置ro.adb.secure=false,然后执行adb命令
C:\Users\lc\Desktop
$ adb root
adb: unable to connect for root: device unauthorized.
This adb server's $ADB_VENDOR_KEYS is not set
Try 'adb kill-server' if that seems wrong.
Otherwise check for a confirmation dialog on your device.
C:\Users\lc\Desktop
$ adb devices
List of devices attached
10.12.200.186:5555 unauthorized
此时设备处入未认证的状态,adb install失效,不符合我们的需求。
drop_privileges()
看drop_privileges函数名,知道它是用来降低权限的,对调用者权限从root到shell的控制
static void drop_privileges(int server_port) {
99 ScopedMinijail jail(minijail_new());
100
101 // Add extra groups:
102 // AID_ADB to access the USB driver
103 // AID_LOG to read system logs (adb logcat)
104 // AID_INPUT to diagnose input issues (getevent)
105 // AID_INET to diagnose network issues (ping)
106 // AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
107 // AID_SDCARD_R to allow reading from the SD card
108 // AID_SDCARD_RW to allow writing to the SD card
109 // AID_NET_BW_STATS to read out qtaguid statistics
110 // AID_READPROC for reading /proc entries across UID boundaries
111 // AID_UHID for using 'hid' command to read/write to /dev/uhid
112 gid_t groups[] = {AID_ADB, AID_LOG, AID_INPUT, AID_INET,
113 AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
114 AID_NET_BW_STATS, AID_READPROC, AID_UHID};
115 minijail_set_supplementary_gids(jail.get(), arraysize(groups), groups);
116
117 //安全模式下,不监听端口(默认为5037),以非root用户身份运行
119 if (should_drop_privileges()) {
120 const bool should_drop_caps = should_drop_capabilities_bounding_set();
121
122 if (should_drop_caps) {
123 minijail_use_caps(jail.get(), CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
124 }
125 //更改群组为AID_SHELL
126 minijail_change_gid(jail.get(), AID_SHELL);
//更改用户为AID_SHELL
127 minijail_change_uid(jail.get(), AID_SHELL);
128 // minijail_enter() will abort if any priv-dropping step fails.
129 minijail_enter(jail.get());
130
131 //清除clearing the inheritable, effective, and permitted sets.
135 using ScopedCaps =
136 std::unique_ptr<std::remove_pointer<cap_t>::type, std::function<void(cap_t)>>;
137 ScopedCaps caps(cap_get_proc(), &cap_free);
138 if (cap_clear_flag(caps.get(), CAP_INHERITABLE) == -1) {
139 PLOG(FATAL) << "cap_clear_flag(INHERITABLE) failed";
140 }
141 if (cap_clear_flag(caps.get(), CAP_EFFECTIVE) == -1) {
142 PLOG(FATAL) << "cap_clear_flag(PEMITTED) failed";
143 }
144 if (cap_clear_flag(caps.get(), CAP_PERMITTED) == -1) {
145 PLOG(FATAL) << "cap_clear_flag(PEMITTED) failed";
146 }
147 if (cap_set_proc(caps.get()) != 0) {
148 PLOG(FATAL) << "cap_set_proc() failed";
149 }
150
151 D("Local port disabled");
152 } else {
153 // minijail_enter() will abort if any priv-dropping step fails.
154 minijail_enter(jail.get());
155
156 if (root_seclabel != nullptr) {
157 if (selinux_android_setcon(root_seclabel) < 0) {
158 LOG(FATAL) << "Could not set SELinux context";
159 }
160 }
161 std::string error;
162 std::string local_name =
163 android::base::StringPrintf("tcp:%d", server_port);
164 if (install_listener(local_name, "*smartsocket*", nullptr, 0, nullptr, &error)) {
165 LOG(FATAL) << "Could not install *smartsocket* listener: " << error;
166 }
167 }
168}
通过should_drop_privileges()函数来判断是否需要降低权限
static bool should_drop_privileges() {
63#if defined(ALLOW_ADBD_ROOT)
64 // The properties that affect `adb root` and `adb unroot` are ro.secure and
65 // ro.debuggable. In this context the names don't make the expected behavior
66 // particularly obvious.
67 //
68 // ro.debuggable:
69 // Allowed to become root, but not necessarily the default. Set to 1 on
70 // eng and userdebug builds.
71 //
72 // ro.secure:
73 // Drop privileges by default. Set to 1 on userdebug and user builds.
74 bool ro_secure = android::base::GetBoolProperty("ro.secure", true);
75 bool ro_debuggable = __android_log_is_debuggable();
76
77 // Drop privileges if ro.secure is set...
78 bool drop = ro_secure;
79
80 // ... except "adb root" lets you keep privileges in a debuggable build.
81 std::string prop = android::base::GetProperty("service.adb.root", "");
82 bool adb_root = (prop == "1");
83 bool adb_unroot = (prop == "0");
84 if (ro_debuggable && adb_root) {
85 drop = false;
86 }
87 // ... and "adb unroot" lets you explicitly drop privileges.
88 if (adb_unroot) {
89 drop = true;
90 }
91
92 return drop;
93#else
94 return true; // "adb root" not allowed, always drop privileges.
95#endif // ALLOW_ADBD_ROOT
96}
看了这里的逻辑才恍然大悟,难怪只是设置ro.secure的值没用,真的需要判断的条件是__android_log_is_debuggable()和service.adb.root属性值。
真丶解决方案
/system/core/liblog/properties.c
280LIBLOG_ABI_PUBLIC int __android_log_is_debuggable() {
281 static uint32_t serial;
282 static struct cache_char tag_cache;
283 static const char key[] = "ro.debuggable";
284 int ret;
285
286 if (tag_cache.c) { /* ro property does not change after set */
287 ret = tag_cache.c == '1';
288 } else if (lock()) {
289 struct cache_char temp_cache = { { NULL, -1 }, '\0' };
290 refresh_cache(&temp_cache, key);
291 ret = temp_cache.c == '1';
292 } else {
293 int change_detected = check_cache(&tag_cache.cache);
294 uint32_t current_serial = __system_property_area_serial();
295 if (current_serial != serial) {
296 change_detected = 1;
297 }
298 if (change_detected) {
299 refresh_cache(&tag_cache, key);
300 serial = current_serial;
301 }
302 ret = tag_cache.c == '1';
303
304 unlock();
305 }
306
307 return ret;
308}
然后查一下service.adb.root属性值的初始化
****@****:~/work/mt8788_9$ grep -inr "service.adb.root" system/core/adb/
system/core/adb/daemon/main.cpp:81: std::string prop = android::base::GetProperty("service.adb.root", "");
system/core/adb/services.cpp:87: android::base::SetProperty("service.adb.root", "1");
system/core/adb/services.cpp:98: android::base::SetProperty("service.adb.root", "0");
/system/core/adb/services.cpp
void restart_root_service(int fd, void *cookie) {
if (getuid() == 0) {
WriteFdExactly(fd, "adbd is already running as root\n");
adb_close(fd);
} else {
if (!__android_log_is_debuggable()) {
WriteFdExactly(fd, "adbd cannot run as root in production builds\n");
adb_close(fd);
return;
}
android::base::SetProperty("service.adb.root", "1");
WriteFdExactly(fd, "restarting adbd as root\n");
adb_close(fd);
}
}
void restart_unroot_service(int fd, void *cookie) {
if (getuid() != 0) {
WriteFdExactly(fd, "adbd not running as root\n");
adb_close(fd);
} else {
android::base::SetProperty("service.adb.root", "0");
WriteFdExactly(fd, "restarting adbd as non root\n");
adb_close(fd);
}
}
可以看到service.adb.root的属性值是动态设置的,判断条件也是__android_log_is_debuggable()方法
修改ro.debuggable的值
diff --git a/build/make/core/main.mk b/build/make/core/main.mk
index c2e0a82f04..14ca69b4a4 100755
--- a/build/make/core/main.mk
+++ b/build/make/core/main.mk
@@ -301,7 +301,7 @@ 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
+ ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=0
# Enable Dalvik lock contention logging.
ADDITIONAL_BUILD_PROPERTIES += dalvik.vm.lockprof.threshold=500
# Include the debugging/testing OTA keys in this build.
编译,烧机之后,验证功能
C:\Users\lc\Desktop
$ adb disconnect & adb connect 10.12.200.27:5555 & adb root & adb remount
disconnected everything
connected to 10.12.200.27:5555
Not running as root. Try "adb root" first.
C:\Users\lc\Desktop
$ adb install -r antutu_v8.4.8.apk
Performing Streamed Install
adb: failed to install antutu_v8.4.8.apk: Failure [-9999: **** signature error for com.antutu.ABenchMark]
注:-9999是增加的第三方验签功能,这里无关紧要。
root功能失效,应用安装功能等保留,问题解决。
总结
遇事多看看源码,看源码之前,看看大佬的博客,有助于我们阅读源码
ADB(二)_ADBD_main()函数代码梳理
ADB(三)_ADBD_adbd_main()函数代码梳理
ADB(四)_host端的启动流程代码梳理