.dex 文件如何防止被修补?

问题描述 投票:0回答:1

我对处理 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中描述的工作流程。 它对我有用。

java android dex
1个回答
0
投票

乱序 string_ids 意味着 - dex 文件的 string_ids 部分是用作名称/常量/类名称/方法名称/字段名称/........................的字符串列表 这只是一个列表。例如-

  1. 方法名称
  2. LClass/bla/bla/MainActivity;
  3. 创建时
  4. 网络错误!

等等。 无论何时需要这些字符串,它们都只使用该列表项的索引。 例如,onCreate() 方法(在 methodSection 中)将仅保留数字“3”作为 methodName。 所以 dex 文件中的所有内容都是通过项目索引引用的。 这样,dex 文件就不会变大,因为不会一次又一次存储相同的字符串。

这个字符串部分(以及其他部分)有两个规则。

  1. 所有项目均应按字母顺序排列。
  2. 所有物品都应该是唯一的。

因此,当您替换某些字符串时,您正在编辑 stringSection。因为它是字符串出现的唯一地方。(所有其他地方只有它的索引)

但是通过编辑,你会打乱它的字母顺序。

© www.soinside.com 2019 - 2024. All rights reserved.