Открыть Электронные книги
Категории
Открыть Аудиокниги
Категории
Открыть Журналы
Категории
Открыть Документы
Категории
Перевод
Изначальный текст на русском взят отсюда. Там текст появился из машинного перевода официальной документации.
В итоге, оформил сухой текст + поправил небольшие опечатки и корявости перевода. По поводу замечаний и предложений
можете писать либо мне в ЛС, либо оформлять PR на Gist.
Общая информация
Виды(Types)
Байт-код Dalvik имеет два основных класса типов: примитивные типы и ссылочные типы. Типы ссылок — это объекты и
массивы, все остальное является примитивным.
https://habr.com/ru/post/495024/ 1/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Z - Boolean (логический)
B - Byte (байт)
S - Short (короткий)
C - Char
F - Float (плавающий)
Объекты принимают форму Lpackage/name/ObjectName; — где ведущий L указывает, что это тип объекта,
package/name/ — это пакет, в котором находится объект, ObjectName — это имя объекта и ; обозначает конец имени
объекта.
Это эквивалентно имени package.name.ObjectName в java. Или, для более конкретного примера, Ljava/lang/String;
эквивалентно java.lang.String
Массивы принимают форму [I — это массив целых чисел с одним измерением. т.е. int[] в Java. Для массивов с
несколькими измерениями вы просто добавляете больше [ символов. [[I = int[][] , [[[I = int[][][] и т.д.
(Примечание: максимальное количество измерений, которое вы можете иметь, составляет 255).
Методы(Methods)
Методы всегда указываются в очень подробной форме, которая включает тип, содержащий метод, имя метода, типы
параметров и тип возвращаемого значения. Вся эта информация необходима, чтобы виртуальная машина могла находить
правильный метод и иметь возможность выполнять статический анализ на байт-коде
В этом примере вы должны распознать Lpackage/name/ObjectName; как тип. MethodName — это имя метода. (III)Z
является сигнатурой метода. III — параметры (в данном случае 3 целых числа), а Z — тип возврата (bool).
Lpackage/name/ObjectName;->MethodName(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/Str
ing;
Поля(Fields)
Поля также всегда указывается в многословной форме, которая включает тип, содержащее поле, имя поля и тип поля. Опять
же, это позволяет виртуальной машине находить правильное поле, а также выполнять статический анализ на байт-коде.
https://habr.com/ru/post/495024/ 2/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Это должно быть довольно очевидно — это пакет и имя объекта, имя поля и тип поля соответственно
Регистры (Register)
Вступление
В байт-коделе dalvik регистры всегда 32 битные и могут содержать любой тип значения. 2 регистра используются для хранения
64-битных типов (длинного — Long и числа с плавающей точкой — Double).
Первым параметром для нестатических методов ( non-static methods ) всегда является объект, на который вызывается
метод ( this объект)
Например, допустим, вы пишете нестатический метод LMyObject;->callMe(II)V . Этот метод имеет 2 целочисленных
( integer ) параметра, но также имеет неявный LMyObject; параметр перед обоими целыми параметрами, поэтому для
метода существует всего 3 аргумента.
Предположим, вы указали, что в методе (v0-v4) есть 5 регистров, либо с директивой .registers 5 , либо с директивой
.locals 2 (т.е. 2 local registers + 3 parameter registers). Когда метод вызывается, объект, к которому выполняется метод (т.е.
this ссылка), будет в v2, первый целочисленный ( integer ) параметр будет в v3, а второй целочисленный ( integer )
параметр будет в v4.
Для статических методов ( static methods ) это одно и то же, за исключением того, что неявный этот аргумент.
Итак, вернемся к предыдущему примеру метода с 3-мя аргументами и 5-ю полными регистрами. В следующей таблице
показано обычное имя v# для каждого регистра, за которым следует имя p# для регистров параметров ( parameter
registers )
v# p#
https://habr.com/ru/post/495024/ 3/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
v# p#
Скажем, у вас есть существующий метод с несколькими параметрами, и вы добавляете некоторый код в этот метод, и вы
обнаружите, что вам нужен дополнительный регистр. Вы думаете: «Ничего страшного, я просто увеличу количество регистров,
указанных в директиве .registers !».
К сожалению, это не так просто. Имейте в виду, что параметры метода хранятся в последних регистрах в методе. Если вы
увеличиваете количество регистров — вы меняете, какие регистры вводят аргументы метода. Поэтому вам придется изменить
директиву .registers и перенумеровать каждый регистр параметров.
Но если схема именования p# использовалась для ссылки на регистры параметров во всем методе, вы можете легко
изменить количество регистров в методе, не беспокоясь о перонумеровании любых существующих регистров.
Long/Double значения
Как упоминалось ранее, long и double примитивы ( J и D соответственно) имеют 64-битные значения и требуют 2 регистра.
Это важно иметь в виду, когда вы ссылаетесь на аргументы метода. Например, предположим, что у вас есть (нестатический —
non-static ) метод LMyObject;->MyMethod(IJZ)V . Параметрами метода являются LMyObject;,int,long,bool .
Таким образом, для всех его параметров потребуется 5 регистров:
p0 this
p1 I
p2, p3 J
p4 Z
Кроме того, когда вы вызываете метод позже, вам нужно указать оба регистра для любых аргументов с двойным расширением
в списке регистров для инструкции типа invoke.
Array (массивы)
array-length vA, vB
A : Регистр назначения (4 бита)
https://habr.com/ru/post/495024/ 4/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Заполняет заданный массив vA+ указанными данными в цели ( target ). Ссылка должна быть в массиве примитивов, и
таблица данных должна соответствовать ей по типу и размеру. Ширина массива определяется в таблице.
:target
.array-data 0x2
0x01 0x02
0x03 0x04
.end array-data
B : Регистр размеров
C : Ссылка на тип
Создает новый массив указанного типа и размера. Тип должен быть типом массива.
B : Ссылка на тип
Создает новый массив указанного типа и размера. Тип должен быть типом массива. Ссылка на вновь сгенерированный массив
может быть получена командой move-result-object , непосредственно после команды fill-new-array .
filled-new-array/range { vA .. vX }, Lclass;->type
vA .. vX : Диапазон регистров, содержащих параметры массива (по 4 бита)
Создает новый массив указанного типа. Тип должен быть типом массива. Ссылка на вновь созданный массив может быть
получена командой move-result-object , непосредственно после команды fill-new-array/range .
B : Ссылка на массив
C : Индекс в массиве
https://habr.com/ru/post/495024/ 5/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Также есть другие aget/aput , путем добавления окончания меняется тип значения:
boolean
byte
char
object
short
wide
Сравнения
Легенда:
A : Регистр назначения
Если vB+ < vC+ или vB+ > vC+ то сохраняет -1.
Если vB+ < vC+ или vB+ > vC+ то сохраняет -1.
Если vB == vC то сохраняет 1;
Если vB+ < vC+ или vB+ > vC+ то сохраняет -1.
Константы
const vAA, #+BBBBBBBB
A : Регистр назначения (8 бит)
https://habr.com/ru/post/495024/ 7/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Поместит 16-битную константу в самые верхние биты регистра vAA . Используется для инициализации значений float .
Переместит ссылку на класс ( class ), указанный в регистре назначения vAA . В случае, когда указанный тип является
примитивным, это будет хранить ссылку на особый класс примитивного типа.
Еще примеры:
const-wide/16 vA+, #+BBBB
Go To
goto — Безусловный переход к :target.
goto :target
Примечание: goto буквально использует ± смещения от текущей команды. APKTool преобразует их в метки для удобства
чтения. Если внутри кода, для смещения требуется 16-битное значение, следует использовать goto/16 , или для 32-битного
значение, следует использовать goto/32 . Почти невозможно определить, требуется ли goto/16 или goto/32 при
https://habr.com/ru/post/495024/ 8/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
добавлении новой команды (если не знаешь наверняка). Если вы точно не знаете какой бит, goto/16 может заменить любой
goto, а goto/32 может заменить любой goto/16 или goto .
Только замена не может производиться на оборот: goto не может заменить goto/16, а он в свою очередь не может заменить
goto/32.
Условия
if — Если выполняется условие, происходит переход по метке
Легенда:
Примечание: != — неравно
Примеры:
Invoke
Легенда:
https://habr.com/ru/post/495024/ 9/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
R : Тип возврата.
Вызывает нестатический ( non-static ) direct метод (то есть метод экземпляра, который по своей природе не
переопределяется, а именно либо метод private instance , либо конструктор):
Вызывает метод интерфейса ( interface method ) (то есть объект, чей конкретный класс неизвестен, используя метод,
который ссылается на интерфейс):
Вызывает статический метод ( static method ) (который всегда считается прямым методом):
Вызывает виртуальный метод ( virtual method ) (метод, который не является статическим или окончательным, и не
является конструктором):
Примечание:
Если метод возвращает значение ( R не является « V » для Void), он должен быть зафиксирован в следующей строке одним
из операторов move-result или он будет потерян.
Так-же можно не перечислять все аргументы vA-vX , а сделать диапазон аргументов (Range of arguments) путем добавления
окончание /range . Например:
invoke-direct/range { vA .. vX }, Lclass;->method()R
https://habr.com/ru/post/495024/ 10/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Прочее
check-cast vAA, Lclass
A : Референтный регистр (8 bits)
Проверяет, может ли ссылка на объект в vAA быть передана экземпляру типа, на который ссылается класс.
B : Ссылка на тип
Создает объект класса типа и помещает ссылку на вновь созданный экземпляр в vAA .
nop
Пустая команда/Нет операции
throw vAA
Выбрасывает указанное исключение. Ссылка на объект (object) исключений находится в vAA .
Move
Легенда:
Прим: A: x bits. B: x bits не является частью кода. Добавил только для обозначения бит в регистрах
move vA, vB
A: 4 bits. B: 4 bits
https://habr.com/ru/post/495024/ 11/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Делает тоже самое, что и move . Только исходный регистр и регистр назначения 16 bits
move-exception vAA
A: 8 bits
Сохраняет только что пойманное исключение в vAA . Это должна быть первая инструкция любого обработчика исключений,
чье исключение исключений не должно игнорироваться, и эта инструкция может когда-либо возникать только в качестве первой
инструкции обработчика исключений. P.S: без тавтологии никуда)
Все потоки Разработка Администрирование Дизайн Менеджмент Маркетинг Научпоп Войти Регистрация
move-object vA, vB
A: 4 bits. B: 4 bits
Делает тоже самое, что и move-object . Только исходный регистр и регистр назначения 16 bits
move-result vAA
A: 8 bits.
Переносит результат одиночного слова не объекта (non-object) из самого последнего типа invoke в vAA . Это должно быть
сделано как инструкция сразу после вида invoke , результат которого (однословный, не объект) не должен игнорироваться.
move-result-object vAA
A: 8 bits.
Переносит результат объекта из последнего вида invoke в vAA . Это должно выполняться как инструкция сразу после типа
invoke -типа или fill-new-array , чей (объект) результат не должен игнорироваться.
Остальное кратко:
https://habr.com/ru/post/495024/ 12/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Операции
Оператор ADD
Cкладывает значения по обе стороны от оператора
add-float/2addr vA, vB
A : регистр источника 1 / регистр назначения (4 бит)
https://habr.com/ru/post/495024/ 13/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
add-int/2addr vA, vB
A : регистр источника 1 / регистр назначения (4 бит)
Оператор AND
Бинарный оператор копирует бит в результат, если он существует в обоих операндах.
Оператор DIV
Делит левый операнд на правый операнд
Оператор MUL
Умножает значения по обе стороны от оператора
Оператор OR
Копирует бит, если он существует в любом из операндов.
Оператор REM
Делит левый операнд на правый операнд и возвращает остаток
Оператор SHL
https://habr.com/ru/post/495024/ 14/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Значение левых операндов перемещается влево на количество бит, заданных правым операндом.
Оператор SHR
Значение правых операндов перемещается вправо на количество бит, заданных левых операндом.
Оператор SUB
Вычитает из правого операнда левый операнд
Оператор USHR
Оператор XOR
копирует бит, если он установлен в одном операнде, но не в обоих.
Return
Оператор return используется для выполнения явного возврата из метода. То есть он снова передает управление объекту,
который вызвал данный метод. Оператор return предписывает интерпретатору остановить выполнение текущего метода.
Если метод возвращает значение, оператор return сопровождается некоторым выражением. Значение этого выражения
становится возвращаемым значением метода.
return vAA
A : Регистр возвращаемого значения (8 bits)
return-object vAA
A : Регистр возвращаемого значения (8 bits)
return-void
Возврат из метода void без значения.
return-wide vA+
A : Пара регистров возвращаемого значения (8 bits)
Switch-и
packed-switch vAA, :target
Легенда:
https://habr.com/ru/post/495024/ 15/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Реализует оператор switch , где константы case являются последовательными. Инструкция (сценарий выполнения кода)
использует таблицу индексов. vAA указатели в эту таблицу, чтобы найти смещение инструкции для конкретного случая. Если
vAA выпадает из таблицы индексов, выполнение продолжается в следующей команде (случай по умолчанию). pack-
switch используется, если возможные значения vAA являются последовательными независимо от самого минимального
значения.
:target
.end packed-switch
:target
.sparse-switch
.end sparse-switch
25,2 0,0
Карма Рейтинг
Никита Куликов @LionZXY
Software Android Engeener
ПОХОЖИЕ ПУБЛИКАЦИИ
https://habr.com/ru/post/495024/ 16/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
КУРСЫ
Android-разработчик с нуля
1 июля 2021 •
7 месяцев •
70 740 ₽ •
Нетология
Профессия Android-разработчик
12 июля 2021 •
10 недель •
46 000 ₽ •
Loftschool
Реклама
Кредит без страховок
Оформите кредит по карте "МИР". Нужен только паспорт и СНИЛС! АО
"Почта Банк".
pochtabank.ru * АО «Почта Банк». Лицензия ЦБ РФ на осуществление банковских операций № 650 РЕКЛАМА
Комментарии
0
САМОЕ ЧИТАЕМОЕ
https://habr.com/ru/post/495024/ 17/18
6/27/2021 Шпаргалка по Smali на русском / Хабр
Гайд по спасению китов, технологические кейсы и шанс увидеть вулканы: день открытых дверей в Luxoft
Обучение
Песочница Конфиденциальность
https://habr.com/ru/post/495024/ 18/18