Как Android анализирует resources.arsc для определенных приложений? AAPT и AAPT2 дают разные результатыAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как Android анализирует resources.arsc для определенных приложений? AAPT и AAPT2 дают разные результаты

Сообщение Anonymous »

Я пытаюсь добавить APK-файл приложения Android в свой инструмент анализа. В частности, «Корпоративный портал» Microsoft (версия 5.0.6295.0 на момент написания статьи, вы можете загрузить ее и извлечь с устройства через adb). Ссылка на Play Store.
Этот инструмент предназначен для извлечения строки ресурсы из файла resources.arsc, но, похоже, он неправильно анализирует заголовки ResStringPool и получает слишком большие значения StringCount и StyleCount, в результате чего чтение выходит за пределы границы. Все остальные приложения, которые я тестировал, работали нормально. И я подтвердил, что приложение отлично устанавливается на нескольких устройствах.
Я также заметил, что при использовании разных версий инструмента Google AAPT результаты различаются.
Для справки: вот сравнение вывода для двух приложений:

Код: Выделить всё

$ aapt dump strings CompanyPortal.apk | head
# Outputs: String pool of 41756 unique UTF-8 non-sorted strings, 41756 entries and 41743 styles using 3531384 bytes: (incorrect)
$ aapt2 dump strings CompanyPortal.apk | head
# Outputs: String pool of 41801 unique UTF-8 non-sorted strings, 41801 entries and 529 styles using 3203980 bytes: (correct)

$ aapt dump strings NormalApp.apk | head
# Outputs: String pool of 12217 unique UTF-8 non-sorted strings, 12217 entries and 13 styles using 589388 bytes:
$ aapt2 dump strings NormalApp.apk | head
# Outputs: String pool of 12217 unique UTF-8 non-sorted strings, 12217 entries and 13 styles using 589388 bytes:
Итак, кажется очевидным, что мой инструмент работает так же, как AAPT v1, и мне нужно каким-то образом включить изменение, которое необходимо внести в AAPT2, чтобы получить точный подсчет. Когда я извлекаю resources.arsc из двух приложений, которые вижу

Код: Выделить всё

$ od -x CompanyPortalresources.arsc | head
0000000 0002 000c a0b8 0054 0001 0000 0001 001c
0000020 (e278 0035) (a31c 0000) (a30f 0000) 0100 0000 # (3531384, 41756, 41743)
0000040 18c8 0005 3f78 0033 0000 0000 0003 0000
0000060 009a 0000 0133 0000 01cc 0000 025b 0000

$ od -x NormalAppresources.arsc | head
0000000 0002 000c e5a8 000e 0001 0000 0001 001c
0000020 (fe4c 0008) (2fb9 0000) (000d 0000) 0100 0000 # (589388,12217,13)
0000040 bf34 0000 fd74 0008 0000 0000 0036 0000
0000060 005c 0000 0074 0000 0096 0000 00ba 0000
с помощью шестнадцатеричного поиска мы можем увидеть, откуда берутся неправильные значения, поэтому я сначала предположил, что это просто другая кодировка, но, глядя на все представления в этом шестнадцатеричном веб-инструменте, я все равно могу Не понимаю, откуда aapt2 извлекает правильные значения. В частности, я не вижу 0211 нигде в шестнадцатеричном дампе файла.
  • 3531384 => 0x0035e278, 41756 => < strong>0x0000A31C, 41743 => 0x0000A30F
  • 3203980 => 0x0030e38c, 41801 => 0x0000a349, 529 => 0x00000211
  • 589388 => 0x0008fe4c, 12217 => 0x00002fb9, 13 => 0x0000000d

    Ниже приведены другие ссылки, которые я использовал для справки, но, насколько я могу судить, все они предлагают читать Int32 в одном и том же месте, чтобы получить подсчеты, но я не очень хорош. при чтении C/C++, так что, возможно, я что-то упускаю. Будем очень признательны за любые советы/помощь, спасибо за уделенное время.
  • Общее описание resources.arsc
  • Apk инструмент синтаксического анализа jadx (написан на Java)
  • Инструменты платформы AOSP
  • Компилятор AOSP aapt
    Android studio AAPT2< /li>
ОБНОВЛЕНИЕ: 2024-08-02
aapt2/cmd/Dump.cpp показывает, что он получает таблицу из APK и вызывает конструктор ResStringPool с тремя аргументами

Код: Выделить всё

int DumpStringsCommand::Dump(LoadedApk* apk) {
ResourceTable* table = apk->GetResourceTable();
//...
android::StringPool::FlattenUtf8(&buffer, table->string_pool, GetDiagnostics());
auto data = buffer.to_string();
android::ResStringPool pool(data.data(), data.size(), false);
Debug::DumpResStringPool(&pool, GetPrinter());
aapt2/Debug.cpp Показывает, что напечатанное значение должно быть таким же, как и в Pool->size()

Код: Выделить всё

void Debug::DumpResStringPool(const android::ResStringPool* pool, text::Printer* printer) {
SortedVector uniqueStrings;
const size_t N = pool->size();
for (size_t i=0; iisUTF8()) {
uniqueStrings.add(UnpackOptionalString(pool->string8At(i), &len));
} else {
uniqueStrings.add(UnpackOptionalString(pool->stringAt(i), &len));
}
}
printer->Print(StringPrintf("String pool of %zd unique %s %s strings, %zd entries and %zd styles using %zd bytes:\n", uniqueStrings.size(), ...
}
ResourceTypes.cpp и ResourceTypes.h, кажется, показывают, что это происходит из mHeader->stringCount с конструктором, который также просто вызывает data.convert()

Код: Выделить всё

size_t ResStringPool::size() const
{
return (mError == NO_ERROR) ? mHeader->stringCount : 0;
}

status_t ResStringPool::ResStringPool(incfs::map_ptr data, size_t size, bool copyData)
{
//...
const auto chunk_header = data.convert();
const bool notDeviceEndian = htods(0xf0) != 0xf0; // htods=host to device short?
const auto header = data.convert();
mHeader = header.verified();
if (notDeviceEndian) {
h->stringCount = dtohl(mHeader->stringCount); // dtohl = device to host long?
}
utils/ByteOrder.h, кажется, имеет dtohl, а htods ничего не делает, я думаю, это просто остатки старых версий (см. пример 4.2.2_r1

Подробнее здесь: https://stackoverflow.com/questions/787 ... -are-givin
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»