1.属性添加说明
为了通过安卓系统的属性控制fridaserver启动和停止,将加入如下属性:
# 该属性控制启动和停止frida
# 0:停止 1:启动
xro.start.myfrd=0
# 该属性设置frida server启动的端口,默认端口为27042
xro.start.myfrd.port=27042
# 该属性控制adbd进程重启,这个属性是为了方便控制adbd进程重启
# 1:停止adbd然后再启动
# 0:停止adbd然后再重启
xro.start.myadbd=
2.系统中添加属性
2.1 系统中新增属性
在文件"buildtoolsbuildinfo.sh"中添加以下属性,添加之后属性如下:
...
echo "xro.start.myfrd=0"
echo "xro.start.myfrd.port=27042"
echo "xro.start.myadbd="
...
2.2 为新增的属性配置selinux标签
由于新增的属性需要在后续开发的具有System权限的App中设置和获取。如果不配置系统App的selinux访问策略,App将没有权限进行属性修改操作。由于adbd运行已经拥有了超级权限,adbd对新增的属性具有读取和设置的能力,所以可以不用为adbd配置访问新增属性的selinux策略。安卓系统中和selinux配置相关的目录路径如下:
systemsepolicy
新增属性配置操作如下。
(1).定义属性标签类型"mysystem_prop"
在以下文件中添加自定义的属性标签类型定义,文件路径如下:
systemsepolicypublicproperty.te
systemsepolicyprebuiltsapi29.0publicproperty.te
自定义的属性标签定义如下:
type mysystem_prop, property_type;
由于以上两个文件内容必须保持一致,所以请确保以上两个文件中添加的内容保持一致,否则编译报错。
(2).为自定义的属性关联标签
在以下文件中添加自定义的属性关联的selinux标签,文件路径如下:
systemsepolicyprivateproperty_contexts
systemsepolicyprebuiltsapi29.0privateproperty_contexts
添加的标签内容如下:
# 表示xro.start.前缀的属性标签都为mysystem_prop
xro.start. u:object_r:mysystem_prop:s0
由于以上两个文件内容必须保持一致,所以请确保以上两个文件中添加的内容保持一致,否则编译报错。
(3).为system_app添加自定义属性访问权限
为了让system权限的app能够访问到自定义的属性,需要在以下文件中添加访问规则,文件路径如下:
systemsepolicyprivatesystem_app.te
systemsepolicyprebuiltsapi29.0privatesystem_app.te
添加的访问规则如下:
# 表示允许系统权限的app读取mysystem_prop标签的属性
get_prop(system_app, mysystem_prop)
# 表示允许系统权限的app修改mysystem_prop标签的属性值
set_prop(system_app, mysystem_prop)
由于以上两个文件内容必须保持一致,所以请确保以上两个文件中添加的内容保持一致,否则编译报错。
3.使用属性控制fridaserver运行
在课程"配置fridaserver为后台服务程序"中已经实现了adbd启动之后启动fridaserver的功能。本篇中将使用新增的属性来控制fridaserver启动、停止。
在文件"systemcoreadbdaemonmain.cpp"中通过属性控制fridaserver的核心关键代码如下:
//该函数判断fridaserver是否已经在运行了
static int is_fridaserver_running() {
int ret=-1;
char buf[256]={0};
FILE * fp=NULL;
if((fp=popen("ps","r"))==NULL)
{
MYLOGD("popen error in is_fridaserver_running");
return ret;
}
while(fgets (buf,255, fp)!=NULL) {
MYLOGD("readline====>%s",buf);
if(strstr(buf,"myfridaserverarm64")!=NULL)
{
ret=0;
break;
}
}
pclose(fp);
return ret;
}
//通过广播发送当前的fridaserver运行状态,方便App中状态更新
static void broadcast_frida_server_status(int status,const char * portstr)
{
//am broadcast -a com.android.myaction.FRIDA_SERVER_STATUS --es isRunning 0
char cmd_buf[128]={0};
sprintf(cmd_buf,"am broadcast -a com.android.myaction.FRIDA_SERVER_STATUS --es isRunning %d --es port %s",status,portstr);
system(cmd_buf);
MYLOGD("broadcast_frida_server_status success");
}
//线程处理函数,根据属性值来判断fridaserver的启动、停止
// 1 for start
// 2 for stop
// 3 for running
void *work_thread(void *m) {
MYLOGD("work_thread start");
while (1 > 0) {
std::string prop = android::base::GetProperty("sys.boot_completed", "");
std::string myfrd = android::base::GetProperty("xro.start.myfrd", "");
std::string port_str = android::base::GetProperty("xro.start.myfrd.port", "27042");
bool boot_ok = (prop == "1");
//bool bool_myfrd= (myfrd == "1" );
MYLOGD("sys.boot_completed:%s", prop.c_str());
if (boot_ok) {
int frida_status = is_fridaserver_running();
broadcast_frida_server_status(frida_status, port_str.c_str());
MYLOGD("is_fridaserver_running==>%d", frida_status);
if (myfrd == "1") {
MYLOGD("start to launch myfridaserverarm64");
char cmd_buf[128] = {0};
sprintf(cmd_buf,
"killall myfridaserverarm64rnsleep 1rnmyfridaserverarm64 -l 0.0.0.0:%s -D",
port_str.c_str());
system(cmd_buf);
MYLOGD("start myfridaserverarm64 finish ");
android::base::SetProperty("xro.start.myfrd", "3");
} else if (myfrd == "0") {
MYLOGD("start to stop myfridaserverarm64");
char cmd_buf[128] = {0};
sprintf(cmd_buf, "killall myfridaserverarm64");
if (frida_status >= 0) {
system(cmd_buf);
}
MYLOGD("stop myfridaserverarm64 finish ");
} else if (myfrd == "3") {
if (frida_status < 0) {
//说明adbd 第一次启动,并且状态属性为3说明adbd被重启了,需要重新启动frida server
MYLOGD("adbd restart,start to launch myfridaserverarm64");
char cmd_buf[128] = {0};
sprintf(cmd_buf,
"killall myfridaserverarm64rnsleep 1rnmyfridaserverarm64 -l 0.0.0.0:%s -D",
port_str.c_str());
system(cmd_buf);
MYLOGD("adbd restart,start myfridaserverarm64 finish ");
//android::base::SetProperty("xro.start.myfrd","3");
}
MYLOGD("myfridaserverarm64 is running");
} else {
}
} else {
//LOG(DEBUG) << "sys.boot_completed:"<<prop;
}
sleep(4);
}
return NULL;
}
//创建线程处理fridaserver的运行
static void start_fridaserver()
{
MYLOGD("start_fridaserver start ");
pthread_t thread_id;
int i = 9;
pthread_create(&thread_id, NULL, &work_thread, (void*)&i);
LOG(DEBUG) << "thread is created!";
}
static void drop_privileges(int server_port) {
...
if (should_drop_privileges()) {
...
} else {
// minijail_enter() will abort if any priv-dropping step fails.
minijail_enter(jail.get());
if (root_seclabel != nullptr) {
if (selinux_android_setcon(root_seclabel) < 0) {
LOG(FATAL) << "Could not set SELinux context";
}
///ADD START
//adbd设置su权限标签之后开启线程进行fridaserver的运行管控
start_fridaserver();
///ADD END
}
...
}
}
4.属性控制adbd重启配置
在本方案中,fridaserver是由adbd母体调用system函数创建的。测试过程中如果adbd杀掉fridaserver也会被杀掉。所以为了防止fridaserver卡死的情况,增加属性控制adbd重启的功能。同时通过该属性控制adbd重启方便在修改模块adbd的代码之后编译测试。
具体操作如下:
在文件init.rc中添加属性控制adbd的配置信息,init.rc文件路径如下:
systemcorerootdirinit.rc
添加的内容为:
on property:xro.start.myadbd=1
stop adbd
start adbd
5.编译刷机验证
5.1 编译
参考命令如下:
qiang@ubuntu:~/lineageOs$ source build/envsetup.sh
qiang@ubuntu:~/lineageOs$ breakfast oneplus3
qiang@ubuntu:~/lineageOs$ brunch oneplus3
Looking for dependencies in device/oneplus/oneplus3
Looking for dependencies in device/oppo/common
....
5.2 刷机
参考命令:
qiang@ubuntu:~/lineageOs$ adb push out/target/product/oneplus3/lineage-17.1-20210324-UNOFFICIAL-oneplus3.zip /sdcard/update.zip
out/target/product/oneplus3/lineage-17...28.1 MB/s (783285269 bytes in 26.561s)
qiang@ubuntu:~/lineageOs$
qiang@ubuntu:~/lineageOs$
qiang@ubuntu:~/lineageOs$ adb reboot recovery
qiang@ubuntu:~/lineageOs$
qiang@ubuntu:~/lineageOs$
qiang@ubuntu:~/lineageOs$
5.3 测试验证
测试关闭fridaserver服务:
C:UsersQiang>adb shell setprop xro.start.myfrd 0
测试打开fridaserver服务:
C:UsersQiang>adb shell setprop xro.start.myfrd 1
测试重启adbd服务:
C:UsersQiang>adb shell setprop xro.start.myadbd 1
原文始发于微信公众号(哆啦安全):添加自定义属性控制fridaserver启动和停止
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论