java - 如何保护 .dex 文件免受修补?
问题描述
我是处理 Android 应用程序及其特征的新手。有一件事我不明白,到目前为止我还没有找到对观察到的行为的解释:
我创建了一个基本的 Android 应用程序,其中定义了一个字符串:
package com.example.helloworld;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String s = new String("JustanExample");
}
}
此应用程序可以在 Android Studio 模拟器中构建和运行而不会出现问题。
现在,如果我使用 apktool 反编译 apk 文件,对其进行编译、签名并运行,一切正常。
$ apktool d -r -s app-test.apk
$ apktool b -f -d app-test
$ jarsigner -verbose -keystore my-test-key.keystore app-test/dist/app-test.apk alias_name
但是如果我反编译apk,使用十六进制编辑器打开classes.dex文件并将“JustanExample”字符串更改为其他内容(例如“abcdanExample” - 相同长度),编译它,签名并安装它,应用程序立即停止/崩溃。
$ apktool d -r -s app-test.apk
change the string in the classes.dex with hex editor
$ apktool b -f -d app-test
$ jarsigner -verbose -keystore my-test-key.keystore app-test/dist/app-test.apk alias_name
.dex 文件是否受到保护以防止修补尝试?如何以及可以绕过它?
更新 01:根据 David Kroukamp 的建议,我查看了 logcat 输出(com.example.helloworld 是应用程序的名称)。这似乎是一个校验和问题:
Suppressed: java.io.IOException: Failed to open dex files from /data/app/com.example.helloworld-KxRtzkSSxWpFrHOn_7pXEQ==/base.apk because: Failure to verify dex file '/data/app/com.example.helloworld-KxRtzkSSxWpFrHOn_7pXEQ==/base.apk': Bad checksum (fce4124d, expected e273124a)
根据阅读一些第一个搜索结果,校验和似乎存储在 dex 文件本身中。我将做一些进一步的阅读,看看我是否能找到一种方法让我的修补 dex 文件工作。
更新 02:如果我将 dex 文件头中的校验和替换为从 logcat 输出中获得的校验和,则会获得不同的错误输出:
Suppressed: java.io.IOException: Failed to open dex files from /data/app/com.example.helloworld-QNglYY_UVQvVT-7uwN4dhA==/base.apk because: Failure to verify dex file '/data/app/com.example.helloworld-QNglYY_UVQvVT-7uwN4dhA==/base.apk': Out-of-order string_ids: 'abcdanExample' then 'KEEP_ALIVE'
此外,在以前的两种情况下,我都会收到一条仅略有不同的附加消息:
校验和未修补:
2020-12-28 12:34:45.110 7106-7106/com.example.helloworld E/LoadedApk: Unable to instantiate appComponentFactory java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[[zip file "/data/app/com.example.helloworld-YMa5lJJ4Vva3eQZ0chGS4Q==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.helloworld-YMa5lJJ4Vva3eQZ0chGS4Q==/lib/x86_64, /system/lib64]]
校验和修补:
2020-12-28 12:39:33.644 7481-7481/com.example.helloworld E/LoadedApk: Unable to instantiate appComponentFactory java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[[zip file "/data/app/com.example.helloworld-QNglYY_UVQvVT-7uwN4dhA==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.helloworld-QNglYY_UVQvVT-7uwN4dhA==/lib/x86_64, /system/lib64]]
当前解决方案 目前,我现在使用https://reverseengineering.stackexchange.com/a/9185中描述的工作流程。这个对我有用。
解决方案
推荐阅读
- sql - 重写 sql 查询以获得更好的优化
- javascript - 如何通过可观察将数据从一个组件发送到另一个组件并在 Angular 的第二个 html 模板中显示数据
- sql - 为什么在sql存储过程中选择一个等于列名的变量?
- variables - 这是一种声明变量的方法还是只是一个标签(Nasm)?
- python-3.x - ExcelWriter 不覆盖工作表而是创建一个新工作表
- android - 如何使用 Xamarin.Android 从最终 AAB 文件中删除未使用的语言?
- python - 从整数中取第一个数字 - py
- django - 无法访问数据表中的外键数据
- flutter - 如何在不应该受夏令时影响的颤振中创建日期时间
- java - springboot Logback如何防止删除较旧的Log文件