-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Description
由于我想看到HookerMethodHandler类里的doHookInner日志,我把第61-63行的代码从
if (time > 5) {
Log.i(TAG, "doHookInner method(%s.%s) cost %s ms", method.getDeclaringClass().getName(), method.getName(), time);
}
改成了
//if (time > 5) {
Log.i(TAG, "doHookInner method(%s.%s) cost %s ms", method.getDeclaringClass().getName(), method.getName(), time);
// }
我注释掉了time >5的代码,结果我在断点调试的时候就发现了一个NPE错误,我在Log类的第122行,
sHandler.post(new Runnable() {
报了NPE,其中sHandler为空,但是
static {
sHandlerThread = new HandlerThread("DroidPlugin@FileLogThread");
sHandlerThread.start();
sHandler = new Handler(sHandlerThread.getLooper());
}
sHandler是在静态代码里初始化的,按理说调用静态方法的时候这些静态代码块是执行完的,不会出现NPE的问题,
再次经过断点调试以后我发现了问题,
在HoolFactory的方法
public void installHook(Hook hook, ClassLoader cl) {
try {
hook.onInstall(cl);
synchronized (mHookList) {
mHookList.add(hook);
}
} catch (Throwable throwable) {
Log.e(TAG, "installHook %s error", throwable, hook);
}
}
当抛出异常的时候会调用Log.e,然后先去初始化Log方法,在Log方法的初始里,有一行这个代码
private static final File sDir = new File(Environment.getExternalStorageDirectory(), "360Log/Plugin/");
这个方法会去调用系统调用,由于前面Environment的系统调用已经被hook住了,所以就会走到HookerMethodHandler,然后会走到
Log.i(TAG, "doHookInner method(%s.%s) cost %s ms", method.getDeclaringClass().getName(), method.getName(), time);
此时就会去调用Log的i方法,最后就会走到sHandler.post(new Runnable() {这里,此时sHandlerThread的初始化静态代码块是还没有初始化完的,就会出现上面问题了。
本质上就是在类的静态代码块里调用了该类的方法,而这个方法使用到了静态变量或者静态代码块里的内容,而这些内容还没有被初始化,至于修改的方法有很多,其一就是可以把那个静态代码块放到会引起静态方法调用的静态变量之前,也可以在hook install之前将 Log类提前初始化好,以上就是一些个人的看法,望采纳。