FART 自动化脱壳框架一些 bug 修复记录

news2025/6/2 7:04:27

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/

open() 判断不严谨

https://github.com/CYRUS-STUDIO/FART/blob/master/fart10/art/runtime/art_method.cc

比如:

int dexfilefp = open(dex_path.c_str(), O_RDONLY);
if (dexfilefp > 0) {
    close(dexfilefp);
}

这个判断条件其实是不严谨的,导致 if 中 的 close(dexfilefp); 一直没有执行。

open() 的返回值语义是:

  • 成功时:返回一个非负整数(即 >= 0),它是打开的文件描述符。

  • 失败时:返回 -1

正确的判断方式应该是:

if (fp >= 0) {
    // 成功打开
} else {
    // 打开失败,打印错误信息
    LOG(ERROR) << "open dex file failed";
}

mkdir failed errno: 13

FART 中通过 mkdir 函数在 sdcard 上创建 dump 文件存放目录,但是这样必须 app 拥有存储卡读写权限。不然 mkdir 会执行失败。

下面时一个 frida 脚本,调用系统 的 mkdir 函数创建目录

function mkdir(path) {
    const libc = Module.findExportByName(null, "mkdir");
    if (!libc) {
        console.error("[-] Cannot find mkdir symbol.");
        return;
    }

    const mkdirNative = new NativeFunction(libc, 'int', ['pointer', 'int']);

    const pathStr = Memory.allocUtf8String(path);
    const mode = 0o777; // 权限

    const result = mkdirNative(pathStr, mode);
    if (result === 0) {
        console.log("[+] mkdir success:", path);
    } else {
        const errnoLocation = Module.findExportByName(null, "__errno");
        if (errnoLocation) {
            const errnoPtr = new NativeFunction(errnoLocation, 'pointer', []);
            const errnoValue = Memory.readU32(errnoPtr());
            console.error("[-] mkdir failed errno:", errnoValue);
        } else {
            console.error("[-] mkdir failed");
        }
    }
}

调用 mkdir 创建目录 /sdcard/fart/com.cyrus.example

mkdir("/sdcard/fart/com.cyrus.example");

结果如下:

[Remote::com.cyrus.example]-> mkdir("/sdcard/fart/com.cyrus.example");
[-] mkdir failed errno: 13

[-] mkdir failed errno: 13 表示 Permission denied(权限被拒绝)。

常见的 errno 错误码:

errno 值含义
EEXIST目录已经存在
EACCES权限不足
ENOENT上级目录不存在
ENAMETOOLONG路径太长
ENOSPC没有磁盘空间或 inode

errno 定义参考:https://cs.android.com/android/platform/superproject/+/android15-qpr2-release:external/musl/arch/mips64/bits/errno.h;l=13?q=EACCES

解决方案:把 dump 路径改为:/sdcard/Android/data/<packageName>/fart

该目录无需动态申请存储权限,也不受 MANAGE_EXTERNAL_STORAGE 限制。

art_method.cc 中增加以下方法,创建目录并并打印日志

//add 创建目录
bool ensure_dir_exists(const std::string& path) {
    int res = mkdir(path.c_str(), 0777);
    if (res == 0 || errno == EEXIST) {
        return true;
    } else {
        LOG(ERROR) << "mkdir failed: " << path << ", errno=" << errno << ", " << errno;
        return false;
    }
}

修改 dumpDexFileByExecute 和 dumpArtMethod 方法中 dump 文件存放路径

// 创建目录:/sdcard/Android/data/<packageName>/fart
std::string base_dir = "/sdcard/Android/data/";
std::string app_dir = base_dir + szProcName;
std::string fart_dir = app_dir + "/fart";

ensure_dir_exists(app_dir);
ensure_dir_exists(fart_dir);

// 保存 dex 文件
std::string dex_path = fart_dir + "/" + std::to_string(size_int) + "_dex_file.dex";
// 保存 class 列表
std::string class_list_path = fart_dir + "/" + std::to_string(size_int) + "_class_list.txt";

