Привет. Я пытаюсь понять, как правильно увеличить регистры в smali виртуальном методе.Чтобы ввести код, который будет использовать новый регистр
Для справки я уже прочитал следующее: https://github.com/JesusFreke/smali/wiki/Registers
Это мой код Java:
public void toastMsg(String msg) {
Toast toast = Toast.makeText(this, msg, Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
В Smali это выглядит так:
.method public toastMsg(Ljava/lang/String;)V
.locals 2
const/4 v0, 0x1
.line 26
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 27
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 28
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
return-void
.end method
Теперь, насколько я понимаю, приведенный выше фрагмент кода smali для метода toastMsg содержит всего 4 регистра.
.locals = 2 + 1 для объекта (this) и 1 для параметра (String msg) для метода toastMsg.
Поэтому мои регистры выглядят так
v0 - free local register
v1 - free local register
v2 => p0 (this)
v3 => p1 (the string parameter - our msg)
Теперь давайте предположим, что я хочу добавить следующую строку logcat, но у меня нет свободных локальных регистров.
const-string v3, "MYAWESOMELOG"
invoke-static {v3, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
Внедрение этого кода logcat теперь, конечно, заклинило бы регистр v3, это будет работатьно значение для p1 будет потеряно, поскольку v3 == p1.
Я хочу добавить один дополнительный регистр в .locals, чтобы он мог содержать строку.и ничего не бьёт.Если предположить, что я могу просто увеличить число в переменной .locals
, это даст мне больше локальных регистров для использования.
Так что если .locals 3
регистры в этом методе теперь должны выглядеть так:
v0 - free local register
v1 - free local register
v2 - new free local register ?
v3 => p0 (this)
v4 => p1 (the string parameter - our msg)
Таким образом, локальный регистр v2 теперь должен быть совершенно новым и бесплатным, если я правильно понимаю.
Так что теперь следующий код smali для logcat, я надеюсь, может использовать новый регистр v2 для хранения тега и при этом сохранить строковый параметр (p1)
const-string v2, "MYAWESOMELOG"
invoke-static {v2, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
Таким образом, модифицированный код теперь выглядитвот так
.method public toastMsg(Ljava/lang/String;)V
.locals 3 <--- increased here by 1
const/4 v0, 0x1
.line 25
invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object p1
const/4 v0, 0x0
const/16 v1, 0x11
.line 26
invoke-virtual {p1, v1, v0, v0}, Landroid/widget/Toast;->setGravity(III)V
.line 27
invoke-virtual {p1}, Landroid/widget/Toast;->show()V
# PATCH here useing the new regiser
const-string v2, "MYAWESOMELOG"
invoke-static {v2, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
# END PATCH
return-void
.end method
К сожалению, это не так, поэтому я предполагаю, что не понял, как правильно изменять и использовать новые регистры.
Я восстановил и установил свойпример, но приложение закрывается из-за ошибки проверки класса Java.
apktool d example.apk
apktool b example -o example-modified.apk
java.lang.VerifyError: Verifier rejected class
com.example.androidtest.MainActivity: void com.example.androidtest.MainActivity.toastMsg(java.lang.String) failed to
verify: void com.example.androidtest.MainActivity.toastMsg(java.lang.String):
[0x10] register v4 has type Reference: android.widget.Toast but expected Precise Reference: java.lang.String
(declaration of 'com.example.androidtest.MainActivity' appears in
/data/app/com.example.androidtest-m1NPS9_tJaTgZLY7-1Ev6w==/base.apk)
Кажется, я что-то напутал с регистрами, но я не совсем понимаю, в чем проблема.Увеличение .locals
на 1 должно дать мне дополнительный регистр, а также автоматически сместить ссылки на параметры вниз, поэтому v4 должен указывать на p1 и быть строкой, но вместо этого он указывает на android.widget.Toast.
Так я не могу увеличить .locals
переменную в методе и использовать новый регистр?Должен ли я объявить новый регистр и инициализировать его другим способом?
Странно то, что некоторые вопросы уже указывают на ответ, что я должен на самом деле увеличить регистры.
Я вполне уверен, что файл не был дизассемблирован с помощью опции -p / - no-parameter-registers.Я просто использовал значения по умолчанию в apktool d
Smali: Увеличить количество регистров
В этом ответе также говорится, что я действительно смогу сделать это https://stackoverflow.com/a/12648626/2678928
Итак, вопрос в том, почему у меня нет нового регистра v2, когда я увеличил переменную .locals
, или, если я это сделаю, почему регистры не сдвинуты вниз?или если все правильно, то, возможно, я не использовал правильный регистр и тоже не вставил патч в нужное место?