Привет, я пытаюсь понять, как правильно увеличить регистры в виртуальном методе 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();
}
На смали это выглядит так
.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
Теперь, насколько я понимаю, приведенный выше небольшой фрагмент для метода toastMsg содержит всего 4 регистра.
.locals = 2 + 1 для объекта (этот) и 1 для параметра (строка 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
, или если есть, то почему регистры не сдвинуты вниз? или если все верно, то может я не тот регистр использовал и патч не туда вставил?