3, ServiceManager Hook过程
每一个Hook系统服务的API都对应着一个ServiceManagerCacheBinderHook对象。下面接着上个章节分析。
3.1 Hook Ibinder对象
首先调用子类的getServiceName方法获取被Hook的系统方法名称,
IlocationManagerBinderHook的getServiceName方法如下,
public String getServiceName() {
return SERVICE_NAME;
}
SERVICE_NAME定义如下,
private final static String SERVICE_NAME = Context.LOCATION_SERVICE;
就是systemserver中的LocationManagerService的名称。
首先构造ServiceManagerCacheBinderHook对象,然后调用onInstall方法,
ServiceManagerCacheBinderHook的构造方法如下,
public ServiceManagerCacheBinderHook(Context hostContext, String servicename) {
super(hostContext);
mServiceName = servicename;//保存服务名称
setEnable(true);
}
ServiceManagerCacheBinderHook也是继承于Hook类,所以构造方法也会调用createHookHandle方法,
protected BaseHookHandle createHookHandle() {
return new ServiceManagerHookHandle(mHostContext);
}
构造了一个ServiceManagerHookHandle对象, ServiceManagerCacheBinderHook其实就是ServiceManager的Hook对象,
ServiceManagerHookHandle就是其代理。
ServiceManagerHookHandle的init方法如下,
protected void init() {
sHookedMethodHandlers.put("queryLocalInterface", new queryLocalInterface(mHostContext));
}
就Hook了一个queryLocalInterface方法。
3.2 onInstall方法
//准备工作终于完成了,
ServiceManagerCacheBinderHook的onInstall方法的主要逻辑如下,
1,获取的sCacheObj 是 ServiceManager的sCache变量,
Object sCacheObj = FieldUtils.readStaticField(ServiceManagerCompat.Class(), "sCache");
ServiceManagerCompat的Class方法如下,
public static final Class Class() throws ClassNotFoundException {
if (sClass == null) {
sClass = Class.forName("android.os.ServiceManager");
}
return sClass;
}
sCacheObj变量是一个哈希表,保存了系统服务的命名和服务, ServiceManager的sCache变量定义如下,
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
2,利用反射调用ServiceManager中getService方法获取LocationManagerService的远程Ibinder对象,
sCache.remove(mServiceName);//删除sCache中原来的LocationManagerService对象
IBinder mServiceIBinder = ServiceManagerCompat.getService(mServiceName);
3,将mServiceName对应的系统原来的服务放入MyServiceManager的mOriginServiceCache中,
MyServiceManager.addOriginService(mServiceName, mServiceIBinder);
MyServiceManager的addOriginService方法如下,
public static void addOriginService(String serviceName, IBinder service) {
mOriginServiceCache.put(serviceName, service);
}
mOriginServiceCache的定义如下,
private static Map<String, IBinder> mOriginServiceCache = new HashMap<String, IBinder>(1);
4,Hook系统服务的Ibinder对象,并且放入ServiceManager的sCache变量中,
Class clazz = mServiceIBinder.getClass();
List<Class<?>> interfaces = Utils.getAllInterfaces(clazz);
Class[] ifs = interfaces != null && interfaces.size() > 0 ? interfaces.toArray(new Class[interfaces.size()]) : new Class[0];
IBinder mProxyServiceIBinder = (IBinder) MyProxy.newProxyInstance(clazz.getClassLoader(), ifs, this);
sCache.put(mServiceName, mProxyServiceIBinder);
5, 将mServiceName对应的Hook对象放入
MyServiceManager.addProxiedServiceCache(mServiceName, mProxyServiceIBinder);
MyServiceManager的addProxiedServiceCache方法如下,
static void addProxiedServiceCache(String serviceName, IBinder proxyService) {
mProxiedServiceCache.put(serviceName, proxyService);
}
mProxiedServiceCache定义如下,
private static Map<String, IBinder> mProxiedServiceCache = new HashMap<String, IBinder>(1);
最后,有个类ServiceManagerBinderHook,听名字像是ServiceManager的Hook,但是好像是多余的,没有地方安装。