python编译移植到测试机,并且移植ctypes模块。利用ctypes代替c程序,利用dalvik内部c++函数,在运行过程中手动命令操控dalvik虚拟机,并结合gdb进行调试。绕过zygote和ASM去启动进程。

由于我使用手动创建虚拟机,而不是通过zygote去启动虚拟机,zygote会通过androidruntime::startVM去加载和初始化所有运行app的环境。所以我必须自行完成这些必要的工作。

不同于jvm,dalvik必须加载两种java运行时包,java runtime以及android runtime。并且不会自动加载native库去注册上面两个runtime的native实现方法。java.*和android.*都在sdk的platform/$(api-level)/android.jar,java.*被称为core library,我们必须编译这个core库成dex,在我们手动的创建的虚拟机中加载。

    system_load(jenv, "/system/lib/libjavacore.so")
system_load(jenv, "/system/lib/libandroid.so")
system_load(jenv, "/system/lib/libandroid_runtime.so")
system_load(jenv, "/system/lib/libbinder.so") print "now start android runtime"
ar = cdll.LoadLibrary("libandroid_runtime.so")
callcxxF(ar, "android::AndroidRuntime::startReg", [jenv])

然后我们还要加载支持core库的native库。libjavacore.so这是对应java.*的native方法实现,libandroid_runtime.so这是对应android.*的native方法实现。我们手动创建的虚拟机必须手动去加载这两个库,libjavacore.so有JNI_OnLoad实现,会自动注册它的native方法。但是libandroid_runtime.so却没有JNI_OnLoad实现,我们必须使用objdump查看函数符号,找出它可能用于注册native方法的函数,并在加载它时调用这个函数去注册native方法。不然的话,你创建的虚拟机并不能使用android.*,尽管你已经加载了这些类,或者还加载了这个so,但是由于你没有注册android.*所依赖的native实现方法,所以不能使用。

之后就是去用jni初始化一些对象,这些对象都是你要调试的so库,它所依赖(或访问到)的java对象。另外就是你只想调试dex里面的某个类,而这个类所依赖(或访问到)的java对象。

通过dvm内部函数加载dex或odex,然后将类加载到虚拟机。

在运行调试过程中,可以使用python调用jni测试调试你想查询的信息,结合gdb可以操控所有线程的运行,并且利用gdb脚本,从虚拟机内部结构出发分析运行状态信息,使用断点(如 dvmCallMethodA)和断点命令日志,跟踪java层或jni调用的行为。gdb调试还可以手动构筑环境让程序在濒临信号崩溃之时得以继续运行下去。

在绕开了来自java层和c层的反调试监控后,让调试的程序运行下去,但是由于程序依赖ContextImpl,这个必须依赖于ASM去初始化的对象,因为脱离zygote和ASM,手动无法创建一个让程序满意的ContextImpl,这个对象关联了太多application运行依赖的服务和信息。

下面是实例,加载libbaiduprotect_x86.so后,libbaiduprotect_x86.so的行为被gdb跟踪监测:

由于程序不是由ASM启动的Application,所以ActivityThread.currentPackageName()返回空,在c层使用这个结果进行strlen时出错,这里还好,用gdb就可以填补过去。构建一个字符串就是了,让程序继续执行。

libbaiduprotect.so依赖了android/app/ContextImpl,抛出了异常,并且在下一次Jni调用时,dalvik主动检测pending异常,发现后对程序abort。

这里必须要注意,SIGSEGV不一定是内存访问出错,在上面的情况是abort发出的信号。

