android 反编译 重打包,Android 反编译、修改、重打包与签名

article/2025/11/7 9:14:51

这篇博客主要介绍如何使用 Apktool、dex2jar、jd-gui等工具反编译 Android APP、修改源码、重新打包并签名。

1. 工具安装

1.1. Apktool

Apktool 主要用于反编译和重编译 APK 文件。

Windows 和 Linux 安装方法参照:官方指南

macOS 安装方法如下:

右键保存启动脚本,命名为 apktool

下载最新版本的 Apktool,命名为 apktool.jar

将 apktool 和 apktool.jar 移动到 /usr/local/bin 目录下

使用 chmod +x apktool 和 chmod +x apktool.jar 添加运行权限

在命令行直接运行命令 apktool 即可,安装完成

1.2. dex2jar

dex2jar 主要用于将 dex 文件转为 jar 文件

从 GitHub 下载最新版本,并解压。运行解压后目录下的 d2j-dex2jar.sh 或 d2j-dex2jar.bat 即可。

1.3. jd-gui

jd-gui 主要用来可视化 jar 文件。

从 GitHub 下载最新版本,并解压。运行解压后目录下的 JD-GUI 即可。

macOS 下注意:

如果 jd-gui 无法打开,编辑 JD-GUI.app/Contents/MacOS/universalJavaApplicationStub.sh

1

2

3

4

5

6

7

8

9

10

11

12exec "$JAVACMD" \

-cp "${JVMClassPath}" \

-Xdock:icon="${ResourcesFolder}/${CFBundleIconFile}" \

-Xdock:name="${CFBundleName}" \

## ----- 添加这两行 -----

--add-opens java.base/jdk.internal.loader=ALL-UNNAMED \

--add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED \

## --------------------

${JVMOptions:+$JVMOptions }\

${JVMDefaultOptions:+$JVMDefaultOptions }\

${JVMMainClass}\

${JVMArguments:+ $JVMArguments}

2. 查看源码

以小米投屏神器 APP 为例。

运行 d2j-dex2jar.sh 将 APK 中的 dex 文件转为 jar 文件:

1

2$ ./d2j-dex2jar.sh mi.apk

dex2jar mi.apk -> ./mi-dex2jar.jar

打开 jd-gui,将 mi-dex2jar.jar 拖进去,即可看到反编译后的源码。

80abe8fc819fd9f8398720d9bbdf532d.png

3. 修改源码

这里以增加 Log 为修改源码的例子。

jd-gui 只能查看源码,但是无法修改。要修改源码,只能修改 smali 文件,它类似于汇编,但是要简单很多。

首先得使用 apktool 进行反编译:

1apktool d mi.apk -o mi

这里将 mi.apk 进行反编译并将结果放到 mi 目录中。

首先找到需要添加 Log 的位置,建议在 jd-gui 中寻找,然后在 mi 目录中定位。

例如以下 class 和 smali 的对应关系

mi-dex2jar.jar!/com/xiaomi/mitv/phone/tvassistant/b/a.class

mi/smali/com/xiaomi/mitv/phone/tvassistant/b/a.smali

打开 a.class 和 a.smali,首先看 java:

1

2

3

4

5

6

7

8

9public void a(int paramInt)

{

String str1 = String.valueOf(System.currentTimeMillis());

String str2 = a(String.valueOf(paramInt), this.b, str1);

new c(this.d, String.format("http://%s:6095/general?action=setVolum&volum=%d&ts=%s&sign=%s", new Object[] { this.a, Integer.valueOf(paramInt), str1, str2 }), new c.a()

{

public void a(int paramAnonymousInt, String paramAnonymousString){}

}).d();

}

对应的 smali 文件内容,为了简单,我只提取了部分内容。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37.method public a(I)V

# a 是方法,p0 = this

# a 接收一个参数, p1 = paramInt'

# 定义了 8 个寄存器

.locals 8

.prologue

.line 55

# 获取系统当前时间

invoke-static {}, Ljava/lang/System;->currentTimeMillis()J

# 结果赋值给 v0

move-result-wide v0

# 调用 String.valueOf 方法,将 v0 转为字符串

invoke-static {v0, v1}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;

# 结果赋值给 v0

move-result-object v0

# 到这一步

# String str1 = String.valueOf(System.currentTimeMillis());

# 执行完了

.line 57

# 调用 String.valueOf 方法 p1 转为字符串

