Android 反编译初探-基础篇

news2024/9/26 5:12:25

前言

本文目标:

  1. 工具:介绍反编译需要用到的工具
  2. 原理:反编译基本原理
  3. 实践:替换一个未混淆&未加固apk的启动页面

工具

1.Android Studio

版本:Android Studio Dolphin | 2021.3.1 Patch 1

2.Jadx Class Decompiler。

一个集成了jadx-gui的AndroidStudio/IDEA插件。
优点:dex2jar&jd-gui的结合体,使用更方便。
在这里插入图片描述
在这里插入图片描述

3.apktool

Android apk文件逆向工具。
https://ibotpeaches.github.io/Apktool/

4. jadx

Dex 到 Java 反编译器,用于从 Android Dex 和 Apk 文件生成 Java 源代码的命令行和 GUI 工具。
优点:dex2jar&jd-gui的结合体,有这一个就够了。
缺点:没有mac的可执行程序。
https://github.com/skylot/jadx

5.LibChecker.apk

此应用程序用于查看设备中应用程序使用的第三方库。它可以查看应用程序本机库的ABI体系结构(通常,无论应用程序是64位还是32位)。它还可以查看由The Rule Repository标记的知名库,甚至可以根据库引用的数量对它们进行排序和查看。

非常好用的Android端app分析软件,主要可以用来分析app的基本结构,查看包名等。
https://github.com/LibChecker/LibChecker

6.dex2jar

把dex文件反编译成jar文件。
https://github.com/pxb1988/dex2jar

7.jd-gui

查看jar源码的可执行程序。
http://java-decompiler.github.io/
mac可执行程序在m1上无法运行,可参考:Mac上打不开JD-GUI解决办法

8.java2smali

可以将java&kotlin代码转为smali的AndroidStudio/IDEA插件。
似乎是只能将纯java&kotlin代码编译成smali,据说AndroidX代码会报错,我自己编译Activity也报错了。

9.smali2java

smali2java是一个将smali代码反编译成java代码的工具。
缺点:没有找到可用mac版本。
http://www.hensence.com/cn/smali2java/

10.J2S2J

java转smali,smali转java工具。
缺点:没有找到可用mac版本。
http://lzonel.cn/3056.html

原理

apk

在AndroidStudio中双击一个apk,打开查看apk内的详情,也可以直接用压缩软件解压。
在这里插入图片描述

其中:

  1. META_INF文件夹:储存的是关于apk的签名信息,在安装apk时,系统会校验apk的签名信息,判断程序完整性。
  2. res文件夹:存储着apk用到的资源文件。
  3. assest文件夹:原生资源文件,放在这个文件夹下面的文件不会被R文件编译,dex动态加载等时使用。
  4. lib文件夹:存储着c++编译成的so库。
  5. AndroidManifest.xml:存储着apk程序配置信息的清单文件。
  6. class.dex:DEX文件(DalvikVM executes),顾名思义,是Android Dalvik虚拟机上的执行程序,也就是Dalvik字节码,程序的代码都在里面。
  7. resources.arsc:编译后的二进制资源文件。

apktool

反编译apk的核心工具apktool。

一个逆向工程第三方,封闭,二进制Android应用程序的工具。
它可以将资源解码为接近原始的形式,并在进行一些修改后重新构建它们。
它还使应用程序的工作更容易,因为项目,如文件结构和自动化的一些重复性任务,如构建apk等。

dex作为包含程序代码的文件,Android程序的启动运行都是通过类加载器ClassLoader读取dex中的代码运作的。
因此如何修改dex中的代码是反编译的关键所在,而apktool可以将dex反编译成smali文件,我们通过修改smali文件完成“目标”。
因此反编译的大致流程是:

反编译
编译
apktool d test.apk
将dex转换为smali
修改smali
apktool b test
未签名的新apk
重新签名apk

Smali

Smali,Baksmali分别是指安卓系统里的Java虚拟机(Dalvik)所使用的一种.dex格式文件的汇编器,反汇编器。
其语法是一种宽松式的Jasmin/dedexer语法,而且它实现了.dex格式所有功能(注解,调试信息,线路信息等)。