逆向libbaiduprotect(三)- 移植python操作dalvik虚拟机c++函数,配合gdb控制程序运行流程的更多相关文章

  1. Python逆向(三)—— Python编译运行及反汇编

    一.前言 前期我们已经对python的运行原理以及运行过程中产生的文件结构有了了解.本节,我们将结合具体的例子来实践python运行,编译,反编译的过程,并对前些章节中可能遗漏的具体细节进行补充. 二 ...

  2. python 操作excel 的包 函数

    ###########sample 1 https://blog.csdn.net/chengxuyuanyonghu/article/details/54951399 python操作excel主要 ...

  3. Python学习笔记:open函数和with临时运行环境(文件操作)

    open函数 1.open函数: file=open(filename, encoding='utf-8'),open()函数是Python内置的用于对文件的读写操作,返回的是文件的流对象(而不是文件 ...

  4. 06 python操作MySQL和redis(进阶)

    python操作mysql.redis 阶段一.mysql事务 主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息, ...

  5. python操作Redis安装、支持存储类型、普通连接、连接池

    一.python操作redis安装和支持存储类型 安装redis模块 pip3 install redis 二.Python操作Redis之普通连接 redis-py提供两个类Redis和Strict ...

  6. Android逆向基础----Android Dalvik虚拟机

    Android Dalvik虚拟机的特点: l  体积小,占用内存空间小. l  专有DEX可执行文件. l  常量池采用32位索引值,寻址类方法名,字段名,常量更快. l  基于寄存器架构,并拥有一 ...

  7. 深入理解JAVA虚拟机原理之Dalvik虚拟机(三)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 本文是Android虚拟机系列文章的第三篇,专门介绍Andorid系统上曾经使用 ...

  8. python 历险记(三)— python 的常用文件操作

    目录 前言 文件 什么是文件? 如何在 python 中打开文件? python 文件对象有哪些属性? 如何读文件? read() readline() 如何写文件? 如何操作文件和目录? 强大的 o ...

  9. 第三百五十节,Python分布式爬虫打造搜索引擎Scrapy精讲—selenium模块是一个python操作浏览器软件的一个模块,可以实现js动态网页请求

    第三百五十节,Python分布式爬虫打造搜索引擎Scrapy精讲—selenium模块是一个python操作浏览器软件的一个模块,可以实现js动态网页请求 selenium模块 selenium模块为 ...

随机推荐

  1. linux-pclint代码检测

    win10.ubuntu16.04, vs2017. 1.安装pc-lint到C盘. 2.将linux下的usr整个目录打包拷贝到win10某盘下. 3.获取lint检测linux c++ 代码的宏参 ...

  2. python编程系列---最详细的讲解进程与线程的关系

    进程与线程 先引入三个比如: cpu---公司 进程---办公室   线程---程序员(我们)   全局变量,内存等资源---公司提供的电脑,桌子等 进程:  操作系统分配程序执行资源的单位 线程:进 ...

  3. StreamWriter 相关知识分享

    在介绍StreamWriter之前,我们首先来了解一下它的父类TextWriter. 一.TextWriter 1.TextWriter的构造函数和常用属性方法 下面是TextWriter的构造函数: ...

  4. 解决Anki服务器同步问题:坚果云 & Floder sync (已测试)

    读前须知: 更新日期:2019-07-08 1.本教程面向对象为:有一定计算机知识人群 2.配合参考链接中的文章,共同食用. 3.已经过测试,可同步图片,音频,视频 4.尝试有风险,提前导出Anki卡 ...

  5. CentOS6.6-MySQL报Curses library not found

    cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.40 \> -DMYSQL_DATADIR=/application/mysql-5. ...

  6. 把图片在word中显示

    如下: //放入word中 #region word ThreadPool.QueueUserWorkItem(//使用线程池 (P_temp) =>//使用lambda表达式 { G_wa = ...

  7. unityweb Request请求

    UnityWebRequest是新的网络请求Api,分为LLApi和HLApi,其中LLApi为低级api,所谓低级api是指只是提供最基本的api接口,然后需要通过不同的参数来确定请求方式.为此un ...

  8. 百度地图Javascript API 调用示例

    调用示例 !<!DOCTYPE html> <html> <head> <title>百度地图DEMO</title> </head& ...

  9. js实现的几种继承方式

    他山之石,可以攻玉,本人一直以谦虚的态度学他人之所长,补自己之所短,望各位老师指正! 拜谢 js几种继承方式,学习中的总结: 所谓的继承是为了继承共有的属性,减少不必要代码的书写 第一种:借用构造函数 ...

  10. Linux 命令行获取天气

    目标: 使用 Linux 命令行显示天气预报. 发行版: 所有 Linux 发行版. 要求: 能连上因特网的 Linux 难度: 容易 约定: # - 需要使用 root 权限来执行指定命令,可以直接 ...