___2017

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  326 随笔 :: 18 文章 :: 15 评论 :: 18万 阅读

 


一、背景

目前,很多嵌入式Linux开发为了调试方便移植了adb到Linux,官方也有相应的patch。作为产品方基于安全考虑,可以在量产时关闭adb;如果需要保留,那么应该在adb登陆系统时验证密码。

 

二、adb登录流程

在使用adb shell命令登陆系统时,adb服务(adbd)为我们fork一个子shell作为终端,源码如下:

复制代码
// core/adbd/services.c
#define
SHELL_COMMAND "/bin/sh" static int create_subproc_thread(const char *name) { stinfo *sti; adb_thread_t t; int ret_fd; pid_t pid; if(name) { ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid); } else { ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid); } D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid); ....... } static int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) { char *devname; int ptm; ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); if(ptm < 0){ printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); return -1; } fcntl(ptm, F_SETFD, FD_CLOEXEC); if(grantpt(ptm) || unlockpt(ptm) || ((devname = (char*) ptsname(ptm)) == 0)){ printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); adb_close(ptm); return -1; } *pid = fork(); if(*pid < 0) { printf("- fork failed: %s -\n", strerror(errno)); adb_close(ptm); return -1; } if(*pid == 0){ int pts; setsid(); pts = unix_open(devname, O_RDWR); if(pts < 0) { fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); exit(-1); } dup2(pts, 0); dup2(pts, 1); dup2(pts, 2); adb_close(pts); adb_close(ptm); // set OOM adjustment to zero char text[64]; snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid()); int fd = adb_open(text, O_WRONLY); if (fd >= 0) { adb_write(fd, "0", 1); adb_close(fd); } else { D("adb: unable to open %s\n", text); } execl(cmd, cmd, arg0, arg1, NULL); fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", cmd, strerror(errno), errno); exit(-1); } else { // Don't set child's OOM adjustment to zero. // Let the child do it itself, as sometimes the parent starts // running before the child has a /proc/pid/oom_adj. // """adb: unable to open /proc/644/oom_adj""" seen in some logs. return ptm; } }
复制代码

 

三、增加密码验证功能

系统登陆时验证密码是通过/bin/login命令实现的,所以我们只需要fork时执行它既可。

--- b/core/adbd/services.c
+++ b/core/adbd/services.c
-#define SHELL_COMMAND "/bin/sh" 
+#define SHELL_COMMAND "/bin/adb_shell"

bin/adb_shell:可执行脚本:
复制代码
#!/bin/sh
export ENV='/etc/adb_profile'
if [ $1 = '-' ];then
    /bin/login
elif [ $1 = '-c' ];then
    /bin/login -c "$2"
else
    /bin/login
fi
复制代码

 

/etc/adb_profile:登陆前需要设置环境变量,这里只是简单的复用/etc/profile里的设置:
#!/bin/sh
. /etc/profile

 

posted on   yin'xiang  阅读(7208)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示