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

内容参考于:图灵Python学院

工具下载:

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

提取码:zy89

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

上一个内容:28.安卓逆向2-frida hook技术-逆向os文件(一)

ida不同版本反编译的伪代码有点差异,下方是ida7.0版本,它反编译的伪代码没有ida9.0好

ida9.0安装看这个大哥写的:https://mrx.hk/posts/f66fa9e6643dec79c46f35361986b601

上一个内容通过找sign参数,发现它的加密是在so文件中,然后又去找了so文件,然后so文件使用c/++写的,然后就需要一个工具对它进行逆向,工具叫做IDA,接下来就开始下载和使用ida

地址:https://52pojie.cn/thread-1874203-1-1.html

注意要下载,后面带Hex-Rays的,这表示有Hex-Rays插件,这个插件可以生成伪代码

下载完后双击下图红框

双击之后,然后点击Next

然后继续Next

继续Next

Password是qY2jts9hEJGy,继续Next

然后选择一个安装目录,选择完点击Next

然后创建桌面图标,然后Next

然后Install

等待安装完成

安装完成,勾选LaunchIDA然后点击Finish

 它的图标,32-bit是用来分析32位的so文件,64位的是用来分析64位的so文件,如果用32位的查看64位的会打不开

然后点击下图红框

点击Finish后

image-20250713163716380

然后点击ok

然后点击go

然后就打开了

然后把so文件拖到上图的窗口中后,如下图直接点ok,用默认的就可以

然后就把文件反编译好了

然后按空格可以展示成下图的样子

如果上图中的窗口不小关闭了,可以在下图位置找

如果窗口乱了

可以点击下图Reset desktop位置恢复

上一个内容中调用了wtf文件中的getSign方法,接下来找一下这个方法,鼠标左键单机下图红框位置

然后按CTRL+F,就会出现下图红框的东西

然后输入getSign,如下图就找到了getSign方法

然后双击下图红框位置就能跳转过去了

双击之后进入getSign方法里

然后按F5,就给它编程成了,c语言代码,注意如果下载的ida没有 Hex-Rays 插件这一步没办法做到,所以一定要下载带 Hex-Rays 插件的

然后开始分析,分析直接给ai,让ai写分析,分析完注释,这里的ai用的豆包,也可以使用ai把下方的代码还原成Python代码

