基于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.隔离,客户端 ...
随机推荐
- 653. 两数之和 IV - 输入 BST + HashSet
653. 两数之和 IV - 输入 BST 题目描述 题解分析 最简单的方法就是遍历整棵树,找出所有可能的组合,判断是否存在和为 kk 的一对节点.现在在此基础上做一些改进. 如果存在两个元素之和为 ...
- 简单的ssm练手联手项目
简单的ssm练手联手项目 这是一个简单的ssm整合项目 实现了汽车的品牌,价格,车型的添加 ,修改,删除,所有数据从数据库中拿取 使用到了jsp+mysql+Mybatis+spring+spring ...
- 利用xslt与xml实现具体字段字母的大小写转换
定义一个全局的变量 <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" ...
- GET跟POST的区别
GET.POST的区别: 一.GET在浏览器后退时候,可以还原表单大部分数据,POST当浏览器后退时,表单数据将会丢失 二.GET产生的 URL 请求地址可以 Bookmark,而POST不可以 三. ...
- 一键获取linux内存、cpu、磁盘IO等信息脚本编写,及其原理详解
更多linux知识,请关注公众号:一口Linux 一.脚本 今天主要分享一个shell脚本,用来获取linux系统CPU.内存.磁盘IO等信息. #!/bin/bash # 获取要监控的本地服务器IP ...
- 【LeetCode】2020-04 每日一题
8. 字符串转换整数 (atoi)(中等) [分类]:模拟.正则表达式 [题解]: 解法1:直接模拟,但是在判断INT_MAX和INT_MIN上需要注意,因为直接判断会超出范围,所以可以将式子转换一下 ...
- 配置docker的pdflatex环境
技术背景 Latex在文档撰写方面是不可或缺的工具,尤其是在写文章方面,是必须要用到的文字排版工具.但是latex的环境部署并不是一个特别人性化的操作,尤其是在各种不同的平台上操作是完全不一样的,还经 ...
- C语言之动态内存管理
C语言之动态内存管理 大纲: 储存器原理 为什么存在动态内存的开辟 malloc() free() calloc() realloc() 常见错误 例题 柔性数组 零(上).存储器原理 之前我们提到了 ...
- 最短路径(Dijskra算法)
声明:图片及内容基于:https://www.bilibili.com/video/BV16C4y1H7Zc?from=articleDetail 最短路径 Dijkstra算法 原理 数据结构 核心 ...
- 全网最详细的Linux命令系列-less命令
less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more 更加的有弹性.在 more 的时候,我们并没有办法向前面翻 ...