修改Smali有三种方式:

  1. 懂Smali语法,打开直接撸。
  2. 用上述提到的工具转为java代码后修改。
  3. 创建一个新AndroidStudio项目,包名与目标apk完全一致,添加想要类的代码,修改完后打包成debug apk,然后使用apktool反编译拿到对应的smali文件,复制到目标apk的反编译文件中替换对应的smali。

实践

由于我不会smali语法,也没有找到适合mac的smali转换工具,因此采用上述第三种修改Smali的方式。

首先自己打包一个未混淆&未加固的apk作为目标apk。

1.用AndroidStudio打开

在AndroidStudio打开目标apk,打开AndroidManifest.xml,读取包名&启动Activity。
在这里插入图片描述
如上图可知:
包名为:com.demon.demonnewest
启动Activity为:com.demon.demonnewest.module.StartActivity

2.根据上述包名创建一个AndroidStudio新项目

添加测试代码:

TestActivity.kt

package com.demon.demonnewest

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
class TestActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val layout = LinearLayout(this)
        layout.orientation = LinearLayout.VERTICAL
        val text = TextView(this)
        val button = Button(this)
        button.text = "Click"
        layout.addView(text)
        layout.addView(button)
        setContentView(layout)
        val sb: StringBuilder = StringBuilder()
        sb.append("TestActivity\n")
        intent.extras?.run {
            keySet().forEach {
                sb.append("$it=${get(it)}\n")
            }
        }
        text.text = sb.toString()
        button.setOnClickListener {
           Toast.makeText(this@TestActivity,"Button~",Toast.LENGTH_SHORT).show()
            startActivity(Intent(this@TestActivity, TestJavaActivity::class.java))
        }
    }
}

TestJavaActivity.java

package com.demon.demonnewest;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class TestJavaActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        tv.setText("TestJavaActivity");
        Button btn = new Button(this);
        btn.setOnClickListener(view -> Toast.makeText(TestJavaActivity.this,"Button~",Toast.LENGTH_SHORT).show());
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.addView(tv);
        layout.addView(btn);
        setContentView(layout);
    }
}

3.将新项目打包

直接gradle---Tasks---other---assembleDebug双击运行,打debug包。

然后在app/build/outputs/apk/debug/app-debug.apk找到打包后的apk。

命令行执行apktool d app-debug.apk反编译,找到需要添加的smali。

在这里插入图片描述

4.用apktool对目标apk进行反编译

得到反编译后的app文件夹。

apktool d app.apk

在这里插入图片描述

5.修改目标apk反编译后AndroidManifes.xml

编辑器直接打开修改即可。

//...
//修改启动Activty为TestActivity
<activity android:exported="true" android:name="com.demon.demonnewest.TestActivity" android:theme="@style/Theme.Start">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
//添加TestJavaActivity
<activity android:name="com.demon.demonnewest.TestJavaActivity"/>
//...        

6.添加新增的smali

将第三步中我们新增加代码后得到smali复制到smali_classes文件夹中。
随便找一个包含目标包名:com.demon.demonnewest的目录即可。
在这里插入图片描述

7.apktool重新编译

如下指令将修改后的反编译文件夹,编译成new.apk。

apktool b app -o new.apk

得到的apk是未签名的是无法安装的,需要签名。

8.重新签名new.apk

不推荐使用旧版的jarsigner进行签名,只能进行v1签名,高版本手机可能无法安装。
新版的v1&v2 签名工具apksigner在版本>25的SDK\build-tools\中。

//windows
java -jar apksigner.jar sign  --ks 你的密钥  --ks-key-alias 别名  --ks-pass pass:密钥密码  --key-pass pass:别名密码  --out 签名后的apk路径  待签名的apk 
//mac
./apksigner sign --ks 你的密钥  --ks-key-alias 别名  --ks-pass pass:密钥密码  --key-pass pass:别名密码  --out 签名后的apk路径  待签名的apk

9.安装运行签名后的apk