dumpArtMethod 方法中 CodeItem 的保存路径也要修改

// 保存 CodeItem
std::string ins_path = fart_dir + "/" + std::to_string(size_int) + "_ins_" + std::to_string(tid) + ".bin";

修改完成后重新编译刷机。参考:移植 FART 到 Android 10 实现自动化脱壳

即使 app 没有存储卡读写权限也能正常 dump 了。

word/media/image1.png

跳过 Android 编译构建阶段的 dump 调用

在 Android 编译构建阶段的 dex2oatd 工具执行时 调用了 art_method.cc 中的方法,导致出现下面的日志

dex2oatd E 05-27 19:26:24  7330  7330 art_method.cc:151] mkdir failed: /sdcard/Android/data/out/soong/host/linux-x86/bin/dex2oatd, errno=2, 2
dex2oatd E 05-27 19:26:24  7330  7330 art_method.cc:151] mkdir failed: /sdcard/Android/data/out/soong/host/linux-x86/bin/dex2oatd/fart, errno=2, 2
dex2oatd E 05-27 19:26:24  7330  7330 art_method.cc:234] [dumpDexFileByExecute] /sdcard/Android/data/out/soong/host/linux-x86/bin/dex2oatd/fart/4376620_dex_file_execute.dex open failed, fp=-1
dex2oatd E 05-27 19:26:24  7330  7330 art_method.cc:151] mkdir failed: /sdcard/Android/data/out/soong/host/linux-x86/bin/dex2oatd, errno=2, 2
dex2oatd E 05-27 19:26:24  7330  7330 art_method.cc:151] mkdir failed: /sdcard/Android/data/out/soong/host/linux-x86/bin/dex2oatd/fart, errno=2, 2

在 dump 前加上判断是否运行在 Android 环境

//add 跳过 Android 编译构建阶段的 dex2oatd 工具执行时的调用
bool isValidAndroidApp(const char* procName) {
    // 排除 host 工具,例如 dex2oat、dex2oatd、aapt2 等
    return procName != nullptr &&
           strstr(procName, "/") == nullptr &&         // 不应该包含路径
           strstr(procName, "dex2oat") == nullptr &&   // 排除 dex2oat/dex2oatd
           strstr(procName, "soong") == nullptr;       // 排除构建系统相关路径
}

//add
extern "C" void dumpDexFileByExecute(ArtMethod* artmethod) REQUIRES_SHARED(Locks::mutator_lock_) {
        ...
        
        if (szProcName[0] == '\0') {
            LOG(WARNING) << "[dumpDexFileByExecute] 获取进程名失败:" << artmethod->PrettyMethod();
            return;
        }

        if (!isValidAndroidApp(szProcName)) {
            LOG(WARNING) << "[dumpDexFileByExecute] 当前进程 " << szProcName << " 非法,跳过 dex dump";
            return;
        }

        ...
}

//add
extern "C" void dumpArtMethod(ArtMethod* artmethod) REQUIRES_SHARED(Locks::mutator_lock_) {
        ...

        if (szProcName[0] == '\0') {
            LOG(WARNING) << "[dumpArtMethod] 获取进程名失败:" << artmethod->PrettyMethod();
            return;
        }

        if (!isValidAndroidApp(szProcName)) {
            LOG(WARNING) << "[dumpArtMethod] 当前进程 " << szProcName << " 非法,跳过 dex dump";
            return;
        }

        ...
}

完整源码

开源地址:https://github.com/CYRUS-STUDIO/FART

相关文章:

  • FART 自动化脱壳框架简介与脱壳点的选择

  • FART 主动调用组件设计和源码分析

  • 移植 FART 到 Android 10 实现自动化脱壳

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2393554.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Flask实现豆瓣Top250电影可视化

项目截图 概述 该项目旨在对豆瓣Top 250电影进行全面的数据分析&#xff0c;使用了Python爬虫、Flask框架进行开发&#xff0c;并采用了Echarts进行数据可视化以及WordCloud进行词云分析。应用展示了多个功能&#xff0c;如电影列表、评分分布、词频统计和团队信息。 主要功能…