/*** JNI函数:Java_cn_thecover_lib_common_manager_SignManager_getSign* 功能:生成API请求签名(带入参数:account="accccc", token="", timestamp="1235")* 核心逻辑:双重MD5加密 + 参数拼接,最终返回大写签名*/
jstring __fastcall Java_cn_thecover_lib_common_manager_SignManager_getSign(JNIEnv *env, jclass obj, jstring account, jstring token, jstring timestamp)
{// 输入参数固定值:// account = "accccc"(用户账号)// token = ""(令牌,此处为空字符串)// timestamp = "1235"(时间戳)jstring v5; // 最终返回的签名字符串_jstring *v6; // 从Java获取的应用签名(假设为"appSecret123")char *v7; // 应用签名的UTF-8格式("appSecret123")std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char> >::value_type *__rhs; // 账号的UTF-8值("accccc")char *v9; // 令牌的UTF-8值("")char *v10; // 时间戳的UTF-8值("1235")JNIEnv *v11; // 暂存JNI环境指针const char *v12; // 最终签名的C字符串_jmethodID *v13; // 静态方法getAppSign的ID_jclass *v14; // Java类LogShutDown的引用jstring v15; // 暂存timestamp参数("1235")jstring v16; // 暂存token参数("")jstring v17; // 暂存account参数("accccc")_jstring *v18; // 临时生成的Java字符串char v19; // 待加密字符串的临时副本char v20; // 第二次MD5加密的结果std::__ndk1::string result; // 最终签名(第二次MD5大写结果)std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char> > __lhs; // 第一步拼接结果std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char> > v23; // 第二步拼接结果std::__ndk1::string encrypt; // 最终待加密的完整字符串char v25; // 应用签名的临时存储("appSecret123")char v26; // 应用签名的MD5结果(假设为"9A0A82F06B516634C4394A7E9072264D")std::__ndk1::string appsignMd5result; // 应用签名MD5的最终值("9A0A82F06B516634C4394A7E9072264D")JNIEnv *enva; // 暂存JNI环境指针__int64 v29; // 栈保护Cookie(防溢出)// 保存栈Cookie(用于函数结束时校验栈完整性)v29 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);enva = env;v17 = account;v16 = token;v15 = timestamp;// 步骤1:查找Java类LogShutDown(用于获取应用签名)v14 = (_jclass *)_JNIEnv::FindClass(env, "cn/thecover/lib/common/utils/LogShutDown");if (v14) // 类查找成功{// 步骤2:获取类中静态方法getAppSign()的ID(方法签名:()Ljava/lang/String;)v13 = (_jmethodID *)_JNIEnv::GetStaticMethodID(enva, v14, "getAppSign", "()Ljava/lang/String;");if (v13) // 方法ID获取成功{// 步骤3:调用静态方法获取应用签名(假设返回"appSecret123")v6 = (_jstring *)_JNIEnv::CallStaticObjectMethod(enva, v14, v13);// 步骤4:将Java字符串转为C的UTF-8格式("appSecret123")v7 = (char *)_JNIEnv::GetStringUTFChars(enva, v6, 0LL);// 步骤5:将应用签名存入C++字符串(v25 = "appSecret123")std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::basic_string<decltype(nullptr)>(&v25, v7);// 步骤6:对应用签名做MD5加密(v26 = MD5("appSecret123") = "9A0A82F06B516634C4394A7E9072264D")md5((const std::__ndk1::string *)&v25, (std::__ndk1::string *)&v26);// 步骤7:MD5结果转大写(保持"9A0A82F06B516634C4394A7E9072264D",因MD5本身大写)toUpperCase(&v26);// ######################## ida问题说明 ########################// 这里应该有一步向 appsignMd5result 中添加v26的数据,这应该由于ida的问题给省略了,这个是问ai没有看到appsignMd5result赋值// 到后面 appsignMd5result 怎么就等于 9A0A82F06B516634C4394A7E9072264D了// 然后结合这里的代码很奇怪,上方调用getAppSign方法得到了一个数据,然后进行了MD5加密,加密完紧着就调用basic_string释放了内存// 并没有使用这个数据,这就很不正常,这里就可能在代码编译的时候进行了优化,然后ida反编译的时候就出错了// ######################## ida问题说明 ########################// 步骤8:释放临时变量(v25、v26完成使命)std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&v26);std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&v25);// 步骤9:将输入参数转为C的UTF-8格式__rhs = (std::__ndk1::basic_string::value_type *)_JNIEnv::GetStringUTFChars(enva, v17, 0LL); // __rhs = "accccc"(account)v9 = (char *)_JNIEnv::GetStringUTFChars(enva, v16, 0LL); // v9 = ""(token)v10 = (char *)_JNIEnv::GetStringUTFChars(enva, v15, 0LL); // v10 = "1235"(timestamp)// ######################## 核心拼接过程 ########################// 规则:appsignMd5result(应用签名MD5) + account + token + timestamp// 拼接步骤1:appsignMd5result + account// 输入:appsignMd5result = "9A0A82F06B516634C4394A7E9072264D",__rhs = "accccc"// 输出:__lhs = "9A0A82F06B516634C4394A7E9072264Daccccc"std::__ndk1::operator+<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>(&__lhs, &appsignMd5result, __rhs);// 拼接步骤2:上一步结果 + token// 输入:__lhs = "9A0A82F06B516634C4394A7E9072264Daccccc",v9 = ""// 输出:v23 = "9A0A82F06B516634C4394A7E9072264Daccccc"(因token为空,结果不变)std::__ndk1::operator+<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>(&v23, &__lhs, (const unsigned __int8 *)v9);// 拼接步骤3:上一步结果 + timestamp// 输入:v23 = "9A0A82F06B516634C4394A7E9072264Daccccc",v10 = "1235"// 输出:encrypt = "9A0A82F06B516634C4394A7E9072264Daccccc1235"(最终待加密字符串)std::__ndk1::operator+<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>(&encrypt, &v23, (const unsigned __int8 *)v10);// ######################## 拼接结束 ########################// 步骤10:释放拼接过程的临时变量(__lhs、v23完成使命)std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&v23);std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&__lhs);// 步骤11:将待加密字符串复制到临时变量(v19 = encrypt = "9A0A82F06B516634C4394A7E9072264Daccccc1235")std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::basic_string(&v19, &encrypt);// 步骤12:对完整字符串做第二次MD5加密(v20 = MD5("9A0A82F06B516634C4394A7E9072264Daccccc1235"))md5((const std::__ndk1::string *)&v19, (std::__ndk1::string *)&v20);// 步骤13:第二次MD5结果转大写(最终签名值)toUpperCase(&v20);// 步骤14:释放临时变量(v19、v20完成使命)std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&v20);std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&v19);// 步骤15:释放输入参数的UTF-8资源(避免内存泄漏)_JNIEnv::ReleaseStringUTFChars(enva, v17, (const char *)__rhs); // 释放account_JNIEnv::ReleaseStringUTFChars(enva, v16, v9); // 释放token_JNIEnv::ReleaseStringUTFChars(enva, v15, v10); // 释放timestamp_JNIEnv::ReleaseStringUTFChars(enva, v6, v7); // 释放应用签名// 步骤16:删除JNI本地引用(释放类和方法的引用)_JNIEnv::DeleteLocalRef(enva, &v6->0);_JNIEnv::DeleteLocalRef(enva, &v14->0);// 步骤17:准备返回结果(result = 最终签名值)v11 = enva;v12 = (const char *)std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::c_str(&result);// 步骤18:将C字符串转为Java的jstring类型v18 = (_jstring *)_JNIEnv::NewStringUTF(v11, v12);// 步骤19:释放剩余临时变量std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&result);std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&encrypt);v5 = (jstring)std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>>::~basic_string(&appsignMd5result);}else // 方法ID获取失败{_JNIEnv::ExceptionDescribe(enva); // 打印异常_JNIEnv::ExceptionClear(enva); // 清除异常状态__android_log_print(4LL, "theCover", "find md5mtd error"); // 日志提示方法查找失败v5 = (jstring)_JNIEnv::NewStringUTF(enva, "wtf"); // 返回错误标识v18 = v5;}}else // 类查找失败{__android_log_print(4LL, "theCover", "find class error"); // 日志提示类查找失败_JNIEnv::ExceptionDescribe(enva);_JNIEnv::ExceptionClear(enva);v5 = (jstring)_JNIEnv::NewStringUTF(enva, "wtf"); // 返回错误标识v18 = v5;}// 校验栈完整性(若栈未被破坏,返回v18;否则返回异常值)if (*(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40) == v29)v5 = v18;return v5; // 返回最终签名(或错误标识"wtf")
}

