您的位置:首页 > 移动开发 > Android开发

android新版本中如何解决厂商应用的su权限

2015-10-10 16:44 525 查看

网上有很多的关于应用执行su,比如Runtime.getRuntime().exec("su"),这个在老版本的android可能还有用(至少我验证4.3就是无效),《android KK 4.4 版本后,user 版本su 权限严重被限制问题说明》这个文章说明了4.4后不是/system/bin/中集成了su命令就了事了,google在android的代码级别进行了限制,即使你在user版本中自执行了su(这个是eng版本源码编译的,我编译到user中了),顶多是shell的$符号变成了#,然而你当前并没有实际的root权限,不信你su后执行ls
/data/data保证立马跳出permission denied,我就是在4.3版本上实验得到这样的效果。但是我用刷机精灵他居然能把我的4.3的系统root了,并新增了/system/bin/su和一个权限管理的apk,并且apk也被放到了/system/app下了,真牛氓,肯定是找漏洞获取了root权限,然后强行push进来的,这样用户删都删不掉,变马甲为系统所有了。我也没这个源码,如果要弄的话,我可以把它的su和superuser.apk从root后的手机中pull出来,再编译到我的system.img就行了,我也不能集成人家的apk,侵权么!?

我们另辟蹊径,因为apk可以执行Runtime.getRuntime().exec(String cmd),那我们就在底层的放一个由init启动的service,然后定制一个cmd与服务socket通信,这样虽然apk与cmd/service在不同的空间,不同的权限,但是底层具有root权限啊,apk将shell命令原汁原味的传递给cmd/service,让他们执行不就行了,当然可能还有更好的办法,此处我就将这个方法记录下。

服务器端的步骤如下:

1. socket: 建立一个socket

2. bind: 将这个socket绑定在某个文件上(AF_UNIX)或某个端口上(AF_INET)

3. listen: 开始监听。指定同时能处理的最大连接要求, 如果连接数目达此上限则client端将收到ECONNREFUSED的错误。Listen()并未开始接收连线, 只是设置socket为listen模式, 真正接收client端连线的是accept()。通常listen()会在socket(), bind()之后调用,
接着才调用accept()。

4. accept: 如果监听到客户端连接,则调用accept接收这个连接并同时新建一个socket来和客户进行通信。【accept一般包含在一个while循环中监听,作为后台监听服务】

5. read/write[send/recv]:读取或发送数据到客户端

6. close: 通信完成后关闭socket

客户端的步骤如下:

1. socket: 建立一个socket

2. connect: 主动连接服务器端的某个文件(AF_UNIX)或某个端口(AF_INET)

3. read/write[b][send/recv][/b]:如果服务器同意连接(accept),则读取或发送数据到服务器端

4. close: 通信完成后关闭socket
对于服务端当接受到客户端原始shell命令后,如果将结果反馈(包括命令执行结果输出和错误输出),对!重定向!

strlcat(recv_buf, " 2>&1", sizeof(recv_buf));
FILE	*fp = popen(recv_buf, "r");
if (!fp) {
ALOGE("exec command failed. (%d)\n", -errno);
close(sock_client);
continue;
}
while (fgets(send_buf, sizeof(send_buf), fp)) {
ALOGI("Send %d bytes: %s\n", strlen(send_buf), send_buf);
len = send(sock_client, send_buf, strlen(send_buf), 0);
if (len < (int)strlen(send_buf)) {
ALOGE("send failed. (%d)\n", len);
break;
}
}


打开一个管道popen,这个管道会用shell去运行recv_buf中命令,这个命令中追加了2>&1就是将错误输出也输出到标准输出上,这样执行结果或者错误结果都会从管道的另一端出来,然后fgets就是读取这些输出,然后逆向传给调用者。

集成下载代码的时候注意点:

1).在init.rc中加入

service seustub /system/bin/seustub
class main
2).加入编译体系

因为下面的代码TAG是optional,所以在系统编译环境的比如我这是msm8610.mk中的PRODUCT_PACKAGES要加入

PRODUCT_PACKAGES += \
seustub \
seustubtest \
3)在使用时调用seustubtest加上shell命令,

比如seustbtest cp /sdcard/xxx.apk /system/app/

代码下载http://download.csdn.net/detail/sgmenghuo/9168557
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: