Смали лучшее место для ввода кода
Я делаю скрипт Python, чтобы добавить трассировку для каждого метода, чтобы иметь возможность получить вызов метода во время выполнения в logcat.
Мое приложение все время падает, не просите меня скопировать вам журнал ошибок, потому что это не главное в моем вопросе. На самом деле я пытаюсь ввести свой код сразу после объявления реестра: .locals
Первый раз я использовал .registers
директивы, но получили ошибки из-за совмещения локальных регистров и регистров параметров.
Я думал тогда, что я мог бы использовать .locals
директива вместо этого, но это точно так же.
Другой тест, который я сделал, был следующим:
- Если разница между локальным и регистров параметров была больше, чем 2, я использую
v0
а такжеv1
, - Остальное я увеличил
.locals
директива на 2, и я использовалv0
а такжеv1
,
Но я продолжаю получать ошибки VFY.
Почему иногда .locals
равно 0, но есть такие параметры, как p0
например. p0
должен быть псевдоним v0
но .locals
0, так почему, если я изменю это на .locals
2 и просто использовать v0
а также v1
Я все еще получаю VFY?
Я думаю добавить свой код непосредственно перед директивой возврата, по крайней мере, не будет иметь значения, если я изменю локальную переменную, если она не является возвращаемой переменной
edit: @JesusFreke спасибо за ваши хорошие комментарии.
В настоящее время я пытаюсь улучшить мой скрипт на Python с вашим предложением. Поэтому я создал CustomClass, который копирую в корневую папку, но факт заключается в том, что я зацикливаюсь на всех методах в корневой папке, я получаю имя класса и метода, которые я сохраняю в переменных, а затем меняю значение параметров этого функция, и я вызываю его внутри каждого метода.
Но дело в том, что он не может работать, потому что значения параметров статической функции меняются каждый раз, когда я вношу новый метод, и в конце он будет сохранять только значение последнего метода, в который я вошел.
В этом случае мне нужно будет генерировать столько статических функций, сколько у меня есть методов в папке smali, которая составляет около 40.000...
Это часть моего кода:
def edit_custom_class(custom_class_path, my_tag, my_message):
with open(custom_class_path, "r+") as file:
for line in file:
if ('const-string p0' in line):
file.write('\tconst-string p0, "{0}" \n' .format(my_tag))
elif ('const-string p1' in line):
file.write('\tconst-string p1, "{0}" \n' .format(my_message))
else:
file.write(line + '\n')
def process_file(file_path, custom_class_path, my_tag, file_metadata):
is_inside = False
valid_registers = []
with open(file_path, "r+") as file:
for line in file:
# we get the data concerning the method and mark it as a treated method
if (('.method' in line) and (helper.is_valid_class_or_method_directive(line)) and (is_inside == False)):
is_inside = True
method_data = get_method_data(helper.get_class_or_method_name(line), file_metadata)
my_message= (method_data[0] + '->' + method_data[1])
file.write(line + '\n')
elif (('return' in line) and (is_inside == True) and (method_data[4] == False)):
edit_custom_class(custom_class_path, my_tag, my_message)
file.write('\t# has been edited by smali-rmc-interceptor on {0} \n' .format(time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())))
file.write('\t# start editing \n')
file.write('\tinvoke-static, {0};->e(Ljava/lang/String;Ljava/lang/String;)I \n' .format(custom_class_path))
file.write('\t# end editing \n')
file.write(line + '\n')
elif (('.end method' in line) and (is_inside == True) and (method_data[4] == False)):
is_inside = False
method_data = []
file.write(line + '\n')
else:
file.write(line + '\n')
И мой контент CustomClass:
.class public LCustomClass;
.source "CustomClass.java"
.method public static add_trace()V
.locals 0
.parameter "tag"
.parameter "message"
.prologue
.line 10
const-string p0, "my_tag"
const-string p1, "my_message"
.line 15
invoke-static {p0, p1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
.line 18
return-void
.end method
1 ответ
В общем, проще всего избежать выделения новых регистров в существующем методе. Это приводит к целому ряду проблем из-за ограничений регистра многих команд.
Лучше всего создать отдельный статический вспомогательный метод, который принимает некоторые значения и распечатывает их или все, что вы хотите сделать, а затем просто вводите статический вызов метода в метод, который вы хотите использовать, без выделения каких-либо новые регистры.