到这就把这个方法分析了,然后接下来就开始使用fridahook它们


img

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

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

相关文章

[析]Deep reinforcement learning for drone navigation using sensor data

Deep reinforcement learning for drone navigation using sensor data 基于传感器数据的无人机导航深度强化学习方法 评价&#xff1a;MDP无记忆性&#xff0c;使用LSTM补足缺点。PPO解决新旧策略差距大的问题。 对于环境中的障碍物&#xff0c;设置增量课程&#xff0c;障碍…

SpringBoot项目启动报:java: 找不到符号 符号: 变量 log 的解决办法

问题&#xff1a;使用IDEA创建SpringBoot项目&#xff0c;在项目中使用 Slf4j 注解引入log日志后&#xff0c;启动项目&#xff0c;报如下错误&#xff1a;原因&#xff1a;网上找了很多博文&#xff0c;说是lombook依赖没有引入&#xff0c;但是我的pom.xml中已经引入 lombook…

HTML基础知识 二(创建容器和表格)

HTML 基础知识&#xff1a;创建容器和表格&#xff08;补充版&#xff09;HTML&#xff08;超文本标记语言&#xff09;是构建网页的基础。容器元素用于组织内容&#xff0c;表格用于展示结构化数据&#xff0c;两者都是网页设计中不可或缺的部分。一、HTML 容器元素容器元素就…

