Hook Java的的一个改进版本
《注入安卓进程,并Hook java世界的方法》这篇好文相信大家都看这,里面所提到的方法估计大家也都试过。不过里面的所用的方法,我发现有两个可以改进的地方。
改进点一:更简单地修改java方法为本地方法
...
// hook method
int argsSize = calcMethodArgsSize(method->shorty);
if (!dvmIsStaticMethod(method))
argsSize++;
SET_METHOD_FLAG(method, ACC_NATIVE);
method->registersSize = method->insSize = argsSize;
method->outsSize = 0;
method->jniArgInfo = dvmComputeJniArgInfo(method->shorty);
// save info to insns
method->insns = (u2*)info;
// bind the bridge func,only one line
method->nativeFunc = method_handler;
LOGI("[+] %s->%s was hooked\n", classDesc, methodName);
...
直接把method->nativeFunc即可,无需重新调用JNIEnv的RegisterNatives方法,其中method_handler可以是下面两种形式之一:
typedef void (*DalvikBridgeFunc)(const u4* args, JValue* pResult, const Method* method, struct Thread* self);
typedef void (*DalvikNativeFunc)(const u4* args, JValue* pResult);
这样有一个好处,就是所有java方法都可以统一指向同一个native func,而不需要像为每一个java method方法指定一个native func。
改进点二:方法回调避免线程安全问题
原来的方法,是这样的
//hook之前先拷贝
uint mlen = sizeof(Method);
Method *oldMeth = (Method*)malloc(mlen);
memcpy(oldMeth,method,mlen);
info->odlMethod = oldMeth;
info->curMethod = method;
//回调后再拷贝回来&