配置fridaserver为后台进程

描述

1.安卓系统中配置后台进程讨论

在以下讨论两种selinux开启的情况启动frida-server的方法。

1.1 init.xx.rc文件中配置

在安卓系统中配置native后台服务,主要是在init.xx.rc文件中添加服务配置信息。比如adbd后台服务配置如下:

# adbd is controlled via property triggers in init..usb.rc
service adbd /system/bin/adbd --root_seclabel=usu:s0
    class core
    socket adbd seqpacket 660 system system
    disabled
    seclabel uadbd:s0

这种方法配置主要是通过init进程进行启动管理。如果配置的后台进程服务的功能需要超级root权限操作的,最好关闭selinux的情况下进行配置。

以下是通过init.xx.rc文件中配置启动fridaserver的一个参考配置:

service myfridaserver /system/bin/myfridaserverarm64  -D
    class main
    user root
    seclabel uinit:s0

1.2 进程中启动服务配置

可以选择合适的后台进程,调用 system函数进行服务启动。比如选择超级 root权限的adbd、或者root权限的init进程。

1.3 两种方式的测试

在内置fridaserver的过程中,分别对以上两种方式进行了测试。

  • init.xx.rc中国配置

    在开启 selinux的情况下,由于 init进程被限制了很多功能,比如禁止ptrace其他进程,会导致失败。所以该种配置需要根据需要内置服务的功能进行分析,是否适合。虽然init进程运行的是root用户运行,但是selinux的域为init,被限制了很多特权功能。如果不在乎selinux,可以关闭selinux之后进行内置。

  • 进程中启动服务

    进程中启动服务主要是需要找到权限高的进程作为母体。比如像 init进程、adbd进程。在测试过程中,selinux打开的情况下虽然init进程root用户运行,但是selinux标签init限制了很多特权,所以不大适合启动fridaserver。在上一篇文章中已经实现了adbdroot权限运行,并且运行标签变成了usu:s0,所以adbd作为母体启动服务之后,服务就存在了超级权限,比较适合fridaserver这种需要特权的服务。

    以下是通过命令查看的系统init进程和adbd进程运行的selinux域的情况:

 C:UsersQiang>adb shell ps  -Z|findstr "adbd"
usu:s0                      root         11431     1  135960   4564 poll_schedule_timeout 794c9aa3c8 S adbd

C:UsersQiang>adb shell ps  -Z|findstr "init"
uinit:s0                    root             1     0   86984   8240 SyS_epoll_wait 76f889a248 S init
uvendor_init:s0             root           454     1   39736   5256 poll_schedule_timeout 79937963c8 S init
uvendor_init:s0             root           455     1   38968   4328 poll_schedule_timeout 74340f23c8 S init

二、adbd中启动fridaserver开发

2.1 查找合适的启动入口

adbd启动过程中,会根据传入的参数如果存在root_seclabel会将adbd进程的域由uadbd:s0修改为"usu:s0"域。具体相关逻辑位于文件"systemcoreadbdaemonmain.cpp" 中,代码如下:

static void drop_privileges(int server_port) {
    ScopedMinijail jail(minijail_new());

    ...
    if (should_drop_privileges()) {
       ...
    } else {
        // minijail_enter() will abort if any priv-dropping step fails.
        minijail_enter(jail.get());

        if (root_seclabel != nullptr) {
            //修改当前进程的域为usu:s0,从而获得超级权限
            if (selinux_android_setcon(root_seclabel) < 0) {
                LOG(FATAL) << "Could not set SELinux context";
            }
        //TODO 可以考虑在此处添加启动的逻辑
        }
        ...
      }
    }
}

通过以上分析我们可以在adbd设置root_seclable成功之后加入启动frida-server的启动逻辑。

2.2 添加启动核心代码

添加如下方法实现启动 fridaserver进程。

