逆向libbaiduprotect(三)- 移植python操作dalvik虚拟机c++函数,配合gdb控制程序运行流程
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控制程序运行流程的更多相关文章
- Python逆向(三)—— Python编译运行及反汇编
一.前言 前期我们已经对python的运行原理以及运行过程中产生的文件结构有了了解.本节,我们将结合具体的例子来实践python运行,编译,反编译的过程,并对前些章节中可能遗漏的具体细节进行补充. 二 ...
- python 操作excel 的包 函数
###########sample 1 https://blog.csdn.net/chengxuyuanyonghu/article/details/54951399 python操作excel主要 ...
- Python学习笔记:open函数和with临时运行环境(文件操作)
open函数 1.open函数: file=open(filename, encoding='utf-8'),open()函数是Python内置的用于对文件的读写操作,返回的是文件的流对象(而不是文件 ...
- 06 python操作MySQL和redis(进阶)
python操作mysql.redis 阶段一.mysql事务 主要用于处理操作量大,复杂度高的数据.比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息, ...
- python操作Redis安装、支持存储类型、普通连接、连接池
一.python操作redis安装和支持存储类型 安装redis模块 pip3 install redis 二.Python操作Redis之普通连接 redis-py提供两个类Redis和Strict ...
- Android逆向基础----Android Dalvik虚拟机
Android Dalvik虚拟机的特点: l 体积小,占用内存空间小. l 专有DEX可执行文件. l 常量池采用32位索引值,寻址类方法名,字段名,常量更快. l 基于寄存器架构,并拥有一 ...
- 深入理解JAVA虚拟机原理之Dalvik虚拟机(三)
更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 本文是Android虚拟机系列文章的第三篇,专门介绍Andorid系统上曾经使用 ...
- python 历险记(三)— python 的常用文件操作
目录 前言 文件 什么是文件? 如何在 python 中打开文件? python 文件对象有哪些属性? 如何读文件? read() readline() 如何写文件? 如何操作文件和目录? 强大的 o ...
- 第三百五十节,Python分布式爬虫打造搜索引擎Scrapy精讲—selenium模块是一个python操作浏览器软件的一个模块,可以实现js动态网页请求
第三百五十节,Python分布式爬虫打造搜索引擎Scrapy精讲—selenium模块是一个python操作浏览器软件的一个模块,可以实现js动态网页请求 selenium模块 selenium模块为 ...
随机推荐
- dos命令创建批处理脚本
win+r 打开cmd 输入 copy con 1.bat 回车 进入编辑状态输入 @echo off echo xxxx Ctrl+z 结束编辑 会在当前目录生成一个bat文件
- 移动端真机调试--weinre
一.安装 首先确保你的电脑上有node环境,然后使用cnpm或npm 安装 windows下 npm install weinre -g --registry=https://registry.npm ...
- 如何使用代理IP进行数据抓取,PHP爬虫抓取亚马逊商品数据
什么是代理?什么情况下会用到代理IP? 代理服务器(Proxy Server),其功能就是代用户去取得网络信息,然后返回给用户.形象的说:它是网络信息的中转站.通过代理IP访问目标站,可以隐藏用户的真 ...
- 史上最轻松入门之Spring Batch - 轻量级批处理框架实践
从 MariaDB 一张表内读 10 万条记录,经处理后写到 MongoDB . Batch 任务模型 具体实现 1.新建 Spring Boot 应用,依赖如下: <!-- Web 应用 -- ...
- Activity 学习(一) 插件安装篇
目录 Ider下安装 Eclipse下安装 Ider安装图解 首先,创建一个普通的Java工程即可,然后按照下面流程进行: 1:点击菜单中的File(最左上角),选择settings 2:plugin ...
- Newtonsoft—Json.NET常用方法简述
Json.NET常用方法汇总(可解决日常百分之90的需求) 0.Json.NET基础用法 首先去官网下载最新的Newtonsoft.Json.dll(也可以使用VS自带的NuGet搜索Json.NET ...
- go map数据结构和源码详解
目录 1. 前言 2. go map的数据结构 2.1 核心结体体 2.2 数据结构图 3. go map的常用操作 3.1 创建 3.2 插入或更新 3.3 删除 3.4 查找 3.5 range迭 ...
- Linux 提示符格式及颜色
# 提示符颜色配置: 颜色 黑 红 绿 黄 青 紫 蓝 白 字体 30 31 32 33 34 35 36 37 背景 40 41 42 43 44 45 ...
- Mui 长按保存图片
必须先要 引入 mui.js,然后参考具体代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8 ...
- [Spark]Spark-sql与hive连接配置
一.在Mysql中配置hive数据库 创建hive数据库,刷新root用户权限 create database hive; grant all on *.* to root@'; flush priv ...