安装后启动app,启动页已经正常替换,按钮可以正常跳转,初步反编译实践成功。

参考

Android反编译简单实战

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

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

相关文章

go 数组(array)和切片(slice)

文章目录数组ArraySlice 切片appendcopy&#xff08;切片复制&#xff09;goto数组Array 和以往的数组有很大的不同 数组时值类型&#xff0c;复制和传参会复制整个数组&#xff0c;而不是指针数组长度必须是常量&#xff0c;且是类型的组成部分。[2]int和[3]int是不同的数据…

Vue中Vue.use()的原理及基本使用

目录 &#x1f525; 前言 1. 举例理解 2. 源码分析 &#x1f525; 小结 相信很多人在用Vue使用别人的组件时,会用到 Vue.use() ,例如&#xff1a;Vue.use(VueRouter)、Vue.use(MintUI)&#xff0c;这篇文章主要给大家介绍了关于Vue中Vue.use()的原理及基本使用的相关资料&a…

Mysql索据-Mysql的innodb引擎为什么要使用b+tree作为索引数据结构?

目录 索引&#xff1f; 什么是索引&#xff1f;索引有什么优点&#xff1f;索引有什么缺点&#xff1f; 索引的分类 按照功能分类&#xff1a; 按照数据结构分类 相关数据结构&#xff08;b-tree、btree&#xff09; b-tree btree b-tree和btree的区别 为什么Innodb要…

65. 锚框的代码实现

目标检测算法通常会在输入图像中采样大量的区域&#xff0c;然后判断这些区域中是否包含我们感兴趣的目标&#xff0c;并调整区域边界从而更准确地预测目标的真实边界框&#xff08;ground-truth bounding box&#xff09;。 不同的模型使用的区域采样方法可能不同。 这里我们…

TiDB学习笔记(八)-数据库故障处理

一、数据丢失快速恢复 数据恢复前置条件-GC&#xff0c;tidb_gc_life_time 查询GC已经清理的时间点tikv_gc_safe_point 数据快速恢复操作方式 DML->tidb_snapshot参数 &#xff08;在tikv_gc_safe_point范围内&#xff09; DDL->flashback table/recover table (flas…

AIGC与搜索深度融合,百度定义“生成式搜索”

设想一下&#xff0c;当你搜索“公司活动通知怎么写”时&#xff0c;搜索引擎直接“写”了一篇送到眼前是什么体验&#xff1f;百度的“生成式搜索”正在让这样的场景成为现实。日前&#xff0c;百度宣布&#xff0c;百度搜索将升级“生成式搜索”能力&#xff0c;基于百度自研…

项目管理工具dhtmlxGantt甘特图入门教程(七):在服务器上使用甘特图

dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表&#xff0c;可满足项目管理控件应用程序的所有需求&#xff0c;是最完善的甘特图图表库。 这篇文章给大家讲解如何在服务器上使用DHTMLX Gantt 。 DhtmlxGantt正版试用下载&#xff08;qun&#xff1a;764…

Cadence PCB仿真使用Allegro PCB SI元器件类别设置为IO,IC和Discrete的方法图文教程

⏪《上一篇》   🏡《总目录》   ⏩《下一篇》 目录 1,概述2,配置方法3,总结1,概述 本文简单介绍使用Allegro PCB SI软件配置电压地网络电压的方法。 2,配置方法 第1步:打开待仿真的PCB文件,并确认软件为Allegro PCB SI 如果,打开软件不是Allegro PCB SI则可这样…

ElementUI源码系列一-完整引入和按需引入

前言 本篇将介绍&#xff0c;ElementUI 是如何实现完整引入和按需引入的。 完整引入 官网使用 源码步骤 src/index.js 通过对外暴露 install()&#xff0c;让主项目通过 Vue.use(ElementUI) 引入&#xff0c;还需单独引入样式 import element-ui/lib/theme-chalk/index.c…

Selenium用法详解【Options选项】【JAVA爬虫】