//线程处理函数,主要是判断手机重启完成之后再去启动**fridaserver**
void *work_thread_once(void *m)
{
   MYLOGD("work_thread start");

   while(1>0)
   {
     std::string prop = android::GetProperty("sys.boot_completed""");

  MYLOGD("start_fridaserver_once sys.boot_completed:%s",prop.c_str());
     bool boot_ok = (prop == "1");
   //bool bool_myfrd= (myfrd == "1" );
  MYLOGD("start_fridaserver_once sys.boot_completed:%s",prop.c_str());
  if(boot_ok)
  {

      break;

  }
       sleep(4);    
   }

   std::string port_str="27042";
   MYLOGD("start_fridaserver_once start to launch myfridaserverarm64");
   char cmd_buf[128]={0};
   sprintf(cmd_buf,"killall myfridaserverarm64
sleep 1
myfridaserverarm64 -l 0.0.0.0:%s -D",port_str.c_str());
   system(cmd_buf);
   MYLOGD("start_fridaserver_once start myfridaserverarm64 finish ");

   return NULL;
}

//创建线程等待手机启动完成之后启动fridaserver
static void  start_fridaserver_once()
{

     MYLOGD("start_fridaserver_once start ");
     pthread_t thread_id;
     int i = 9;
     pthread_create(&thread_id, NULL, &work_thread_once, (void*)&i);
     MYLOGD("start_fridaserver_once thread is created!");

}

以上逻辑中判断手机完全重启了才启动。

在设置 root_label的地方加入调用,参考代码如下:

static void drop_privileges(int server_port) {
    ScopedMinijail jail(minijail_new());

    ...
    if (should_drop_privileges()) {
       ...
    } else {
        // minijail_enter() will abort if any priv-dropping step fails.
        minijail_enter(jail.get());

        if (root_seclabel != nullptr) {
            //修改当前进程的域为usu:s0,从而获得超级权限
            if (selinux_android_setcon(root_seclabel) < 0) {
                LOG(FATAL) << "Could not set SELinux context";
            }
        //TODO 可以考虑在此处添加启动的逻辑
          start_fridaserver_once();
        }
        ...
      }
    }
}

3.编译测试

3.1 编译adb模块

参考命令:

//完整编译手机镜像参考命令
qiang@ubuntu:~/lineageOs$ source build/envsetup.sh 
qiang@ubuntu:~/lineageOs$ breakfast oneplus3
qiang@ubuntu:~/lineageOs$ brunch oneplus3

//只编译adbd模块参考
qiang@ubuntu:~/lineageOs$ make adbd
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=10
LINEAGE_VERSION=17.1-20210324-UNOFFICIAL-oneplus3
 ...

3.2 push到手机

由于之前我们已经刷了一次自己编译的手机镜像。所以此处只修改了adbd模块,可以只编译单个模块替换手机系统的就可以。参考命令:

qiang@ubuntu:~/lineageOs$ adb devices
* daemon not running; starting now at tcp:5037
* daemon started successfully
List of devices attached
d5cc1133 device

qiang@ubuntu:~/lineageOs$ adb remount
[libfs_mgr]dt_fstab: Skip disabled entry for partition vendor
[libfs_mgr]dt_fstab: Skip disabled entry for partition vendor
[libfs_mgr]dt_fstab: Skip disabled entry for partition vendor
remount succeeded
qiang@ubuntu:~/lineageOs$ adb push out/target/product/oneplus3/system/bin/adbd   /system/bin/adbd
out/target/product/oneplus3/system/bin...shed. 0.9 MB/s (30608 bytes in 0.034s)
qiang@ubuntu:~/lineageOs$ 
qiang@ubuntu:~/lineageOs$ 

3.3 重启手机测试

参考如下命令:

//查看当前内置的fridaserver是否开机之后自动启动
C:UsersQiang>adb reboot
C:UsersQiang>adb shell ps -Z |findstr "myfridaserver"
usu:s0       root          3216     1  139424  43008 poll_schedule_timeout 7da95663c8 S myfridaserverarm64

//测试手机frida-server是否能连接上
C:UsersQiang>frida-ps -U
 PID  Name
----  ---------------------------------------------------
2190  .dataservices
3290  .dataservices
2305  .qtidataservices
...
   

 


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分