invoke-static {p1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;

# 结果赋值给 v1

move-result-object v1

# 获取 this.b,也就是从 p1 中获取 b,并赋值给 v2

iget-object v2, p0, Lcom/xiaomi/mitv/phone/tvassistant/b/a;->b:Ljava/lang/String;

# 将 v1,v2,v0 作为参数调用方法 a,并传递 p0 作为 this

invoke-direct {p0, v1, v2, v0}, Lcom/xiaomi/mitv/phone/tvassistant/b/a;->a(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

# 将结果赋值给 v1

move-result-object v1

# 到这一步

# String str2 = a(String.valueOf(paramInt), this.b, str1);

# 执行完了

...

假设我们想要得知其中 this.b 的值,可以这样添加 Log:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43.method public a(I)V

# 额外定义 4 个寄存器用于存储 TAG

.locals 12

.prologue

.line 55

# 设置初始化TAG

const-string v8, "AndiedieHack.currentTimeMillis"

const-string v9, "AndiedieHack.param"

const-string v10, "AndiedieHack.b"

const-string v11, "AndiedieHack.result"

invoke-static {}, Ljava/lang/System;->currentTimeMillis()J

move-result-wide v0

invoke-static {v0, v1}, Ljava/lang/String;->valueOf(J)Ljava/lang/String;

move-result-object v0

# 第一个 Log,使用 v8 作为 TAG,输出 v0 的值,即系统当前时间

invoke-static {v8, v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

.line 57

invoke-static {p1}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;

move-result-object v1

# 第二个 Log,使用 v9 作为 TAG,输出 v1 的值

# v1 是 p1 的字符串形式,p1 是函数参数

invoke-static {v9, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

iget-object v2, p0, Lcom/xiaomi/mitv/phone/tvassistant/b/a;->b:Ljava/lang/String;

# 第三个 Log,使用 v10 作为 TAG,输出 v2 的值,即 this.b

invoke-static {v10, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

invoke-direct {p0, v1, v2, v0}, Lcom/xiaomi/mitv/phone/tvassistant/b/a;->a(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

move-result-object v1

# 第四个 Log,使用 v11 作为 TAG,输出 v1 的值,即 str2

invoke-static {v11, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

到这一步,源码修改完成。接下来进行重新打包。

3. 重新打包与签名

将修改后的内容重新打包为 APK:

1apktool b mi -o unsigned.apk

打包之后的 unsigned.apk 是没有签名的,无法安装。

签名需要使用一个 keystore,可以直接使用 Android Studio 为我们生成的 debug 用 keystore。

位置在 用户目录/.android/debug.keystore,alias 是 androiddebugkey,密码是 android

签名命令:

1jarsigner -keystore debug.keystore -signedjar signed.apk unsigned.apk androiddebugkey

输入密码即可。

4. 测试

在手机上安装 signed.apk,注意如果之前已经安装了投屏神器,需要先卸载,因为两者的签名不一致。

运行 APP,调整音量,可以看到以下 Log:

1306c2810011068378bdd81b327a44f8.png


http://chatgpt.dhexx.cn/article/hAlGZPb3.shtml

相关文章

H5和安卓交互时,H5渲染滞后的坑

一、H5页面和安卓如何交互的 1.为什么会有h5和安卓的交互? 在手机app中,有时候需要在app中嵌入h5网页,能增加app的跨平台性,也就是相同的h5也可以嵌在ios平台。减少跨平台的开发成本。 同时,也能增强响应速度&#…

MAUI Blazor 权限经验分享 (定位,使用相机)

入门文章 Blazor Hybrid / MAUI 简介和实战 https://www.cnblogs.com/densen2014/p/16240966.html 在 Mac 上开发 .NET MAUI https://www.cnblogs.com/densen2014/p/16057571.html 在 Windows 上开发 .NET MAUI https://docs.microsoft.com/zh-cn/dotnet/maui/get-started/i…

UniApp 实战指南

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。 打包原生 APP 申请 AppKey 登录 DCloud 管理应用 点击…

Android Studio 插件大全(转)

转自:http://blog.csdn.net/alpha58/article/details/62881144 现在Android的开发者基本上都使用android Studio进行开发(如果你还在使用eclipse那也行,毕竟你乐意怎么样都行)。使用好Android Studio插件能大量的减少我们的工作量。 1.GsonFormat 快速…

定位技术课程设计-微信小程序校园导游系统

定位技术课程设计课程设计教学目的课程设计要求课程设计题目原题目拓展内容需求分析原理分析微信小程序API定位原理WIFI指纹定位原理路径规划算法调研详细设计总述主页面介绍学校简介页面介绍导引页面概述导引地图景点列表景点详细介绍页面搜索界面导航页面概述导航逻辑驾车导航…

前端知识——盒子类型,浮动属性,定位属性,JavaScript基础语法

文章目录 CSS—盒子类型marginpadding 浮动属性CSS—溢出属性overflow的设置项 CSS—定位属性定位状态定位操作 CSS—z-indexJavaScript简介主要功能运行模式变量与注释数据类型数据类型之数值类型(Number)数据类型之字符串类型(String) CSS—盒子类型 所有的标签其实都有一个…

python转js解释器_python 代码转换 js

广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 推荐使用腾讯云 api 配套的7种常见的编程语言 sdk,已经封装了签名和请求过程,均已…

android 图像识别定位,Android OpenCV 图像识别

最近打算写一个android 平台opencv 的小程序,着手查找了一下资料.网络上的资料参差不齐,有一些都比较老旧,我参考了前面的方法找到了一个简单的搭建方法,分享给大家. 0,环境的搭建: java 虚拟机环境搭建,网络资料很多不再赘述. 下面说明如果搭建 android opencv 环境: 下载Open…

安卓逆向及JavaScript实战

沐阳~ 各种案例,瑞树啥的,等等,案例多。 安卓逆向如下: 主: 沐阳~ 课程如下: 1.(ndk)1.初始NDK.mp4 1.(ndk)2.NDK性能提升及数据类型.mp4 1.(ndk)3.JAVA反射结合NDK.mp4 1.(ndk)4.JVM和JNI.mp4 1.(ndk)4.…

js逆向、安卓逆向教程

JS基础 提示信息 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn 1.零基础js逆向专题 MD5通杀 长度32位置 搜索关键词: 16进制 0x67452301 10进制 1732584193 RSA 搜索关键词: setpublickey AES cryptojs.aes DES cryptojs.des.encrypt …

学习强国---Android逆向及JS逆向

沐阳~ 各种案例,瑞树啥的,等等,案例多。有意私我,优惠大大 安卓逆向如下: 主: 沐阳~ 课程如下: 1.(ndk)1.初始NDK.mp4 1.(ndk)2.NDK性能提升及数据类型.mp4 1.(ndk)3.JAVA反射结合NDK.mp4 1.(…

js加密参数定位

当我们抓取网页端数据时,经常被加密参数、加密数据所困扰,如何快速定位这些加解密函数,尤为重要。本片文章是我逆向js时一些技巧的总结,如有遗漏,欢迎补充。 所需环境:Chrome浏览器 1. 搜索 1.1 全局搜索…

【APP 逆向百例】Frida 初体验,root 检测与加密字符串定位

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未…

巴斯勒相机acA1300-60gm

Basler acA1300-60gm GigE 相机配有 e2v EV76C560 CMOS 感光芯片,每秒 60 帧图像,130 万像素分辨率。

如何选择合适的工业相机

如何选择合适的工业相机 目录 如何选择合适的工业相机简洁具体**多相机检测****工业相机的白平衡知识**工业相机的参数工业数字相机常见问题解决方案参考文献 简洁 工业相机有许多项参数,选择合适的工业相机既要考虑工业相机的参数,也要考虑到项目的精度…

巴斯勒BASLER GIGE相机程序调试报错后需要拔网线

巴斯勒BASLER GIGE相机程序调试报错后需要拔网线的个人解决方案 根据SDK的用户手册提示,在相机连接后,直接执行以下程序。 camera.Parameters[PLTransportLayer.HeartbeatTimeout].TrySetValue(1000,IntegerValueCorrection.Nearest); // 1000 ms time…

机器视觉_工业相机及相关配件选型

文章目录 工业相机一、 概述二、 相机参数1. 传感器芯片1.1. CCD&CMOS1.2. CCD1.3. CMOS1.4. 靶面1.5. 传感器芯片选型 2. 黑白or彩色3. 帧数⭐4. 接口类型4.1. POE供电 三、相关硬件⭐1. 镜头1.1. 焦距⭐1.2. 视野⭐1.3. 物距1.4. 景深⭐1.5. 调焦1.6. 镜头的一些理论小知…

Ubuntu环境下配置巴斯勒相机及相机测试

Ubuntu环境下配置巴斯勒相机及相机测试 Ubuntu配置巴斯勒相机及相机测试软硬件要求Ubuntu虚拟系统安装安装c编译器安装Sublime Text 3及配置C运行环境配置巴斯勒相机SDK及代码测试 Ubuntu配置巴斯勒相机及相机测试 软硬件要求 软件 我们对Markdown编辑器进行了一些功能拓展与…

Python之OpenCV 005 工业相机Basler之图像采集

工业机器视觉系统2D应用用到Basler(德国),Baumer(瑞士),ImageSource(台湾),大恒和海康等等牌子工业相机。 Basler(巴斯勒)是比较常用的&#xff…

机器视觉 · 工业相机

文章目录 工业相机 面阵相机工业相机 线阵相机工业相机 光场相机工业相机 棱镜相机工业相机 多光谱/高光谱工业相机 偏振相机工业相机 传感器 CCD工业相机 传感器 ICCD工业相机 传感器 EMCCD工业相机 传感器 CMOS工业相机 传感器 sCMOS工业相机 传感器 红外探…