对提供的 CrackmeTest.apk 进行逆向分析,程序含有反调试机制(加壳),通过静态补丁反反调试(去壳),再动态调试获取其中密码。

目录

环境

基础

实验内容

静态分析

动态分析

反反调试

再动态调试

补充

环境

环境:Windows11,java环境。

工具:IDA_Pro_v7.0 , AndroidKiller_V1.2 , 雷神模拟器,adb工具。

基础

        壳目的:反调试、反静态分析、反篡改、许可证管理。

        壳种类:压缩壳、加密壳(防止逆向)

        当一个Android应用加载一个原生库System.loadLibrary("crackme")时,Java层调用 System.loadLibrary,然后加载libcrackme.so动态链接,Android Native库加载执行的三个级别如下:

  • 系统级:-> libdl.so ->linker

  • 外壳级:.init ->.init_array -> JNI_OnLoad

  • 应用级:Java_com_xxx函数(SecurityCheck)

     可在以上位置设置加壳,实验样本是加在JNI_OnLoad的简单保护壳(“弱壳”),外壳级,对JNI_OnLoad下断点

     若 JNI_OnLoad 被加壳,应在以下位置设断点:

  • .init 、.init_array

  • 系统级.so中的初始化函数(例如在libc.so的fopen、strcmp,或者链接器的__dl_init函数)

         壳保护机制:在 libcrackme.so 的 JNI_OnLoad函数中,通过ptrace进行自我跟踪检测。如果发现TracerPid不为0(即程序正在被调试),就立即终止进程。

         Android APK 文件结构:

  • AndroidManifest.xml:应用“身份证”和“权限申请单”

  • resources.arsc:资源索引表,将所有资源ID映射到具体内容

  • res:资源目录,存放具体资源文件

    •  res/values/strings.xml:保存所有文本字符串

    • res/values/public.xml:固定资源ID的映射关系

  • Classes.dex:应用代码逻辑,由Java编译成

  • Lib/ 原生库目录:存放.so文件,C/C++编译的本地库

实验内容

静态分析

  • 初始在模拟器中运行程序,随意输入密码显示验证码校验失败。

  • 使用 AndroidKiller 反编译 APK,查看AndroidMainfest.xml中的activity类,找到入口Activity(MainActivity),以及在res-values-strings.xml和public.xml搜索成功提示等,未找到字段。

  • 使用 jadx-gui 分析 Java 代码,查看MainActtivity和ResultActivity的java代码,确定密码校验的关键函数securityCheck。

  • 用IDA静态分析libcrackme.so文件定位到securityCheck函数,对其分析可知apppwd即加密后off_628C(初始"aWojiushidaan"),与inputpwd即用户输入的密码比较,相等则校验成功。

  • 确定securityCheck偏移地址:0x000011A8,JNI_OnLoad偏移地址00001B9C。

动态分析

  • adb连接模拟器后将android_server上传后运行失败,换成android_x86_server后运行成功,开始监听,并将23946端口转发。

  •         模拟器开启root权限,开启adb远程调试权限,在IDA中附加进程com.mytest0.crackme开始远程调试。

  • 搜segement找libcrackme.so发现无可执行的.so文件,modules搜索crackme得到的入口地址:0B244000

  • 入口地址加上securityCheck的偏移地址000011A8得到绝对地址: F0B2451A8,搜索绝对地址添加断点调试。

  • 发现屏幕显示FFFFFFFF,程序有反调试机制,查看ptrace确认TracerPid非零。

反反调试

  • 调试模式启动程序,重新打开IDA调试挂载的程序。

  • libcrackme.so的基地址0B244000+JNI_OnLoad偏移地址00001B9C得到绝对地址0B245B9C,跳转到这里添加断点逐步调试。

  • 发现到对应相对地址00001C58处退出,BLX R7这个调用最终会执行ptrace检测,如果发现被调试就退出,静态调试修改libcrackme.so对应十六进制文件,修改该指令为空指令。

  • 将修改后的.so文件替换原来的.so文件,用AndroidKiller重新编译打包,再次上传,重新调试。

再动态调试

        再次挂载程序,IDA附加进程,基地址0B245000(动态链接,每次都会变),加上securityCheck函数偏移地址000011A8得到绝对地址0B2451A8添加断点调试,随意输入密码放入寄存器,一直F8执行,直到0B2451A8处发现R1中存放输入的密码,与R3中真正的密码比较,查看内存中R3寄存器处的对应值得到真实的密码aiyou,bucuoo。

补充

静态脱壳(适用于简单压缩壳),有些压缩壳的算法是公开的,可以直接用专门的脱壳工具(如UPX -d)进行解压,恢复出原始文件,但对加密壳完全无效。

动态脱壳是最主流的方法

  1. 加载程序(壳开始执行)
  2. 执行壳的解密代码(绕过反调试)
  3. 等待解密完成(定位原始程序的真正入口OEP)
  4. 抓取内存镜像(Dump Memory)
  5. 修复文件(内存镜像重建输入表/节区)
  6. 得到脱壳后的原生程序

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

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

相关文章

Rust 开发环境安装与 crates.io 国内源配置(Windows / macOS / Linux 全流程)

Rust 这几年在系统编程、WebAssembly、区块链、后端服务领域越来越火,很多开发者都在尝试用它做一些新项目。 但是国内安装 Rust 开发环境时,经常遇到 安装慢、依赖拉不下来、crates.io 超时 等问题。本文结合个人踩坑经验,整理了一份 跨平台…

Nginx SSL/TLS 配置

Nginx SSL/TLS 配置指南:从入门到安全强化前言一、环境准备:Nginx安装配置1.1. **EPEL仓库配置**:1.2. **Nginx安装**:1.3. **服务启停管理**:1.4. **服务状态验证**:二、SSL/TLS证书获取方案方案A&#xf…

Java ReentrantLock和synchronized的相同点与区别

1. 核心概念与定位synchronized:Java 内置的关键字,属于 JVM 层面的隐式锁。通过在方法或代码块上声明,自动实现锁的获取与释放,无需手动操作。设计目标是提供简单易用的基础同步能力,适合大多数常规同步场景。Reentra…

【npm】npm 包更新工具 npm-check-updates (ncu)

npm 包太多了,一个项目有那么多依赖包,它们的升级管理需要一个工具:npm-check-updates: 安装: npm install -g npm-check-updates安装之后,就可以使用它的命令:ncu 查看哪些包可以升级&#xff…

go资深之路笔记(一) Context

一、 Context 的正确使用与底层原理 1.结构体 type Context interface {// Deadline 返回此 Context 被取消的时间点。// 如果未设置截止时间,ok 为 false。Deadline() (deadline time.Time, ok bool)// Done 返回一个 channel。当 Context 被取消或超时后&#xff…

VS2022 + Qt5.9 中文乱码/项目设置utf-8编码

🛠️ 解决QT5.9 VS2022中文乱码的全面方案 📁 1. 检查文件编码与编译器设置 确保源文件是 带BOM的UTF-8 编码对MSVC编译器很重要。VS2022默认可能使用本地编码(如GB2312)解析源文件,即使文件以UTF-8保存。 查看和设置…

数据库--MySQL数据管理

数据库–MySQL数据管理 文章目录数据库--MySQL数据管理1.外键管理2.数据库数据管理3.DML语言3.1添加数据3.2修改数据3.3删除数据4.练习1.外键管理 外键概念 如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,…

【C++练习】13.C++输出九九乘法表的方法详解

目录 C++输出九九乘法表的方法详解 方法1:双重for循环(最基础) 思考: 代码分析: 特点: 方法2:使用while循环 思考: 代码分析: 特点: 方法3:使用递归实现 思考: 代码分析: 特点: 方法4:格式化输出(对齐美观) 思考: 代码分析: 特点: 方法5:使用函数封装 思考…

MVC及其衍生

MVC 把软件分成模型(Model)、视图(View)、控制器(Controller)三个基本部分。 事实上对应着 Controller——输入 用户交互,将输入处理成Controller能处理的形式 Model——处理 描述状态、逻辑规律…

微硕WINSOK MOS管WSF3089,赋能汽车转向系统安全升级

随着汽车电子化程度不断提高,转向系统对高效功率器件的需求日益增长。微硕WINSOK推出的N沟道Trench MOS管WSF3089,以30 V/72 A大电流、4.5 mΩ超低导通电阻和TO-252-2L紧凑封装,为EPS(电动助力转向)电机驱动、电源管理…

淘宝拍立淘接口的接入与应用||item_search_img-按图搜索淘宝商品(拍立淘)

淘宝拍立淘接口的接入与应用如下:接入流程注册与认证:开发者账号注册:访问淘宝开放平台,进行开发者账号注册。创建应用:在控制台创建新应用,获取 App Key 和 App Secret,这是接口调用的凭证。申…

Python学习-day8 元组tuple

元组(Tuple)是Python中一种不可变的序列类型,用于存储多个有序元素。与列表(List)类似,但元组一旦创建后不能修改(不可添加、删除或修改元素),这使得它在安全性、性能优化…

大数据毕业设计选题推荐-基于大数据的国家医用消耗选品采集数据可视化分析系统-Hadoop-Spark-数据可视化-BigData

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇…

二次学习C语言补充2

文章目录表栈、队列、二叉树一、二叉树二、表栈三、队列链表一、单向链表二、循环链表、双向链表和双向循环链表预处理一、预处理二、宏定义文件文件操作补充本篇文章是对二次学习C语言12——文件操作 二次学习C语言14——预处理及模块化 二次学习C语言15——链表 二次学习C语言…

2.9Vue创建项目(组件)的补充

1.再创建和引入vue的选择2.VsCode插件 安装Vue自己搜索最新的3.style自己的作用域在一个组件中引入另一个文件的子组件,给当前组件设置样式,那么子组件的样式也会改变的。为了解决这个问题 我们在自己的style中设置一个属性4.另一种创建vue 的方式(主流…

算法高频题

刷题:LeetCode(Top 100-150题,至少刷两遍)。重点:链表、树、二分查找、动态规划、回溯、栈/队列。 每一个题型,前10个高频题 算法思考框架参考:算法题思维框架-CSDN博客 高频顺序参考网站&…

服务器安装 LDOPE(MODIS 数据处理工具)

目录下载方式1-(简单快捷)根据WRF-VPRM 需要打补丁下载方式2:(手动安装依赖)一、安装所需依赖库(4 个主库 2 个基础库)另- HDF-EOS 手动编译二、解压并安装 LDOPE参考下载方式1-(简…

克隆代币 + 捆绑开盘:多链环境下的低成本发币玩法

在加密世界,发币已经不再是“少数开发者的专利”。随着工具的普及,任何人都可以快速发行一个在加密世界,发币已经不再是“少数开发者的专利”。随着工具的普及,任何人都可以快速发行一个代币。但问题是:如何在保证低成…

数据结构中的 二叉树

1.前言 在 Java 中,树(Tree)是一种非线性数据结构,由节点(Node)组成,常见的线性表则是我们之前学过的顺序表、链表、栈、队列等等。每个节点包含数据和指向子节点的引用。树的常见实现方式包括二…

IntelliJ IDEA 启动项目时配置端口指南

🌟 一、为什么需要手动设置启动端口? 默认情况下,Spring Boot 应用会使用 8080 端口启动。但在以下场景中,我们必须自定义端口: 多个微服务同时运行,需避免端口冲突;团队协作开发,统…