More SQL(Focus Subqueries、Join)

目录 Subqueries Subqueries That Return One Tuple Subqueries and Self Connection The IN Operator The Exists Operator The Operator ANY The Operator ALL Union, Intersection, and Difference&#xff08;交并差&#xff09; Bag Semantics Controlling Dupl…

从图像处理到深度学习:直播美颜SDK的人脸美型算法详解

在直播的镜头前&#xff0c;每一位主播都希望自己“光彩照人”。但在高清摄像头无死角的审视下&#xff0c;哪怕是天生丽质&#xff0c;也难免需要一点技术加持。于是&#xff0c;美颜SDK应运而生&#xff0c;成为直播平台提升用户粘性和视觉体验的重要工具。 尤其是在“人脸美…

zTasker一款Windows自动化软件,提升效率:大小仅有10MB,免费无广告

一、zTasker是什么&#xff1f; zTasker是一款发布于2023年9月的免费无广告工具&#xff0c;专为Windows用户打造。它以仅8MB的轻量体积、极低资源占用&#xff08;内存消耗不足10MB&#xff09;和秒级启动速度脱颖而出&#xff0c;堪称“任务计划程序的终极强化版”。无论是定…

最大流-Ford-Fulkerson增广路径算法py/cpp/Java三语言实现

最大流-Ford-Fulkerson增广路径算法py/cpp/Java三语言实现 一、网络流问题与相关概念1.1 网络流问题定义1.2 关键概念 二、Ford-Fulkerson算法原理2.1 核心思想2.2 算法步骤 三、Ford-Fulkerson算法的代码实现3.1 Python实现3.2 C实现3.3 Java实现 四、Ford-Fulkerson算法的时间…

【测试】Bug和用例

软件测试贯穿于软件的整个⽣命周期 软件测试的⽣命周期是指测试流程&#xff0c;这个流程是按照⼀定顺序执⾏的⼀系列特定的步骤&#xff0c;去保证产品质量符合需求。在软件测试⽣命周期流程中&#xff0c;每个活动都按照计划的系统的执⾏。每个阶段有不同的⽬标和交付产物 Bu…

鸿蒙OS的5.0.1.120版本体验怎么样?

点击上方关注 “终端研发部” 设为“星标”&#xff0c;和你一起掌握更多数据库知识 越来越是好用了&#xff0c;之前是凑合能用&#xff0c;现在是大多能用。 我朋友的mate30PRO和PuraX一起用&#xff0c;新系统确实满足我90%以上的需求 一个系统适配一款机型&#xff0c;是要…

使用ssh-audit扫描ssh过期加密算法配置

使用ssh-audit扫描ssh过期加密算法配置 安装检查ssh的加密算法配置修改ssh的加密算法配置 安装 # pip3安装ssh-audit pip3 instal ssh-audit检查ssh的加密算法配置 # 检查ssh的配置 ssh-audit 192.168.50.149修改ssh的加密算法配置 # 查看ssh加密配置文件是否存在 ls /etc/c…

Java+Playwright自动化-2-环境准备与搭建-基于Maven

1.简介 上一章中已经讲如何通过引入jar包来搭建JavaPlaywright自动化测试环境&#xff0c;这一种是比较老的方法&#xff0c;说白了就是过时的老古董&#xff0c;但是我们必须了解和知道&#xff0c;其实maven搭建无非也就是下载引入相关的jar包&#xff0c;只不过相比之下是简…

由sigmod权重曲线存在锯齿的探索

深度学习的知识点&#xff0c;一般按照执行流程&#xff0c;有 网络层类型&#xff0c;归一化&#xff0c;激活函数&#xff0c;学习率&#xff0c;损失函数&#xff0c;优化器。如果是研究生上课学的应该系统一点&#xff0c;自学的话知识点一开始有点乱。 一、激活函数Sigmod…