简介本文主要讲解如何使用java代码利用selenium控制浏览器的启动选项Options的代码操作教程。Options选项这是一个Chrome的参数对象&#xff0c;在此对象中使用addArgument()方法可以添加启动参数&#xff0c;添加完毕后可以在初始化Webdriver对象时将此Options对象传入&#x…

minio分布式存储的go语言开发衔接

minio是分布式存储&#xff0c;可集群部署&#xff0c;阵列磁盘&#xff0c;纠错码等大数据存储必备的技术。由于它是go语言开发的&#xff0c;我们用go来与它衔接&#xff1a;上传文件&#xff0c;比如图片&#xff0c;然后预览。这里涉及几个重要的知识点。一是minio永久路径…

Vue学习笔记(二)

Vue学习笔记二脚手架利用脚手架软件生成项目包脚手架 随着时代的发展, WEB开发逐渐出现了 工程化 特征: 流水线作业! 脚本方式: 到饭店 自选点餐… 脚手架方式: 点 套餐, 一套完善的配置,扩展, 各种易用功能… 脚手架: 就是一款软件, 可以按照用户需求自动生成 开发环境: 包含…

[博士论文]基于图数据的可信赖机器学习

密歇根大学Towards Trustworthy Machine Learning on Graph Datahttps://deepblue.lib.umich.edu/handle/2027.42/174201摘要机器学习已经被应用于越来越多影响我们日常生活的与社会相关的场景&#xff0c;从社交媒体和电子商务到自动驾驶汽车和刑事司法。因此&#xff0c;为了…

7-2 洛希极限

科幻电影《流浪地球》中一个重要的情节是地球距离木星太近时&#xff0c;大气开始被木星吸走&#xff0c;而随着不断接近地木“刚体洛希极限”&#xff0c;地球面临被彻底撕碎的危险。但实际上&#xff0c;这个计算是错误的。 洛希极限&#xff08;Roche limit&#xff09;是一…

用Python实现十大经典排序算法(附动图)

排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序&#xff0c;内部排序是数据记录在内存中进行排序&#xff0c;而外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要访问外存。常见的内部排…

69、CLIP-NeRF: Text-and-Image Driven Manipulation of Neural Radiance Fields

简介 官网&#xff1a;https://cassiepython.github.io/clipnerf/ 利用对比语言-图像预训练(CLIP)模型的联合语言-图像嵌入空间&#xff0c;提出了一个统一的框架&#xff0c;可以用短文本提示或示例图像以用户友好的方式操纵NeRF。改论文结合NeRF的新视图合成能力和生成模型潜…

【自学Python】Python缩进规则

Python缩进规则 Python缩进规则教程 Python 和其它程序设计语言采用大括号 {} 分隔代码块不同&#xff0c;Python 采用代码缩进和冒号来区分代码块之间的层次。 在 Python 中&#xff0c;对于 类定义、函数定义、流程控制语句、异常处理语句 等&#xff0c;行尾的冒号和下一…

【Linux篇】之TFTP服务配置

tftp是基于UDP协议的简单文本文件传输协议&#xff1b; 用途&#xff1a;使用网络的方式将文件传输(下载)到开发板中。 具体的tftp服务的安装步骤&#xff1a; 1> 安装tftp服务 (ubuntu必须可以上网) sudo apt-get update ----> 更新源 sudo apt-get install tftpd-hpa…

【MyBatis】如何使用“动态SQL”(不用找了,这一篇足矣)

目录 一、if标签 二、where标签 三、trim标签 四、choose、when、otherwise 五、foreach标签 六、sql标签 一、if标签 if&#xff0c;通过test属性中的表达式判断标签中的内容是否有效&#xff08;有效才将if里面的内容拼接到sql中&#xff09;&#xff1b;一般用于用户在…

Authing 通过中国信通院「身份治理系统和工具能力」全面级评估

Authing 通过中国信通院「身份治理系统和工具能力」全面级评估 近期&#xff0c;Authing 荣获由中国信通院颁发的「身份治理系统和工具能力」全面级评估。在统一身份管理、统一认证管理、开发集成管理以及统一安全管理四个模块满足身份治理系统和工具支撑能力全面级要求。 评估…