从dumpsys自定义服务来认识Android binder
2016-04-15 22:15
316 查看
问题的提出
dumpsys是一个非常有用的命令,可以用来查看打印一些系统服务数据
如
adb shell dumpsys display
adb shell dumpsys battery
详细内容可以搜索dumpsys查看
在查看代码的时候,发现
publishBinderService(“battery”, new BinderService());
猜测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;
ALOGE(“=======test go =======”);
// return -1;
}
就可以调用自定义服务了
dumpsysatestdumpsysatestBinderService2dumpcalled==================== dumpsys atest
dumpsys atest
BinderService2 dump called ====================
ap调用测试
adb shell dumpsys atest
可以调用atest服务的dump方法
再写个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
写的非常好
总结
这里通过添加一个自定义服务,了解了addService的一些信息。
binder是用来进行进程间通信的,和ICE通信机制类似。
采用一些数据传送方法,把client和server关联交互起来
dumpsys是一个非常有用的命令,可以用来查看打印一些系统服务数据
如
adb shell dumpsys display
adb shell dumpsys battery
详细内容可以搜索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;
}
就可以调用自定义服务了
dumpsysatestdumpsysatestBinderService2dumpcalled==================== dumpsys atest
dumpsys atest
BinderService2 dump called ====================
ap调用测试
adb shell dumpsys atest
可以调用atest服务的dump方法
再写个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
写的非常好
总结
这里通过添加一个自定义服务,了解了addService的一些信息。
binder是用来进行进程间通信的,和ICE通信机制类似。
采用一些数据传送方法,把client和server关联交互起来
相关文章推荐
- Android--view自定义--圆环等待
- 五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程
- Android-五子连珠
- 一个基于场景感应的android智能手机防丢失系
- Android Activity彻底运行起来之后的回调onPostCreate( )
- Android之Surfaceview和SurfaceHolder用法
- 【Android 应用开发】GitHub 优秀的 Android 开源项目
- Android--Camera.addCallbackBuffer/setPreviewCallbackWithBuffer模式使用总结
- Android:布局实例之模仿京东登录界面
- 学习Android第8天,Asynctask的使用(异步操作)
- Android:PopupWindow简单弹窗改进版
- android应用程序Manifest文件简介
- Android:PopupWindow简单弹窗
- [android]ShareSDK——内容分享和短信验证
- Android:密码显示隐藏
- Android(三)----数据存储和界面展现02
- Android:利用SharedPreferences实现自动登录
- Android:控件AutoCompleteTextView 客户端保存搜索历史自动提示
- Android学习笔记---(自己实现SimpleAdapter)BaseAdapter
- Android:控件AutoCompleteTextView 自动提示