二、OpenCV图像处理-图像处理

目录 1、连通性 2、形态学操作 2.1腐蚀和膨胀 2.2开闭运算 2.3礼帽和黑帽 2.4总结 3、图像平滑 3.1图像噪声 3.2均值滤波 3.3高斯滤波 3.4中值滤波 3.5总结 4、直方图 4.1直方图的原理与显示 4.2掩膜的应用 4.3直方图均衡化 4.4自适应均衡化 4.5总结 5、边缘…

UPS的工作原理和UPS系统中旁路的作用

UPS&#xff08;不间断电源&#xff09;根据工作原理和适用场景的不同&#xff0c;主要分为以下三种类型&#xff0c;每种类型的特点和适用场景如下&#xff1a; 1. 后备式UPS&#xff08;Offline/Standby UPS&#xff09; 工作原理&#xff1a; 正常供电时&#xff0c;负载直接…

麒麟系统 Linux(aarch64处理器)系统java项目接入海康SDK问题

1. 麒麟系统部署海康摄像头时的 JNA 链接错误&#xff0c; 海康提供的jna sdk版本太低&#xff0c;需升级版本4.5及以上&#xff0c;把集成的Structure 替换成以下类 public class SDK_Structure extends Structure {protected List<String> getFieldOrder() {List<St…

Python图片格式批量转换器教程

&#x1f4da; 前言 编程基础第一期《11-30》-- 在图像处理工作中&#xff0c;我们经常需要将大量图片从一种格式转换为另一种格式。本教程将介绍如何使用Python的Pillow库开发一个简单但功能强大的图片格式批量转换器&#xff0c;帮助你高效处理图片格式转换任务。 目录 &…

从公开到私密:重新思考 Web3 的数据安全

去中心化存储是 Web3 的基石之一&#xff0c;使用户和应用能够在无需依赖中心化服务商的情况下存储数据。但自由也带来了一个重大挑战&#xff1a;数据安全。在一个无许可的世界中&#xff0c;如何确保用户文档、游戏资产或 AI 数据集等敏感内容是私密的、可控访问的&#xff0…

计算机网络常见体系结构、分层必要性、分层设计思想以及专用术语介绍

计算机网络体系结构 从本此开始&#xff0c;我们就要开始介绍有关计算机网络体系结构的知识了。内容包括&#xff1a; 常见的计算机网络体系结构 计算机网络体系结构分层的必要性 计算机网络体系结构的设计思想 举例说明及专用术语 计算机网络体系结构是计算机网络课程中…

接口自动化测试用例的编写方法

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 phpunit 接口自动化测试系列 Post接口自动化测试用例 Post方式的接口是上传接口&#xff0c;需要对接口头部进行封装&#xff0c;所以没有办法在浏览器下直接调…

基于SpringBoot的商家销售管理网站的设计与实现

湖南软件职业技术大学 本科毕业设计(论文) 设计(论文)题目 基于SpringBoot的商家销售管理网站的设计与实现 学生姓名 学生学号 所在学院 专业班级 校内指导教师 企业指导教师 毕业设计(论文)真实性承诺及声明 学生对毕业设计(论文)真实性承诺 本人郑重声明:所提交的毕…

word中表格拉不动以及插入图片有间距

1、word中表格插入图片始终有间隙&#xff0c;怎么调表格高度和宽度都消除不了间隙&#xff0c;如下所示&#xff1a; 可以在表布局—单元格边距—修改上下左右边距为0即可 2、经过上述调整后左右没有间隔了&#xff0c;但图片上下有间隔&#xff0c;直觉是行距问题&#xff0c…

【Java学习笔记】接口

接口 应用场景引出 一、接口的介绍 1. 接口的基本结构 interface 接口名{属性抽象方法 }引出关键字&#xff1a;implements 2. 子类实现接口 class a implements 接口名{}3. 接口中的属性说明&#xff1a;属性默认是public static final修饰的 &#xff08;1&#xff09;f…