42.安卓逆向2-补环境-unidbg安装和简单使用

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

内容参考于:图灵Python学院

工具下载:

链接:https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwd=zy89

提取码:zy89

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:41.安卓逆向2-frida hook技术-过firda检测(五)-利用ida分析app的so文件中frida检测函数过检测

unidbg可以实现单独跑某个so文件,简单说,Unidbg 就是一个 “让隐藏代码显形的工具”—— 不管这些代码藏在安卓还是苹果系统里,不管有没有加密,它都能搭一个 “假环境” 让代码运行起来,还能帮我们看清代码的每一步操作(它支持断点)。

下载:

https://github.com/zhkl0228/unidbg,打开网址后点击下图红框

然后点击下图红框进行下载

它是采用java语言和maven项目管理工具,所以就需要安装java和maven,这俩放到百度网盘了(jdk下载很麻烦,之前很简单,maven网络不好没法下),然后下图红框repository有点特殊,repository里面是java语言用到的一些代码(别人写好的代码,给我用的),repository要使用maven加载,加载方式是修改maven的文件,后面写了,jdk-8u202-windows-x64的安装有点特殊后面写了,其它的没特殊的了,正常安装就可以(最好把下面的内容都看完了再安装)

下载完需要对maven进行设置,下载完maven解压好,然后找到下图红框的文件

打开上图红框的文件,然后找到下图红框的内容

把上图红框中了目录替换成,下图红框 repository 解压位置就可以了

jdk安装注意下图红框,要点一下,这个jdk就是java语言

下图红框的两个,都根据上图点一下,然后点击下一步,不点的话安装的不全

然后设置环境变量

然后找到Path

然后点击新建

把java的bin目录和maven的bin目录添加进去,如下图

然后点击新建

创建一个JAVA_HOME,这个目录是jdk安装目录

jdk安装目录如下图

到这环境就配好了,打开控制台使用,mvn -v查看maven的版本,java -version查看java版本,如果都正常就说明搞好了

写代码的工具使用 IntelliJ IDEA,也放到百度网盘了,安装没啥要注意的,可以百度idea安装会有一大堆教学

unidbg导入idea中,点击打开

然后找到unidbg解压的目录,这个目录不要有中文,unidbg对中文支持的不好(有中文运行会报错)

然后点击信任

然后打开设置

然后设置maven,idea默认不采用我们的maven,所以要设置一下,注意第一次进入idea,它可能会下载一个maven,直接点击叉号取消下载(它下载完会把我们设置的maven覆盖,需要重新设置maven)

然后来到pom文件,点击同步,然后等待同步结束就可以了,这个过程有点慢

然后打开代码,如下图会有红色的错误,这是缺少jdk

然后再设置一下JDK,点击项目结构

选择我们上方安装的jdk

点击完确定就可以了,下方的SignUtil.java是unidbg作者给我们的实例

代码是从下图红框开始执行的(main方法开始执行)

然后直接全选,复制给ai大模型,让它解释,这里用的豆包

被ai解释过的代码