多目标优化|HKELM混合核极限学习机+NSGAII算法工艺参数优化、工程设计优化,四目标(最大化输出y1、最小化输出y2,y3,y4),Matlab完整源码

基本介绍 1.HKELM混合核极限学习机NSGAII多目标优化算法&#xff0c;工艺参数优化、工程设计优化&#xff01;&#xff08;Matlab完整源码和数据&#xff09; 多目标优化是指在优化问题中同时考虑多个目标的优化过程。在多目标优化中&#xff0c;通常存在多个冲突的目标&#x…

【AI智能体】Dify 基于知识库搭建智能客服问答应用详解

目录 一、前言 二、Dify 介绍 2.1 Dify 核心特点 三、AI智能体构建智能客服系统介绍 3.1 基于AI智能体平台搭建智能客服系统流程 3.1.1 需求分析与场景设计 3.1.2 选择合适的AI智能体平台 3.1.3 工作流编排与调试 3.1.4 系统集成与发布 3.2 使用AI智能体构建智能客服系…

事务~~~

1、四大特性&#xff1a;A 原子性&#xff1a;对数据的一组操作&#xff0c;要么执行成功&#xff0c;要么不执行C 一致性&#xff1a;事务前后的状态要保持一致&#xff0c;可以理解为数据的一致性I 隔离性&#xff1a;多个事务之间是隔离的&#xff0c;互不影响D 持久性&…

【Linux编译】./build.sh: line 17: $‘\r‘: command not found

文章目录0.运行编译脚本遇到问题&#xff1a;方法 1&#xff1a;使用 dos2unix&#xff08;推荐&#xff09;1. 安装 dos2unix2. 递归转换整个目录方法 2&#xff1a;使用 sed&#xff08;无需安装额外工具&#xff09;方法 3&#xff1a;使用 tr&#xff08;仅单文件&#xff…

Weblogic历史漏洞利用

文章目录漏洞介绍WebLogic 漏洞概述历史漏洞利用弱口令CVE-2014-4210CVE-2018-2894CVE-2019-2725CVE-2020-14882漏洞介绍 Oracle WebLogic Server 是一个用于开发和部署企业级 Java 应用的服务器平台&#xff0c;但其历史上存在多个严重漏洞&#xff0c;尤其以远程代码执行&am…

[Rust 基础课程]使用 Cargo 创建 Hello World 项目

Cargo&#xff08;https://crates.io/&#xff09; 是 Rust 语言中最常用的构建工具和包管理工具&#xff0c;我们看看怎么通过 Cargo 创建一个 Hello World 项目并运行。 :::warning 通过官方的 Rust 安装方式安装 Rust&#xff0c;Cargo 是同时默认安装好的了 ::: 首先&am…

C语言 --- 函数递归

函数递归一、什么是函数递归二、函数递归的要点三、示例1.计算n的阶乘2.提取一个任意正整数的所有位数&#xff0c;按顺序排列3.获取第n个斐波那契数&#xff0c;最开始的两个数是1&#xff0c;1四、总结一、什么是函数递归 函数递归是一种解决问题的思想&#xff0c;是将一个…

