ApkTool разбивает файлы Java на несколько файлов

Я использую ApkTool для дезассемблирования файлов DEX из APK для восстановления кода smali. Я заметил, что файл .java был разбит на разные файлы.

Например:

  • MainActivity.java -> MainActivity.smali, MainActivity$1.smali
  • FirstFragment.java -> FirstFragment.smali, FirstFragment$1.smali, FirstFragment$2.smali

Есть ли причина, по которой это происходит?

У меня есть дополнительный вопрос в связи с этим: почему первые строки этих файлов имеют разное содержимое, если они ссылаются на один и тот же файл? Оба они ссылаются на исходный файл MainActivity.java, но имеют разные классы.

ОсновнаяАктивность$1.smali

.class Lcom/example/testapp/MainActivity$1;
.super Ljava/lang/Object;
.source "MainActivity.java"

ГлавнаяАктивность.smali

.class public Lcom/example/testapp/MainActivity;
.super Landroidx/appcompat/app/AppCompatActivity;
.source "MainActivity.java"

person orapic    schedule 05.12.2020    source источник


Ответы (1)


Файл .smali создается для одного класса Java. Файл .java может явно или неявно включать несколько классов Java. Явно - может быть для внутреннего класса; неявно - т.е. для создания потока (с анонимным классом). Рассмотреть возможность:

package Abc;

class Foo {
  class Bar {}
}

Внутри полностью разрешенными именами классов будут Abc/Foo и Abc/Foo$Bar. Обратите внимание на знак $, который отделяет внутреннее имя класса. Это может продолжаться, как Abc/Foo$Bar$Func. Анонимные классы просто получают числа для имен, например Abc/Foo$1 и Abc/Foo$1$1.

Теперь Apktool и baksmali негласно использует полностью разрешенное имя класса для пути и имени файла.


(*) Обычно каждый класс Java помещается в отдельный файл с именем файла и путем, совпадающим с именем пакета и собственным именем этого класса. Это соглашение. Если только один класс является общедоступным, другой может появиться в том же файле - несколько классов в одном файле.

person Ilia Barahovski    schedule 07.12.2020