Apktool 使用
1:linux安装apktool
可以直接查询下version
apktool -v
如果未安装,会得到如下结果:
Command 'apktool' not found, but can be installed with:
sudo snap install apktool # version 2.7.0, or
sudo apt install apktool # version 2.4.0-1
See 'snap info apktool' for additional versions.
可以根据提示进行安装。
2:apktool命令
这里我先创建了一个简单的demo,具体的代码如下:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainTest";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(TAG, "testxxxxxx");
}
}
2.1 反编译apk文件
apktool d 'LogTest.apk'
输出如下:
I: Using Apktool 2.4.0-dirty on LogTest.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/zh/.local/share/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
此时会在当前目录下生成LogTest目录,目录结构如下:
- original:
- res:
- smali:
- AndroidManifest.xml:
- apktool.yml
这里我们修改下smali下的mainactivity.smali. 让其打印新的日志输出。
2.2 打包apk
apktool b LogTest
输出如下:
I: Using Apktool 2.4.0-dirty
I: Checking whether sources has changed...
I: Checking whether resources has changed...
I: Building resources...
W: aapt: brut.common.BrutException: brut.common.BrutException: Could not extract resource: /prebuilt/linux/aapt_64 (defaulting to $PATH binary)
W: res/drawable-v21/$avd_hide_password__0.xml: Invalid file name: must contain only [a-z0-9_.]
W: res/drawable-v21/$avd_hide_password__1.xml: Invalid file name: must contain only [a-z0-9_.]
W: res/drawable-v21/$avd_hide_password__2.xml: Invalid file name: must contain only [a-z0-9_.]
W: res/drawable-v21/$avd_show_password__0.xml: Invalid file name: must contain only [a-z0-9_.]
W: res/drawable-v21/$avd_show_password__1.xml: Invalid file name: must contain only [a-z0-9_.]
W: res/drawable-v21/$avd_show_password__2.xml: Invalid file name: must contain only [a-z0-9_.]
W: res/drawable-anydpi-v24/$ic_launcher_foreground__0.xml: Invalid file name: must contain only [a-z0-9_.]
brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1): [aapt, p, --min-sdk-version, 16, --target-sdk-version, 28, --version-code, 1, --version-name, 1.0, --no-version-vectors, -F, /tmp/APKTOOL160505404917149026.tmp, -0, arsc, -0, res/drawable-xhdpi-v4/notification_bg_low_pressed.9.png, -0, png, -0, res/drawable-xhdpi-v4/notification_bg_normal.9.png, -0, res/drawable-xhdpi-v4/notification_bg_low_normal.9.png, -0, res/drawable-xhdpi-v4/notification_bg_normal_pressed.9.png, -0, res/drawable-xxxhdpi-v4/abc_btn_switch_to_on_mtrl_00012.9.png, -0, res/drawable-xxxhdpi-v4/abc_btn_switch_to_on_mtrl_00001.9.png, -0, res/drawable-xxxhdpi-v4/abc_switch_track_mtrl_alpha.9.png, -0, res/drawable-xxxhdpi-v4/abc_tab_indicator_mtrl_alpha.9.png, -0, res/drawable-xxxhdpi-v4/abc_spinner_mtrl_am_alpha.9.png, -0, res/drawable-xxhdpi-v4/abc_textfield_search_default_mtrl_alpha.9.png, -0, res/drawable-xxhdpi-v4/abc_list_pressed_holo_dark.9.png, -0, res/drawable-xxhdpi-v4/abc_cab_background_top_mtrl_alpha.9.png, -0, res/drawable-xxhdpi-v4/abc_list_focused_holo.9.png, -0, res/drawable-xxhdpi-v4/abc_ab_share_pack_mtrl_alpha.9.png, -0, res/drawable-xxhdpi-v4/abc_list_selector_disabled_holo_light.9.png, -0, res/drawable-xxhdpi-v4/abc_list_longpressed_holo.9.png, -0, res/drawable-xxhdpi-v4/abc_list_divider_mtrl_alpha.9.png, -0, res/drawable-xxhdpi-v4/abc_scrubber_primary_mtrl_alpha.9.png, -0, res/drawable-xxhdpi-v4/abc_list_pressed_holo_light.9.png, -0, res/drawable-xxhdpi-v4/abc_textfield_search_activated_mtrl_alpha.9.png, -0, res/drawable-xxhdpi-v4/abc_popup_background_mtrl_mult.9.png, -0, res/drawable-xxhdpi-v4/abc_list_selector_disabled_holo_dark.9.png, -0, res/drawable-xxhdpi-v4/abc_menu_hardkey_panel_mtrl_mult.9.png, -0, res/drawable-xxhdpi-v4/abc_scrubber_track_mtrl_alpha.9.png, -0, res/drawable-xxhdpi-v4/abc_textfield_default_mtrl_alpha.9.png, -0, res/drawable-xxhdpi-v4/abc_textfield_activated_mtrl_alpha.9.png, -0, res/drawable-ldrtl-xxxhdpi-v17/abc_spinner_mtrl_am_alpha.9.png, -0, META-INF/androidx.customview_customview.version, -0, META-INF/com.google.android.material_material.version, -0, META-INF/androidx.lifecycle_lifecycle-livedata-core.version, -0, META-INF/androidx.viewpager2_viewpager2.version, -0, META-INF/androidx.transition_transition.version, -0, META-INF/androidx.recyclerview_recyclerview.version, -0, META-INF/androidx.versionedparcelable_versionedparcelable.version, -0, META-INF/androidx.arch.core_core-runtime.version, -0, META-INF/androidx.activity_activity.version, -0, META-INF/androidx.lifecycle_lifecycle-runtime.version, -0, META-INF/androidx.drawerlayout_drawerlayout.version, -0, META-INF/androidx.interpolator_interpolator.version, -0, META-INF/androidx.appcompat_appcompat-resources.version, -0, META-INF/androidx.lifecycle_lifecycle-viewmodel.version, -0, META-INF/androidx.appcompat_appcompat.version, -0, META-INF/androidx.loader_loader.version, -0, META-INF/androidx.lifecycle_lifecycle-livedata.version, -0, META-INF/androidx.viewpager_viewpager.version, -0, META-INF/androidx.cardview_cardview.version, -0, META-INF/androidx.coordinatorlayout_coordinatorlayout.version, -0, META-INF/androidx.cursoradapter_cursoradapter.version, -0, META-INF/androidx.savedstate_savedstate.version, -0, META-INF/androidx.fragment_fragment.version, -0, META-INF/androidx.vectordrawable_vectordrawable.version, -0, META-INF/androidx.core_core.version, -0, META-INF/androidx.vectordrawable_vectordrawable-animated.version, -0, arsc, -I, /home/zh/.local/share/apktool/framework/1.apk, -S, /home/zh/test/LogTest/res, -M, /home/zh/test/LogTest/AndroidManifest.xml]
重新打包我们发现目录结构发生变化了。
多处了build/apk/classes.dex.
但是没有生成新的apk呢?
原因:apktool d ‘LogTest.apk’ 命令会解压资源文件。正确的操作应该是不解码资源文件。
我们修改命令使用:
apktool -r -f d 'LogTest.apk'
输出如下:
I: Using Apktool 2.4.0-dirty on LogTest.apk
I: Copying raw resources...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
重新打包apk.
I: Using Apktool 2.4.0-dirty
I: Checking whether sources has changed...
I: Checking whether resources has changed...
I: Copying raw resources...
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk...
可以看到此时多出了dist目录。
我们尝试安装LogTest.apk.
adb install '/home/zh/test/LogTest/dist/LogTest.apk'
结果:
adb: failed to install /home/zh/test/LogTest/dist/LogTest.apk: Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: Failed to collect certificates from /data/app/vmdl1812301930.tmp/base.apk: Attempt to get length of null array]
我们可以看到打包后的apk没有签名,无法安装。
2.3 重新签名
根据studio创建成功的jks文件,根据提示执行以下命令生成新的即可。
keytool -importkeystore -srckeystore /home/zh/Test.jks -destkeystore /home/zh/Test.jks -deststoretype pkcs12
查看签名文件信息:
keytool -list -v -keystore Test.jks
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN
您的密钥库包含 1 个条目
别名: test
创建日期: 2023-11-10
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: CN=test, OU=test, O=test, L=test, ST=test, C=test
发布者: CN=test, OU=test, O=test, L=test, ST=test, C=test
序列号: 62f04d00
有效期为 Fri Nov 10 17:24:53 CST 2023 至 Tue Nov 03 17:24:53 CST 2048
证书指纹:
MD5: 3E:5B:D8:4B:C3:D9:64:FA:29:69:6C:8B:64:79:2C:99:20:AF:3E:B6
SHA1: E8:57:08:30:39:D2:7A:10:0B:1C:B8:10:0A:AE:73:76:34:09:92:08:CF:8F:4A:95:46:09:7A:0A:26:54:83:A9
SHA256: SHA256withRSA
签名算法名称: 2048 位 RSA 密钥
主体公共密钥算法: 3
版本: {10}
扩展:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: BB 55 D1 25 57 B4 42 86 F4 68 9E E3 E0 44 9D 39 .U.%W.B..h...D.9
0010: ED 95 93 EA ....
]
]
*******************************************
*******************************************
重新签名:
apksigner sign --ks xxx/xxx/Test.jks --ks-key-alias xxxx(alias) '/home/zh/test/LogTest/dist/LogTest.apk'
2.4 无法运行
重新签名后,安装崩溃,反编译发现重新build的apk 丢失了源码。
2.5 解决办法
猜测不是最新版本的问题?
由于我是使用sudo apt install apktool 只能下载到2.4.0的版本。
所以还是老老实实的去官网操作。
https://apktool.org/docs/install
根据linux的操作步骤安装。
这里其实可以有两种方法
-
下载apktool.jar 的最新的版本。
java -jar 'xxx/apktool_2.9.0.jar' d 'xxx.apk'
-
本地配置apktool 环境变量
1:Download Linux wrapper script (https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool)
2:Download latest Apktool. (https://bitbucket.org/iBotPeaches/apktool/downloads)
3:Rename downloaded jar to apktool.jar
4:Move both files (apktool.jar & apktool) to usr/bin
5:Make sure both files are executable (chmod +x)
chmod +x apktool
chmod +x apktool.jar
6:apktool -v
输出如下:
Apktool 2.9.0 - a tool for reengineering Android apk files
with smali v3.0.3 and baksmali v3.0.3
Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>
Copyright 2010 Connor Tumbleson <connor.tumbleson@gmail.com>
重新执行反编译,重新打包,发现问题解决。
最终的步骤如下:(jadx 2.9.0 )
-
反编译apk
apktool -r -f d '/home/zh/下载/LogTest.apk' LogTest
-
修改部分代码
-
重新打包
jadx d LogTest
-
重新签名
apksigner sign --ks '/home/zh/Test.jks' --ks-key-alias Test '/home/zh/LogTest/dist/LogTest.apk'