基于Frida框架打造Art模式下的脱壳工具(OpenMemory)的原理分析
本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80956614
作者dstmath在看雪论坛公布一个Android的art模式下基于frida框架的脱壳脚本,详情见文章《基于frida的脱壳工具》的介绍,作者dstmath公布的frida脚本代码见github地址:https://github.com/dstmath/frida-unpack,脱壳原理比较简单,和我前面的博客《ART模式下基于Xposed Hook开发脱壳工具》中提到的作者的脱壳的思路是一致,这个脱壳思路也比较常见,在看雪论坛有多位楼主提到了这个基于Android的art模式下的OpenMemory拦截进行内存dump的脱壳思路,其实很多Xposed框架的Hook思路都可以移植到基于Frida框架的Hook上,顺便提一句,作者dstmath的简书博客写的不错。
具体参考的其他的文章:
《乐固libshella 2.10.1分析笔记》作者的帖子写的很不错。
《Android第二代加固(support 4.4-8.1)》
下面简要的说下,作者dstmath提供的frida脱壳脚本需要注意的几个点:
由于随着Android系统版本的升级,Art模式下libart.so库中OpenMemory函数的传入参数会有所不同,因此libart.so库文件中OpenMemory函数在编译时的名称粉粹也会不同,不同版本的Android系统的libart.so库文件导出函数OpenMemory的系统符号也会有差异,可用通过adb pull导出相应版本的Android系统的libart.so库文件,用IDA打开该libart.so库文件查看导出表中OpenMemory函数的导出系统符号或者使用 nm 等能查看ELF文件的导出系统符号的工具,查看libart.so库文件中OpenMemory函数的导出系统符号,相应的修改frida-unpack中的frida脱壳脚本文件frida_unpack.py和OpenMemory.js中OpenMemory函数的导出系统符号。
frida的命令行帮助:
>frida -h
Usage: frida [options] target
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-D ID, --device=ID connect to device with the given ID
-U, --usb connect to USB device
-R, --remote connect to remote frida-server
-H HOST, --host=HOST connect to remote frida-server on HOST
-f FILE, --file=FILE spawn FILE
-n NAME, --attach-name=NAME
attach to NAME
-p PID, --attach-pid=PID
attach to PID
--debug enable the Node.js compatible script debugger
--enable-jit enable JIT
-l SCRIPT, --load=SCRIPT
load SCRIPT
-c CODESHARE_URI, --codeshare=CODESHARE_URI
load CODESHARE_URI
-e CODE, --eval=CODE evaluate CODE
-q quiet mode (no prompt) and quit after -l and -e
--no-pause automatically start main thread after startup
-o LOGFILE, --output=LOGFILE
output to log file
1.直接执行frida命令加载脱壳脚本OpenMemory.js文件进行Hook OpenMemory函数的操作 ,内存dump dex文件。
frida -U -f $1 -l $2 --no-pause
# $1--为被脱壳的Android应用的包名
# $2--为被frida加载的脚本文件OpenMemory.js
被frida加载的脚本文件OpenMemory.js的代码如下(代码中使用的被脱壳的Android应用包名需要做相应的修改):
'use strict';
/**
* 此脚本在以下环境测试通过
* android os: 7.1.2 32bit (64位可能要改OpenMemory的签名)
* legu: libshella-2.8.so
* 360:libjiagu.so
*/
Interceptor.attach(Module.findExportByName("libart.so", "_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_"), {
onEnter: function (args) {
//dex起始位置
var begin = args[1]
//打印magic
console.log("magic : " + Memory.readUtf8String(begin))
//dex fileSize 地址
var address = parseInt(begin,16) + 0x20
//dex 大小
var dex_size = Memory.readInt(ptr(address))
console.log("dex_size :" + dex_size)
//dump dex 到/data/data/pkg/目录下
var file = new File("/data/data/xxx.xxx.xxx/" + dex_size + ".dex", "wb")
file.write(Memory.readByteArray(begin, dex_size))
file.flush()
file.close()
},
onLeave: function (retval) {
if (retval.toInt32() > 0) {
/* do something */
}
}
});
2.使用frida框架的远程控制端(客户端)提供的python语言的控制接口调用frida程序执行Hook OpenMemory函数的操作 ,内存dump dex文件,python的脱壳脚本frida_unpack.py文件的代码如下:
#-*- coding:utf-8 -*-
# coding=utf-8
import frida
import sys
def on_message(message, data):
base = message['payload']['base']
size = int(message['payload']['size'])
print hex(base),size
# print session
# dex_bytes = session.read_bytes(base, size)
# f = open("1.dex","wb")
# f.write(dex_bytes)
# f.close()
package = sys.argv[1]
print "dex 导出目录为: /data/data/%s"%(package)
device = frida.get_usb_device()
pid = device.spawn(package)
session = device.attach(pid)
src = """
Interceptor.attach(Module.findExportByName("libart.so", "_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_"), {
onEnter: function (args) {
var begin = args[1]
console.log("magic : " + Memory.readUtf8String(begin))
var address = parseInt(begin,16) + 0x20
var dex_size = Memory.readInt(ptr(address))
console.log("dex_size :" + dex_size)
var file = new File("/data/data/%s/" + dex_size + ".dex", "wb")
file.write(Memory.readByteArray(begin, dex_size))
file.flush()
file.close()
var send_data = {}
send_data.base = parseInt(begin,16)
send_data.size = dex_size
send(send_data)
},
onLeave: function (retval) {
if (retval.toInt32() > 0) {
}
}
});
"""%(package)
script = session.create_script(src)
script.on("message" , on_message)
script.load()
device.resume(pid)
sys.stdin.read()
附上《修改源码dump某加固保的dex》这篇帖子的内容做个备份,本来打算在这篇博客中学习一下art模式下dex文件的加载流程,想想还是后面再研究吧,想看该帖子的内容建议去作者的原链接处看,谢谢原作者。
const DexFile* DexFile::OpenMemory(const byte* base,
size_t size,
const std::string& location,
uint32_t location_checksum,
MemMap* mem_map,
const OatFile* oat_file,
std::string* error_msg) {
CHECK_ALIGNED(base, 4); // various dex file structures must be word aligned
std::unique_ptr<DexFile> dex_file(
new DexFile(base, size, location, location_checksum, mem_map, oat_file));
if (!dex_file->Init(error_msg)) {
return nullptr;
} else {
__android_log_print(ANDROID_LOG_DEBUG,"chason 's DexFile::OpenMemory",
"size is:%zu,location is:%s", size, location.c_str());
if (!strcmp(location.c_str(),"/data/data/com.autohome.mycar/.jiagu/classes.dex"))
{
int fd = open("/data/data/com.autohome.mycar/classes.dex",O_CREAT|O_EXCL|O_WRONLY,S_IRWXU);
__android_log_print(ANDROID_LOG_DEBUG,"chason's copy is starting!","hello");
if (fd>0)
write(fd,base,size);
else
__android_log_print(ANDROID_LOG_DEBUG,"chason's copy is failed!","codeis:%d",fd);
close(fd);
}
return dex_file.release();
}
}
好了,后面继续学习~
基于Frida框架打造Art模式下的脱壳工具(OpenMemory)的原理分析的更多相关文章
- ART模式下基于Xposed Hook开发脱壳工具
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78092365 Dalvik模式下的Android加固技术已经很成熟了,Dalvik ...
- ART模式下基于dex2oat脱壳的原理分析
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78513483 一般情况下,Android Dex文件在加载到内存之前需要先对dex ...
- Android逆向进阶—— 脱壳的奥义(基ART模式下的dump)
本文作者:i春秋作家HAI_ZHU 0×00 前言 市面上的资料大多都是基于Dalvik模式的dump,所以这此准备搞一个ART模式下的dump.HAI_的使用手册(各种好东西) Dalvik模式是A ...
- 基于frida框架Hook native中的函数(1)
作者:H01mes撰写的这篇关于frida框架hook native函数的文章很不错,值得推荐和学习,也感谢原作者. 0x01 前言 关于android的hook以前一直用的xposed来hook j ...
- DexHunter在ART虚拟机模式下的脱壳原理分析
本文博客地址: http://blog.csdn.net/qq1084283172/article/details/78494620 DexHunter脱壳工具在Dalvik虚拟机模式下的脱壳原理分析 ...
- DexHunter在Dalvik虚拟机模式下的脱壳原理分析
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78494671 在前面的博客<DexHunter的原理分析和使用说明(一)&g ...
- 基于Saltstack、Artifactory打造传统模式下持续部署平台
一.持续部署 1. 现状 由于没有建立标准的持续部署流程,导致了版本管理混乱,制品管理混乱,上线持续时间长,上线测试覆盖不全面,业务流量上升后故障较多,排查复杂.运维.测试.开发人员每次版本迭代的时候 ...
- Dalvik模式下System.loadLibrary函数的执行流程分析
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78212010 Android逆向分析的过程中免不了碰到Android so被加固的 ...
- 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)
代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...
随机推荐
- 链表算法题之中等级别,debug调试更简单
文章简述 大家好,本篇是个人的第 5 篇文章 从本篇文章开始,分享关于链表的题目为中等难度,本次共有 3 道题目. 一,两数相加 1.1 题目分析 题中写到数字是按照逆序的方式存储,从进位的角度看,两 ...
- pytorch(03)tensor的操作
张量操作 一.张量的拼接 torch.cat() 功能:将张量按维度dim进行拼接,且[不会扩张张量的维度] tensors:张量序列 dim:要拼接的维度 torch.cat(tensors, di ...
- TiDB在更新版本的时候初始化Prometheus的配置文件失败
一.背景是更换版本了之后,按照正常扩容节点也会报错. 我们安装的TiDB版本是v4.0.0,因为环境还在试用阶段,所以会经常增删节点.原因是我们违背官方说明,强行用机械盘上了,跑不过单机的mysql, ...
- Apache配置 11. 访问控制-user_agent
(1)介绍 user_agent是指用户浏览器端的信息.比如你是用IE的还是Firefox浏览器的.有些网站会根据这个来调整打开网站的类型,如是手机的就打开wap,显示非手机的就打开PC常规页面. ( ...
- linux 安装FastFdfs
一.安装依赖软件和类库(安装前的准备) 依次执行以下命令: yum install gcc-c++ -y yum -y install zlib zlib-devel pcre pcre-devel ...
- IPFS挖矿原理介绍
随着近几年区块链行业迅速发展,虚拟货币交易机制逐渐成熟,作为「区块链新贵」的 IPFS渐渐走入广大投资者的视线. IPFS 与其激励层的运作原理是投资者们必须要了解的.所以今天我就来和大家讲讲 IPF ...
- Hadoop集群--linux虚拟机Hadoop安装与配置、克隆虚拟机
Hadoop集群 第四章 Hadoop安装与配置.克隆虚拟机 一.Hadoop安装与配置 1.将hadoop安装包通过Xftp传输到虚拟机的/software目录下 2.进入/software目录下, ...
- Java代码实现热部署
一.思路 0. 监听java文件最后修改时间,如果发生变化,则表示文件已经修改,进行重新编译 1. 编译java文件为 class文件 2. 通过手写类加载器,加载 class文件 ,创建对象 3. ...
- C++并发与多线程学习笔记--线程之间调度
condition_variable wait() notify_one notify_all condition_variable 条件变量的实际用途: 比如有两个线程A和B,在线程A中等待一个条件 ...
- 了解什么是Odoo,为二次开发做准备
什么是odoo odoo是由python语言开发,XML为模板的一体化业务解决方案系统,主要使用在企业资源规划(ERP)领域,还可以当做CMS系统,快速搭建自己博客.商城...系统 odoo前身是Op ...