1

我正在制作一个 python 脚本来为每个方法添加跟踪,以便能够在 logcat 中获取运行时方法调用。

我的应用程序总是崩溃,不要让我复制错误日志,因为这不是我的问题的重点。实际上,我尝试在注册声明之后立即注入我的代码:.locals

我第一次使用.registers指令但由于本地和参数寄存器的别名而出错。

我当时认为我可以使用该.locals指令,但它完全相同。

我进行的不同测试如下:

  • 如果本地寄存器和参数寄存器之间的差异大于 2,我使用v0v1.
  • 否则,我将.locals指令增加 2 并使用v0and v1

但我不断收到 VFY 错误。

为什么有时.locals等于 0 但有参数p0,例如。 p0应该被别名v0.locals为 0,那么为什么如果我将其更改为.locals2 并且只使用v0并且v1我仍然得到 VFY?

我正在考虑在返回指令之前添加我的代码,至少我是否更改局部变量并不重要,只要它不是返回变量

编辑:@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
4

1 回答 1

2

一般来说,避免在现有方法中分配新寄存器是最简单的。由于许多指令的寄存器限制,这引入了一系列问题。

您最好的选择是创建一个单独的静态辅助方法,该方法接受一些值并将它们打印出来或您想要做的任何事情,然后只需在您想要检测的方法中注入一个静态方法调用,而不分配任何新的寄存器。

于 2015-06-25T19:03:39.877 回答