package com.anjuke.mobile.sign;  // 包名:类似文件夹,用于区分不同的类// 导入Unidbg框架的核心类:这些是别人写好的工具,我们直接拿来用
import com.github.unidbg.AndroidEmulator;  // 安卓模拟器核心类:模拟安卓手机的"大脑"
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;  // 模拟器建造者:用于"组装"一个模拟器
import com.github.unidbg.linux.android.AndroidResolver;  // 安卓系统库解析器:告诉模拟器去哪里找系统文件
import com.github.unidbg.linux.android.dvm.DalvikModule;  // Dalvik模块:用于加载SO文件(类似打开一个程序)
import com.github.unidbg.linux.android.dvm.DvmClass;  // 虚拟类:对应SO文件里的Java类
import com.github.unidbg.linux.android.dvm.StringObject;  // 虚拟字符串:Unidbg里的字符串(和Java字符串略有不同)
import com.github.unidbg.linux.android.dvm.VM;  // 虚拟机:模拟安卓的Java运行环境(类似手机里的Java引擎)
import com.github.unidbg.linux.android.dvm.jni.ProxyClassFactory;  // JNI代理工厂:处理Java和C语言的交互
import com.github.unidbg.linux.android.dvm.jni.ProxyDvmObject;  // 代理对象:把Java对象转换成C语言能识别的格式
import com.github.unidbg.memory.Memory;  // 内存管理:模拟手机的内存(存数据的地方)import java.io.File;  // 文件操作类:用于找到SO文件的位置
import java.io.IOException;  // 异常类:处理文件操作可能出现的错误(比如文件找不到)
import java.nio.charset.StandardCharsets;  // 字符集:用于把字符串转换成字节(计算机能看懂的0101)
import java.util.HashMap;  // 哈希表:一种键值对数据结构(类似字典,方便查找)
import java.util.Map;  // 映射接口:规定了哈希表等数据结构的基本操作/*** 签名工具类:专门用来调用SO文件里的签名方法* 背景:很多APP的签名算法藏在SO文件里(C/C++写的),直接看不懂,* 所以用Unidbg模拟手机环境,调用这个SO文件,拿到签名结果*/
public class SignUtil {// 安卓模拟器实例:声明一个模拟器变量(就像说"我要准备一个手机")// final表示这个变量一旦赋值就不能改了(防止被误操作)private final AndroidEmulator emulator;// SO库中的签名工具类:对应SO文件里的SignUtil类(就像找到了程序里的一个功能模块)private final DvmClass cSignUtil;// Dalvik虚拟机实例:安卓系统的Java虚拟机(手机里运行Java代码的核心)private final VM vm;/*** 构造方法:创建对象时自动执行的代码(相当于"开机初始化")* 作用:启动模拟器、加载系统环境、准备好SO文件*/public SignUtil() {// 1. 创建32位安卓模拟器// AndroidEmulatorBuilder.for32Bit():选择32位模式(因为很多手机SO是32位的)// setProcessName("com.anjuke.android.app"):告诉SO文件"我是安居客APP进程"// (有些SO会检查调用者是不是合法APP,填对进程名才能通过检查)// .build():完成建造,得到一个可用的模拟器emulator = AndroidEmulatorBuilder.for32Bit().setProcessName("com.anjuke.android.app").build();// 2. 获取模拟器的内存管理器(相当于拿到手机的"内存条"控制权)Memory memory = emulator.getMemory();// 3. 设置系统库解析器,指定安卓版本为API 23(即Android 6.0)// 为什么要指定版本?因为不同安卓版本的系统文件不一样,SO可能依赖特定版本的功能// 比如有些老SO只能在安卓6.0上运行,用高版本会出错memory.setLibraryResolver(new AndroidResolver(23));// 4. 创建Dalvik虚拟机(相当于在模拟器里启动Java运行环境)vm = emulator.createDalvikVM();// 5. 设置代理类工厂:处理JNI调用(SO是C写的,Java调用C需要通过JNI接口)// 这个工厂会自动模拟一些JNI的基础功能,让SO能正常调用Java方法vm.setDvmClassFactory(new ProxyClassFactory());// 6. 关闭详细日志:如果设为true,会打印很多调试信息(初学者可能看得眼花缭乱)vm.setVerbose(false);// 7. 加载目标SO文件(我们要调用的签名算法就在这个文件里)// 参数1:SO文件的路径(这里是示例路径,你需要改成自己的SO文件位置)// 参数2:false表示不自动调用SO的初始化方法(后面我们会手动调用,更灵活)DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/armeabi-v7a/libsignutil.so"), false);// 8. 从SO文件中找到我们需要的SignUtil类// 参数是类的完整路径(类似"文件夹/文件名"),必须和SO里定义的一致cSignUtil = vm.resolveClass("com/anjuke/mobile/sign/SignUtil");// 9. 手动调用SO的JNI_OnLoad方法(SO的初始化函数)// 相当于告诉SO:"环境准备好了,你可以初始化自己的资源了"dm.callJNI_OnLoad(emulator);}/*** 销毁模拟器资源* 为什么需要这个?因为模拟器会占用电脑的内存和CPU,用完不关掉会浪费资源* @throws IOException 处理关闭时可能出现的错误(比如资源被占用)*/public void destroy() throws IOException {emulator.close();  // 关闭模拟器,释放所有资源}/*** 调用SO库中的getSign0方法(核心功能)* 相当于"按下SO里的签名按钮,传入参数,得到结果"** @param p1  第一个参数(字符串类型)* @param p2  第二个参数(字符串类型)* @param map 第三个参数(键是字符串,值是字节数组)* @param p3  第四个参数(字符串类型)* @param i   第五个参数(整数类型)* @return 生成的签名字符串*/public String getSign0(String p1, String p2, Map<String, byte[]> map, String p3, int i) {// 方法签名:描述方法的参数类型和返回值类型(C语言需要明确知道这些才能正确调用)// 格式解读:(参数类型)返回值类型// Ljava/lang/String; → 字符串类型(L开头,;结尾,中间是类路径)// Ljava/util/Map; → Map类型// I → 整数类型// 整个签名表示:接收4个字符串和1个整数,返回一个字符串String methodSign = "getSign0(Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;I)Ljava/lang/String;";// 调用SO中SignUtil类的静态JNI方法// 步骤分解:// 1. cSignUtil:我们要调用的类// 2. callStaticJniMethodObject:调用静态的JNI方法,返回一个对象(这里是字符串)// 3. 参数列表://    - emulator:用哪个模拟器运行//    - methodSign:调用哪个方法(通过签名确定)//    - p1,p2:直接传字符串(Unidbg会自动转换成SO能识别的格式)//    - ProxyDvmObject.createObject(vm, map):把Java的Map转换成SO能识别的格式//    - p3,i:后续参数StringObject obj = cSignUtil.callStaticJniMethodObject(emulator, methodSign, p1, p2, ProxyDvmObject.createObject(vm, map), p3, i);// 把Unidbg的StringObject转换成普通Java字符串,返回给调用者return obj.getValue();}/*** 签名方法(对外提供的"接口")* 作用:接收用户传来的普通参数,处理后调用getSign0* synchronized:保证多线程调用时不会混乱(同一时间只有一个线程用这个方法)** @param paramMap 键值对参数(用户传的是String→String,需要转成String→byte[])* 其他参数和getSign0一样* @return 签名结果*/private synchronized String sign(String p1, String p2, Map<String, String> paramMap, String p3, int i) {// 创建一个新的Map,把String值转换成字节数组// 为什么要转?因为SO里的方法可能要求值是字节数组(计算机底层存储数据的形式)Map<String, byte[]> map = new HashMap<>();// 遍历用户传的paramMap,逐个转换for (String key : paramMap.keySet()) {// getBytes(StandardCharsets.UTF_8):把字符串按UTF-8编码转换成字节数组// (就像把中文翻译成二进制,让计算机能看懂)map.put(key, paramMap.get(key).getBytes(StandardCharsets.UTF_8));}// 调用实际和SO交互的方法,返回结果return getSign0(p1, p2, map, p3, i);}/*** 主方法:程序的入口(相当于"测试按钮")* 作用:演示如何使用上面的代码生成签名*/public static void main(String[] args) throws Exception {// 1. 准备测试参数:模拟实际使用时的参数// 创建一个Map,里面放两个键值对(a→b,b→b)Map<String, String> paramMap = new HashMap<String, String>() {{put("a", "b");put("b", "b");}};// 其他参数String p1 = "aa";  // 第一个参数示例String p2 = "bb";  // 第二个参数示例String p3 = "cc";  // 第四个参数示例int i = 10;        // 第五个参数示例// 2. 创建签名工具实例(这一步会执行上面的构造方法,启动模拟器、加载SO)SignUtil signUtil = new SignUtil();// 3. 调用签名方法,传入参数,得到签名结果String sign = signUtil.sign(p1, p2, paramMap, p3, i);// 4. 打印签名结果(在控制台显示生成的签名)System.out.println("sign=" + sign);// 5. 用完后销毁资源(释放内存,好习惯)signUtil.destroy();}}

点击下图红框可以运行

运行之后的效果图:


img

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

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

相关文章

数据结构与算法:哈希函数的应用及一些工程算法

前言这篇里的东西可以说了解了解就行了。一、哈希函数均匀性展示原本让deepseek转了一下老师的java代码&#xff0c;但发现复刻起来太麻烦了。又因为这个理解就好&#xff0c;竞赛不会有&#xff0c;所以就直接贴老师的java代码了……import java.security.MessageDigest; impo…

交叉编译ARM环境

ARM交叉编译 可以采用交叉编译工具链&#xff1a; sudo apt-get install aarch64-linux-gnu-gcc sudo apt-get install aarch64-linux-gnu-g sudo apt-get install gcc-arm-linux-gnueabi sudo apt-get install g-arm-linux-gnueabi 上面两个是64位&#xff0c;下面两个是…

算法思想 之 拓扑排序问题

欢迎拜访&#xff1a;雾里看山-CSDN博客 本篇主题&#xff1a;算法思想 之 拓扑排序问题 发布时间&#xff1a;2025.8.4 隶属专栏&#xff1a;算法 目录算法介绍核心原理适用场景实现步骤(Kahn 算法)例题课程表题目链接题目描述算法思路代码实现课程表 II题目链接题目描述算法思…

机器学习 入门——决策树分类

决策树是一种直观且强大的机器学习算法&#xff0c;适用于分类和回归任务。本文将全面介绍决策树分类的原理、实现、调优和实际应用。一、什么是决策树分类1.概念决策树分类是一种树形结构的分类模型&#xff0c;它通过递归地将数据集分割成更小的子集来构建决策规则。就像我们…

虚拟机中查看和修改文件权限

在虚拟机中管理文件权限是系统管理的重要部分&#xff0c;无论是在Linux还是Windows虚拟机中。下面我将详细介绍两种主要系统的权限管理方法。Linux虚拟机中的文件权限管理查看文件权限使用ls命令&#xff1a;ls -l 文件名输出示例&#xff1a;-rwxr-xr-- 1 user group 1024 Ju…

图像处理拉普拉斯算子

AI对话记录&#xff0c;还没有来得及仔细验证和推导&#xff0c;目前只是记录 当然可以&#xff01;我们来一步步推导拉普拉斯算子在旋转变换下保持不变的数学过程。这里以二维情况为例&#xff0c;最直观也最常见。&#x1f9ee; 拉普拉斯算子旋转不变性的推导&#xff08;二维…

React ahooks——副作用类hooks之useThrottleEffect

useThrottleEffect 是 ahooks 提供的节流版 useEffect&#xff0c;它在依赖项变化时执行副作用函数&#xff0c;但会限制执行频率。一、基本语法useThrottleEffect(effect: React.EffectCallback,deps?: React.DependencyList,options?: Options )二、参数详解2.1. effect (必…

【建模与仿真】融合画像约束和潜在特征的深度推荐算法

导读&#xff1a; 基于深度学习的推荐算法已成为推荐系统领域的研究趋势。然而&#xff0c;大多数现有工作仅考虑单一的用户与物品交互数据&#xff0c;限制了算法的预测性能。本文提出一种画像约束的编码方式&#xff0c;并融合隐因子模型中的潜在特征&#xff0c;丰富了推荐…

华为网路设备学习-26(BGP协议 二)路径属性

一、属性分类二、属性含义①公认必遵&#xff1a;所有BGP对等体 必须识别 且 在Update报文中携带1.Origin2.AS-Path3.Next hop②公认自决&#xff1a;所有BGP对等体 必须识别但可以不在Update报文中携带 1.Local-Preference2.ATOMIC_Aggregate③可选传递&#xff1a;所有BGP对…

从0搭建YOLO目标检测系统:实战项目+完整流程+界面开发(附源码)

文章目录一、前言二、专栏介绍三、已有系统介绍3.0 基于yolo通用目标检测系统&#xff08;手把手教你修改成为自己的检测系统&#xff09;3.1 基于yolov8柑橘检测系统3.2 基于yolov8舰船检测系统3.3 基于yolo11人脸检测系统3.4 基于yolov8无人机影像光伏板缺陷检测系统一、前言…

【测试】自动化测试工具基础知识及基本应用

下面详细介绍一些常用的自动化测试工具及其基本概念&#xff0c;并提供具体的示例代码&#xff0c;帮助你更好地理解和应用这些工具。1. 自动化测试的基本概念自动化测试是通过软件程序自动执行测试用例的过程。与手动测试相比&#xff0c;自动化测试能够提高测试效率、减少人为…

ArcGIS的字段计算器生成随机数

在ArcGIS的字段计算器中使用Python脚本生成0-100的随机数&#xff0c;可以按照以下步骤操作&#xff1a; 打开属性表&#xff0c;选择要计算的字段打开字段计算器选择"Python"解析器勾选"显示代码块"在"预逻辑脚本代码"中输入以下代码在下方表达…

【前端:Html】--1.1.基础语法

目录 1.HTML--简介 2.HTML--编译器 步骤一:启动记事本 步骤二:用记事本来编辑 HTML 步骤三:保存 HTML 步骤四:在浏览器中运行 HTML 3.HTML--基础 3.1.HTML声明--!DOCTYPE 3.2.HTML 标题--h1 3.3.HTML 段落--p 3.3.1. 水平线--hr 3.3.2.换行符--br 3.3.3.固定格式…

FreeSWITCH 简单图形化界面46 - 收集打包的一些ASR服务

FreeSWITCH 简单图形化界面46 - 收集打包的一些ASR服务 0、一个fs的web配置界面预览1、docker地址2、使用2.1 下载2.2 运行 3、例子3.1 下载3.2 启动3.3 编译mod_audio_fork或者mod_audio_stream模块使用3.4 编写呼叫路由和呼叫脚本呼叫路由呼叫脚本 3.5 esl捕获识别结果3.6 其…

20250805问答课题-实现TextRank + 问题分类

textRank的工具包实现其他可能的实现方法&#xff0c;对比结果查找分类的相关算法 目录 1. 关键词提取TF-IDF TextRank 1.1. TF-IDF算法 1.2. TextRank算法 1.3. 双算法提取关键词 2. 问题分类 2.1. 预处理 2.2. 获取BERT向量 2.3. 一级标签预测 2.4. 二级标签预测 3…

Memcached缓存与Redis缓存的区别、优缺点和适用场景

一、核心差异概述特性MemcachedRedis​数据结构​简单键值存储丰富数据结构&#xff08;String/Hash/List/Set等&#xff09;​持久化​不支持支持RDB和AOF两种方式​线程模型​多线程单线程&#xff08;6.0支持多线程I/O&#xff09;​内存管理​Slab分配LRU淘汰多种淘汰策略&…

Git简易教程

Git教程 VCS Version Control System版本控制系统 配置用户名邮箱 配置用户名和邮箱 git config --global user.name mihu git config --global user.email aaabbb.com初始化仓库 从项目仓库拉 git clone [项目地址]新建文件夹之后 git init提交操作 提交到仓库 git add . #把…

关于Web前端安全之XSS攻击防御增强方法

仅依赖前端验证是无法完全防止 XSS的&#xff0c;还需要增强后端验证&#xff0c;使用DOMPurify净化 HTML 时&#xff0c;还需要平衡安全性与业务需求。一、仅依赖前端验证无法完全防止 XSS 的原因及后端验证的重要性1. 前端验证的局限性前端验证&#xff08;如 JavaScript 输入…

消息系统技术文档

消息系统技术文档 概述 本文档详细说明了如何在现有的LHD通信系统中添加自己的消息类型&#xff0c;包括消息的发送、接收、解析和处理的完整流程。 系统架构 消息流程架构图 #mermaid-svg-My7ThVxSl6aftvWK {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博舆情数据可视化分析-热词情感趋势树形图

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解微博舆情数据可视化分析-热词情感趋势树形图…