GitHub 趋势日报 (2025年07月14日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图1916claude-code795the-book-of-secret-knowledge728free-for-dev547markitdown367…

PyTorch中张量(TensorFlow)操作方法和属性汇总详解和代码示例

1、张量的操作汇总 下面是 PyTorch 中常见的 张量操作方法汇总&#xff0c;包括 创建、索引、变换、数学运算、广播机制、维度操作 等内容&#xff0c;并附上详解和代码示例&#xff0c;便于系统学习与实战参考。一、张量创建&#xff08;torch.tensor 等&#xff09; import t…

统一日志格式规范与 Filebeat+Logstash 实践落地

背景 在多部门、多技术栈并存的企业环境中&#xff0c;日志收集与分析是保障系统稳定运行的核心能力之一。然而&#xff0c;不同开发团队采用各异的日志打印方式&#xff0c;导致日志数据结构混乱&#xff0c;严重影响后续的收集、存储、检索与告警效率。 比如我们大部门就有多…

【鸿蒙HarmonyOS】鸿蒙app开发入门到实战教程(三):实现一个音乐列表的页面

鸿蒙里面&#xff0c;实现一个音乐播放的列表,模拟数组的数据展示 实现效果代码实现 准备数据 songs:SongItemTypes[] [{img:https://yjy-teach-oss.oss-cn-beijing.aliyuncs.com/HeimaCloudMusic/0.jpg,name:直到世界的尽头,author:WANDS},{img:https://yjy-teach-oss.oss-cn…

2025年渗透测试面试题总结-2025年HW(护网面试) 47(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 2025年HW(护网面试) 47 1. UDF提权 2. 命令执行与代码执行的区别 3. 文件包含利用姿势 4. 漏洞复现流程 …

iPhone 数据擦除软件评测(最新且全面)

当您准备出售、捐赠或回收 iPhone 时&#xff0c;仅仅恢复出厂设置并不足以保证您的个人数据彻底消失。专业的 iPhone 数据擦除软件采用先进的技术&#xff0c;确保您的敏感信息永久无法恢复。本文回顾了十种流行的 iPhone 数据擦除工具&#xff0c;详细介绍了它们的功能、优点…

Qt 将触摸事件转换为鼠标事件(Qt4和Qt5及以上版本)

在Qt中&#xff0c;触摸事件&#xff08;QTouchEvent&#xff09;和鼠标事件&#xff08;QMouseEvent&#xff09;是两种不同的输入事件类型。通常情况下&#xff0c;触摸事件不会自动转换为鼠标事件&#xff0c;因为它们代表的是不同的输入设备&#xff08;触摸屏 vs 鼠标&…

Blender 云渲染高效流程:渲染 101 集群加速实战​

一、核心优势&#xff1a;适配 Blender 全场景需求​ ✅ 全渲染器深度兼容​ Cycles&#xff08;CPU/GPU 模式&#xff09;&#xff1a;云端 4090 显卡渲染速度比本地快 12 倍&#xff0c;支持 8K 分辨率 16K 纹理无压力​ Eevee 实时渲染&#xff1a;集群同步输出预览动画&am…

SQL学习记录01

什么是SQL&#xff1f; Structured Query Language &#xff08;结构化查询语言&#xff09;&#xff0c;与关系型数据库进行通信的标准语言。什么是数据库&#xff1f;“按照数据结构来组织、存储、和管理数据的仓库。”一个长期存储在计算机内的、有组织的、可共享的、统一管…

医疗项目如何应对法规变更?

医疗项目应对法规变更的关键策略包括建立法规监测体系、及时内部培训和沟通、调整业务流程和合规标准、技术系统快速迭代升级。 其中&#xff0c;建立有效的法规监测体系尤其重要。这意味着企业需要实时关注监管机构发布的政策更新和公告&#xff0c;迅速理解法规变化内容及对自…