赞
踩
详细内容可以搜索dumpsys查看
在查看代码的时候,发现
publishBinderService(“battery”, new BinderService());
private final class BinderService extends Binder {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump Battery service from from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid());
return;
}
dumpInternal(pw, args);
}
}
猜测dumpsys 服务名
可以调用的服务是在这里设置的
publishBinderService(“battery”, new BinderService());
于是,照葫芦画瓢,写了一句
publishBinderService(“atest”, new BinderService());
预料adb shell dumpsys atest 会进行打印调用
结果呢?
编译后,手机不能开机了。
好在可以在DDMS里抓到log
01-01 00:00:57.841: E/AndroidRuntime(817): * FATAL EXCEPTION IN SYSTEM PROCESS: main
01-01 00:00:57.841: E/AndroidRuntime(817): java.lang.RuntimeException: Failed to start service com.android.server.BatteryService: onStart threw an exception
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.server.SystemServiceManager.startService(SystemServiceManager.java:119)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.server.SystemServer.startCoreServices(SystemServer.java:621)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.server.SystemServer.run(SystemServer.java:372)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.server.SystemServer.main(SystemServer.java:258)
01-01 00:00:57.841: E/AndroidRuntime(817): at java.lang.reflect.Method.invoke(Native Method)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
01-01 00:00:57.841: E/AndroidRuntime(817): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:739)
01-01 00:00:57.841: E/AndroidRuntime(817): Caused by: java.lang.SecurityException
一个字符串名称异常导致了系统不能开机,也就是说,一个字符就可以让系统不能开机,太可怕了
在publishBinderService(“atest”, new BinderService());
调用的时候进行try catch处理
结果还好,系统可以开机了
01-01 13:20:07.860: D/BatteryService(968): ================ atest ============
01-01 13:20:07.861: E/SELinux(325): avc: denied { add } for service=atest scontext=u:r:system_server:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager
01-01 13:20:07.862: E/ServiceManager(325): add_service(‘atest’,28) uid=1000 - PERMISSION DENIED
01-01 13:20:07.862: D/BatteryService(968): ================ atest catch ============
01-01 13:20:07.862: W/System.err(968): java.lang.SecurityException
01-01 13:20:07.868: W/System.err(968): at android.os.BinderProxy.transactNative(Native Method)
还不错,打印出了具体信息,SELinux权限的问题
搜索
SELinux(325): avc: denied { add } for service
在stackoverflow上看到一种解决方案
To file:
android-dev\external\sepolicy\service.te
Add:
type mytest_service, system_api_service, system_server_service, service_manager_type;
To file:
android-dev\external\sepolicy\service_contexts
Add:
mytestservice u:object_r:mytest_service:s0
where mytestservice your name service
修改android/external/sepolicy 里的文件
修改后编译,还是抛异常
查找代码
find . -name *.c|xargs grep ’ PERMISSION DENIED’
./frameworks/native/cmds/servicemanager/service_manager.c: ALOGE(“add_service(‘%s’,%x) uid=%d - PERMISSION DENIED\n”,
./frameworks/native/cmds/servicemanager/service_manager.c: ALOGE(“list_service() uid=%d - PERMISSION DENIED\n”,
修改了te文件还是有异常,??
这个不清楚是不是编译的问题,现在决定跳过赋权,对服务调用进行测试
修改./frameworks/native/cmds/servicemanager/service_manager.c
int do_add_service(struct binder_state *bs,
const uint16_t *s, size_t len,
uint32_t handle, uid_t uid, int allow_isolated,
pid_t spid)
{
struct svcinfo *si;
//ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,
// allow_isolated ? "allow_isolated" : "!allow_isolated", uid);
if (!handle || (len == 0) || (len > 127))
return -1;
if (!svc_can_register(s, len, spid)) {
ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
str8(s, len), handle, uid);
ALOGE(“=======test go =======”);
// return -1;
}
就可以调用自定义服务了
再写个ap进行测试
Binder aObject;
try {
aObject = (Binder)getSystemService(“atest”);
int id = aObject.getCallingPid();
System.out.println(“Pid = ” + id);
Log.d(“test614”, “Pid = ” + id);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
Log
01-05 09:32:35.122: D/test614(801): Pid = 801
这样调用的都是binder里的接口方法,如果要自定义方法,aidl就出场了
详细使用可以查看这位达人的系列blog
http://www.cloudchou.com/android/post-447.html
写的非常好
binder是用来进行进程间通信的,和ICE通信机制类似。
采用一些数据传送方法,把client和server关联交互起来
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。