最近学习了如何Hook Android中的剪贴板服务,特此写下一篇博客记录。
首先说明下什么是Hook,Hook即通过使用代理对象替换系统原有对象,达到增强或修改系统类的功能的手段。一般我们替换的对象都会选择不易改变的静态对象。
下面首先介绍Android中获取系统服务的步骤,然后再介绍如何Hook 剪贴板服务ClipboardManager。
以下代码版本为Android 4.4
首先我们调用Context的getSystemService方法,由于Context的实际功能实现类为 ContextImpl,故我们追踪ContextImpl的代码:
@Override
public Object getSystemService(String name) {
ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
return fetcher == null ? null : fetcher.getService(this);
}
ContextImpl去检查了一个系统服务的缓存HashMap SYSTEM_SERVICE_MAP,如下所示(以下仅截取关键代码):
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
new HashMap<String, ServiceFetcher>();
private static void registerService(String serviceName, ServiceFetcher fetcher) {
if (!(fetcher instanceof StaticServiceFetcher)) {
fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
}
SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
}
static {
registerService(ALARM_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(ALARM_SERVICE);
IAlarmManager service = IAlarmManager.Stub.asInterface(b);
return new AlarmManager(service, ctx);
}});
registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new ClipboardManager(ctx.getOuterContext(),
ctx.mMainThread.getHandler());
}});
}
ServiceFetcher是ContextImpl的一个内部类,当我们初次调用getService方法时,会调用createService返回结果
SYSTEM_SERVICE_MAP通过静态代码块初始化注册完毕,其中主要的createService返回方式有两种:- 返回xxxManager(我们这次实验的剪贴板就是这种形式),其中一般