一、目标
上篇教程我们填了jmethodID相同的坑之后,报错:
logger.debug("JNIEnv->GetMethodId(%d, %s, %s) was called,jvm_id = %d" % (clazz_idx, name, sig, method.jvm_id))
AttributeError: 'NoneType' object has no attribute 'jvm_id'
二、步骤
从错误提示上看应该是 method的类型是 Nonetype, 先不管,我们看看别的参数是什么,把打印部分的代码改成:
logger.debug("JNIEnv->GetMethodId(%s, %d, %s, %s) was called" % (type(clazz), clazz_idx, name, sig))
再跑
RuntimeError: Could not find method ('getPackageName', '()Ljava/lang/String;') in class android/app/Activity.
好吧,把Activity的getPackageName方法加上,这里也有jmethodID相同的把戏,所以我们把jvm_id也加上一个。
class Application(metaclass=JavaClassDef, jvm_name='android/app/Application'):
def __init__(self):
pass
@java_method_def(name='getPackageManager', signature='()Landroid/content/pm/PackageManager;' , native=False,jvm_id=0xd2000000+0x1000)
def getPackageManager(self, mu):
logger.info("Im in Application.getPackageManager")
pass
@java_method_def(name='getPackageName', signature='()Ljava/lang/String;' , native=False,jvm_id=0xd2000000+0x1004)
def getPackageName(self, mu):
logger.info("Im in Application.getPackageName")
return "com.jingdong.app.mall"
class Activity(metaclass=JavaClassDef, jvm_name='android/app/Activity'):
def __init__(self):
pass
@java_method_def(name='getPackageManager', signature='()Landroid/content/pm/PackageManager;' , native=False,jvm_id=0xd2000000+0x1000)
def getPackageManager(self, mu):
logger.info("Im in Activity.getPackageManager")
pass
@java_method_def(name='getPackageName', signature='()Ljava/lang/String;' , native=False,jvm_id=0xd2000000+0x1004)
def getPackageName(self, mu):
logger.info("Im in Application.getPackageName")
return "com.jingdong.app.mall"
在跑
androidemu.java.jni_env | JNIEnv->call_object_method(16780528,3523215368) was called
......
raise RuntimeError('Invalid get_reference(%d)' % idx)
RuntimeError: Invalid get_reference(16780528)
3523215386 从前面的日志能找到是getPackageInfo方法的jvm_id,那16780528是什么?从日志里看不出来。
DEBUG androidemu.java.java_method_def | JavaMethodDef name =getPackageInfo,jvm_id = 3523215368
我们来看看IDA反编译出来的代码:
这是之前调用 Application.getPackageManager() 来返回的PackageManager对象,在之前的代码里我们只打印了一下日志,并没有实现这个函数, 参考下原作者定义的PackageManager类,我们学着实现这个函数:
class Application(metaclass=JavaClassDef, jvm_name='android/app/Application'):
def __init__(self):
self.__pkg_Manager = PackageManager()
pass
@java_method_def(name='getPackageManager', signature='()Landroid/content/pm/PackageManager;' , native=False,jvm_id=0xd2000000+0x1000)
def getPackageManager(self, mu):
logger.info("Im in Application.getPackageManager")
return self.__pkg_Manager
class Activity(metaclass=JavaClassDef, jvm_name='android/app/Activity'):
def __init__(self):
self.__pkg_Manager = PackageManager()
pass
@java_method_def(name='getPackageManager', signature='()Landroid/content/pm/PackageManager;' , native=False,jvm_id=0xd2000000+0x1000)
def getPackageManager(self, mu):
logger.info("Im in Activity.getPackageManager")
return self.__pkg_Manager
继续跑,成功跑过去,明天再继续
关注微信公众号,最新技术干货实时推送