版本:2019.2.5免费版
下载地址:
版本:python3.7.0
下载地址:https://download.csdn.net/download/aiming66/10667438
下载地址:https://github.com/P4nda0s/AndroidNativeEmu
参考:https://github.com/P4nda0s/AndroidNativeEmu/blob/8d3b75b00cc3178955dc8f9ad909f3911a67dd5b/samples/example_jni.py
class MainActivity(metaclass=JavaClassDef, jvm_name='local/myapp/testnativeapp/MainActivity'):
def __init__(self):
pass
@java_method_def(name='stringFromJNI', signature='()Ljava/lang/String;', native=True)
def string_from_jni(self, mu):
pass
def test(self):
pass
emulator.mu.hook_add(UC_HOOK_CODE, debug_utils.hook_code)
main_activity = MainActivity()
logger.info("Response from JNI call: %s" % main_activity.string_from_jni(emulator))
输出
2019-12-04 23:37:06,637 INFO __main__ | Response from JNI call: Hello from C++ ONLOAD!!
2019-12-04 23:37:06,637 INFO __main__ | Exited EMU.
2019-12-04 23:37:06,637 INFO __main__ | Native methods registered to MainActivity:
2019-12-04 23:37:06,637 INFO __main__ | - [0xcbc9cfb9] stringFromJNI - ()Ljava/lang/String;
直接去官网(http://www.keystone-engine.org/download/)下载Python module for Windows - Binaries,然后在电脑上安装即可
解决方案如下
将emulator.java_vm.address_ptr替换成 emulator.java_vm.jni_env.address_ptr即可,实例如下
emulator.call_symbol(lib_module, 'Java_org_xxxx_encryptMessage',emulator.java_vm.address_ptr, 0x00, msgData,len(msgData), key)
------更新解决方案------
提示Jni_OnLoad报错可以不用管,不影响后面执行 ,参考:https://www.52pojie.cn/thread-1031123-1-1.html#28013966_emu%E4%BB%A3%E7%A0%81
因为JNIEnv 和jobject未使用,所以下面可以直接传0
解决方法在后面
参考:https://github.com/zhkl0228/unidbg/issues/12
参考:https://www.anquanke.com/post/id/95199
这个工具现在国内文章寥寥无几,遇到问题实在很难找到解决方法,因此既然没有人帮我们抓鱼,就要我们自己去学习怎么抓鱼了,接下来就来研究下怎么抓鱼(抓bug)吧
我是参考的这篇文章的做法https://www.anquanke.com/post/id/95199
就是打印每条执行的指令,当出错时自然知道在哪条指令哪个地址出错了,然后我们在IDA里找到对应的地址,看看其究竟执行了什么。
就比如上面那个NotImplementedError错误,经过利用上面的方法跟踪发现是在调用env->GetByteArrayElements()出现了问题
既然找到了问题,接下来就来说下怎么解决这些问题, 在上面参考的那篇文章中,他是采用跳过的方法,不过我这个地方,应该不能跳过,毕竟后面还需要这条指令的返回值呢
经过深入调试发现NotImplementedError是由于在so中调用了某个jni方法,而这个方法作者直接抛出了异常,并没有实现其功能,如下图所示:
这是我实现后的
根据错误堆栈,确定出错地方是在下图这个地方
经过单步调试发现问题,显然传入的参数不对,正常情况下应该是0,1,2,....之类的数字,并且经过我手动调整后,的确可以正常运行了,不知道是作者的错误还是我的so库有问题
经过调试,猜测应该是参数过多问题
应该由于多次申请内存,并且预先申请的总内存过小,导致出现错误。
临时解决办法:调整预先申请的总内存大小
理想解决办法:申请内存后及时释放
其实程序会自己释放,而我这个之所以没释放,是由于原先用于释放的代码我没有实现导致的,具体举个例子来说明
一般程序执行了env->get_byte_array_elements函数,就必须执行env->release_byte_array_elements
但我原先以为release_byte_array_elements执行了没什么用,所以就直接填个pass(python里的关键字)代替了,所以就导致了上面的内存问题,具体解决方法就是在release_byte_array_elements实现释放内存的操作就行了,如下图:
伪造个Java类
当看到成功解出的明文后,那种满满的成就感真实非常美妙啊,霎时感觉这几天的努力终于有了回报,喜悦的都快要哭出来了,哈哈 。
感觉就像上帝一样,控制着每一条指令的执行,那种感觉真是太爽了,真是激发了我对于汇编的兴趣!
1.寄存器原来是固定分配的,每个寄存器都有对应的机器码(十六进制值),而不是在运行时随机分配的