Android java class dex

обзор

После понимания файла Dex я смог глубже понять некоторые проблемы, возникающие в повседневной разработке. Такие как: APK для похудения, горячий ремонт, плагин, усиление приложений, Android-реверс-инжиниринг, ограничение метода 64 К.

Что такое файл Dex

Прежде чем понять, что такое файл Dex, вы должны сначала понять JVM, Dalvik и ART. JVM — это виртуальная машина JAVA, используемая для запуска программ байт-кода JAVA. Dalvik — это среда выполнения, разработанная Google для платформы Android, которая подходит для систем с ограниченной памятью и скоростью процессора в мобильной среде. ART, или Android Runtime, — это новая среда выполнения Android, разработанная Google для замены Dalvik, и она была запущена в Android 4.4. ART обладает лучшими характеристиками, чем Dalvik. Программы для Android обычно разрабатываются с использованием языка Java, но виртуальная машина Dalvik не поддерживает непосредственное выполнение байт-кода JAVA, поэтому скомпилированные файлы .class будут переведены, восстановлены, интерпретированы, сжаты и т. Д. Этот процесс выполняется dx После обработки продукт, сгенерированный после обработки, оканчивается на .dex, который называется Dex file. Формат файла Dex — это формат сжатия, разработанный специально для Dalvik. Таким образом, его можно просто понять как: Dex-файл является продуктом многих обработанных файлов .class и, наконец, может быть выполнен в среде выполнения Android.

Как создается файл Dex

Процесс преобразования Java-кода в dex-файл показан на рисунке. Конечно, этот процесс не так прост. Вот только визуальное отображение:

14212771-f40219595f0ac3fb.png

Примечание: картина приходит из интернета

Теперь давайте воспользуемся простым примером для реализации преобразования кода Java в файл dex.

Из .java в .class

Давайте сначала создадим файл Hello.java. Чтобы упростить анализ, приведем простой код. код шоу, как показано ниже:

public class Hello < private String helloString = "hello! youzan"; public static void main(String[] args) < Hello hello = new Hello(); hello.fun(hello.helloString); >public void fun(String a) < System.out.println(a); >> 

Используйте javac JDK для компиляции java-файла в том же каталоге уровня файла.

После выполнения команды javac файл Hello.class будет сгенерирован в текущем каталоге, и файл Hello.class уже может быть непосредственно выполнен на виртуальной машине JVM. Используйте команду, чтобы выполнить файл здесь.

После выполнения он должен распечатать «привет! Youzan» на консоли

Здесь вы также можете выполнить команду javap для дизассемблирования файла Hello.class.

Результаты выполнения следующие:

public class Hello < public Hello(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: aload_0 5: ldc #2 // String hello! youzan 7: putfield #3 // Field helloString:Ljava/lang/String; 10: return public static void main(java.lang.String[]); Code: 0: new #4 // class Hello 3: dup 4: invokespecial #5 // Method "":()V 7: astore_1 8: aload_1 9: aload_1 10: getfield #3 // Field helloString:Ljava/lang/String; 13: invokevirtual #6 // Method fun:(Ljava/lang/String;)V 16: return public void fun(java.lang.String); Code: 0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 3: aload_1 4: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 7: return > 

После кода существуют конкретные инструкции для виртуальной машины JVM для выполнения. Для конкретного значения инструкции, пожалуйста, обратитесь к официальному документу JAVA.

Читайте также:  Arraylist in java default size

От .class до .dex

Хотя созданный выше файл .class можно запускать в среде JVM, если он должен выполняться в среде выполнения Android, требуется специальная обработка, то есть обработка dx, которая преобразует, реконструирует, интерпретирует и интерпретирует файл .class. Операции, такие как сжатие.

Для обработки dx будет использоваться инструмент dx.jar, этот файл находится в SDK, конкретный каталог примерноВаш корневой каталог SDK / build-tools / любая версия внутри. Используйте инструмент dx для обработки файла Hello.class, сгенерированного выше, и используйте следующую команду в каталоге Hello.class:

dx --dex --output=Hello.dex Hello.class 

После завершения выполнения файл Hello.dex будет создан в текущем каталоге. Этот файл .dex может быть выполнен непосредственно в среде выполнения Android, а файл dex обычно может быть загружен через PathClassLoader. Теперь выполнить в текущем каталогеdexdump Имя для декомпиляции:

Результаты выполнения следующие (значение некоторых областей описано ниже):

Processing 'Hello.dex'. Opened 'Hello.dex', DEX version '035' ------ Вот информация о классе Hello.java написано ------ Class #0 - Class descriptor : 'LHello;' Access flags : 0x0001 (PUBLIC) Superclass : 'Ljava/lang/Object;' Interfaces - Static fields - Instance fields - #0 : (in LHello;) name : 'helloString' type : 'Ljava/lang/String;' access : 0x0002 (PRIVATE) ------ Следующая область описывает информацию о методе строительства. Цифры, такие как 7010 0400 0100 1a00 0b00 - это инструкции, переведенные в код метода. Dalvik использует 16-битную кодовую единицу, поэтому здесь есть группа из 4 чисел, каждое число в шестнадцатеричном формате. invoke-direct Это мнемоника, соответствующая предыдущим инструкциям, а также представляющая фактическую работу этих инструкций. Если вы заинтересованы в этих преобразованиях инструкций, вы можете перейти по адресу https://source.android.com/devices/tech/dalvik/instruction-formats для просмотра ------ Direct methods - #0 : (in LHello;) name: '' --- Имя метода: Это, очевидно, метод построения --- type: '() V' --- прототип метода, () означает входной параметр, () означает возвращаемое значение, V означает void --- access: 0x10001 (PUBLIC CONSTRUCTOR) --- Тип доступа к методу --- code - registers: 2 --- количество регистров, используемых методом --- ins: 1 --- Метод вводит параметры. В дополнение к определенным нами параметрам система также по умолчанию принимает специальный параметр --- outs : 1 размер insns: 8 16-битных кодовых единиц --- размер инструкции --- 000148: |[000148] Hello.:()V 000158: 7010 0400 0100 |0000: invoke-direct , Ljava/lang/Object;.:()V // [email protected] 00015e: 1a00 0b00 |0003: const-string v0, "hello! youzan" // [email protected] 000162: 5b10 0000 |0005: iput-object v0, v1, LHello;.helloString:Ljava/lang/String; // [email protected] 000166: 0e00 |0007: return-void catches : (none) positions : 0x0000 line=1 0x0003 line=2 locals : 0x0000 - 0x0008 reg=1 this LHello; #1 : (in LHello;) name : 'main' type : '([Ljava/lang/String;)V' access : 0x0009 (PUBLIC STATIC) code - registers : 3 ins : 1 outs : 2 insns size : 11 16-bit code units 000168: |[000168] Hello.main:([Ljava/lang/String;)V 000178: 2200 0000 |0000: new-instance v0, LHello; // [email protected] 00017c: 7010 0000 0000 |0002: invoke-direct , LHello;.:()V // [email protected] 000182: 5401 0000 |0005: iget-object v1, v0, LHello;.helloString:Ljava/lang/String; // [email protected] 000186: 6e20 0100 1000 |0007: invoke-virtual , LHello;.fun:(Ljava/lang/String;)V // [email protected] 00018c: 0e00 |000a: return-void catches : (none) positions : 0x0000 line=5 0x0005 line=6 0x000a line=7 locals : Virtual methods - #0 : (in LHello;) name : 'fun' type : '(Ljava/lang/String;)V' access : 0x0001 (PUBLIC) code - registers : 3 ins : 2 outs : 2 insns size : 6 16-bit code units 000190: |[000190] Hello.fun:(Ljava/lang/String;)V 0001a0: 6200 0100 |0000: sget-object v0, Ljava/lang/System;.out:Ljava/io/PrintStream; // [email protected] 0001a4: 6e20 0300 2000 |0002: invoke-virtual , Ljava/io/PrintStream;.println:(Ljava/lang/String;)V // [email protected] 0001aa: 0e00 |0005: return-void catches : (none) positions : 0x0000 line=10 0x0005 line=11 locals : 0x0000 - 0x0006 reg=1 this LHello; source_file_idx : 1 (Hello.java) 

До сих пор код Java был преобразован в исполняемый файл Dalvik, а именно dex.

Читайте также:  Char empty string java

Конкретный формат файла Dex

Теперь давайте проанализируем конкретный формат файлов Dex. Как и файлы MP3, MP4, JPG и PNG, файлы Dex также имеют свои собственные форматы. Только при соблюдении этих форматов они могут быть правильно распознаны средой выполнения Android.

Общая схема файла Dex показана ниже:

14212771-a46d73e09f2f2ece.png

Данные в этих областях взаимосвязаны и относятся друг к другу. Из-за нехватки места здесь показаны только ассоциации некоторых областей, перейдите на официальный веб-сайт, чтобы самостоятельно проверить соответствующие данные. Поля на рисунке ниже подробно описаны в подробном описании каждой области.

14212771-db7abc64904dbe14.png

Заголовок файла, область индекса и область определения класса будут кратко представлены ниже. Вы можете перейти на официальный сайт Android, чтобы узнать о других областях.

Заголовок файла

Область заголовка файла определяет, как читать этот файл. Конкретный формат выглядит следующим образом (порядок в файле — это порядок в таблице ниже):

14212771-b5eaffaa92e5139c.png

область идентификатора

Область идентификатора хранит смещение реальных данных строки, типа, прототипа, поля и ресурсов метода в файле. Мы можем найти фактические данные, соответствующие идентификатору, в соответствии со смещением области идентификатора.

Область идентификатора строки

Этот блок представляет собой список смещений, каждое смещение соответствует реальному строковому ресурсу, и каждое смещение занимает 32 бита. Мы можем найти соответствующие фактические строковые данные по смещению. Конкретный формат выглядит следующим образом:

14212771-42ff33f12812bbd2.png

Конечная позиция этого смещения должна находиться в области данных. После нахождения позиции этого смещения конкретные данные этого строкового ресурса могут быть считаны в следующем формате:

14212771-787e9e29706b6ca9.png

Введите идентификатор области

Этот блок является списком индексов, и значение индекса соответствует элементу в списке смещений области идентификатора строки. Формат данных следующий:

14212771-69a6df00f35556af.png

Если мы хотим найти значение определенного типа, нам нужно найти соответствующий элемент в списке идентификаторов строк в соответствии со значением индекса в списке идентификаторов типов.Строк строки, соответствующий смещению, хранимому в этом элементе, является строкой этого типа. описание.

Область идентификатора прототипа метода

Этот блок представляет собой список идентификатора прототипа метода, формат данных:

14212771-c183fe93d5e41ea2.png

Область идентификатора участника

В этом блоке хранится список идентификаторов прототипов, формат данных:

14212771-cb2d6a1185508125.png

Область идентификатора метода

Этот блок хранит список идентификаторов методов, формат данных: Этот блок хранит список идентификаторов прототипов, формат данных:

14212771-ab4b9c20ccf6ba45.png

Область определения класса

В этой области хранится список определений классов. Конкретная структура данных выглядит следующим образом:

Читайте также:  Php удалить все переменные сессии

14212771-eff7569e50235f1c.png

Инструменты для разбора файлов dex

Вот инструмент 010 Editor, который может анализировать файлы dex. Это позволяет нам лучше понять формат файла dex с помощью предустановленных шаблонов.

14212771-73c4b76e5a51670e.png

Применение файла Dex в Android Tinker для горячего ремонта

В текущем распространенном решении горячего ремонта Android Tinker обладает преимуществами бесплатного, открытого исходного кода и большого числа пользователей, поэтому Youzan также создает сервис горячего ремонта Android на основе Tinker. Основным принципом оперативного исправления Tinker является создание пакета исправлений путем сравнения файла dex старого APK с файлом dex нового APK, а затем синтезирование нового файла dex в приложении через пакет исправлений и файл dex старого APK. Процесс показан на рисунке ниже:

14212771-7f7a55bea0f4508a.png

Примечание: изображение с официального сайта Тинкера

Генерация патчей

Тинкер официально использует собственную схему синтеза DexDiff. Он основан на характеристиках формата файла Dex и имеет преимущества небольших пакетов исправлений и низкого потребления памяти. В алгоритме DexDiff файл Dex делится на блоки разных типов в соответствии с форматом файла Dex, как показано на следующем рисунке:

14212771-2377fcfa6d1a44f8.png

Эти блоки имеют унифицированную структуру данных, и основные данные включают в себя фактический тип данных, соответствующий блоку и смещению в файле. Как показано ниже:

14212771-781453fed223b7c4.png

При фактическом типе данных и смещении в данных блока фактические данные, содержащиеся в этом блоке, могут быть считаны из файла в соответствии со структурой данных, соответствующей фактическому типу данных. Принимая область заголовка в качестве примера, код чтения выглядит следующим образом (некоторые нерелевантные коды были удалены, и код может ссылаться на описание заголовка файла в формате файла Dex выше):

private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException

После прочтения конкретных данных каждого блока старых и новых файлов Dex из файла, вы можете сравнить и сгенерировать пакет исправлений. Поскольку структура данных каждого блока является непоследовательной, каждый блок имеет соответствующий алгоритм сравнения для обработки генерации патчей и синтеза каждого блока. Список алгоритмов показан на рисунке:

14212771-1a079eb0df47bd28.png

Эти алгоритмы сравнивают разницу между новым и старым файлами Dex после их преобразования в структуры данных, а затем генерируют соответствующие инструкции по эксплуатации, сохраняют их в файле исправлений и отправляют их клиенту.

Синтез патчей

После того, как клиент получит файл исправления, он будет использовать тот же метод чтения, чтобы преобразовать старый файл Dex в соответствующую структуру данных, а затем использовать инструкции по эксплуатации в пакете исправлений, чтобы изменить старые данные Dex, чтобы сгенерировать новые данные Dex и, наконец, данные Напишите файл для генерации нового файла Dex, завершив тем самым синтез патча.

Напиши в конце

Эта статья не содержит ничего особенно подробного и не описывает полностью формат файла dex. Главным образом, чтобы поделиться с вами общей структурой файла dex, а также некоторыми практическими приложениями. Когда в будущем вы столкнетесь с подобными проблемами, у вас могут быть некоторые указания, чтобы понять файл dex и решить проблему. Наконец, если у вас есть какие-либо предложения или комментарии, обратная связь приветствуется.

Справочные ресурсы

Источник

Оцените статью