1

logcat でランタイム メソッド呼び出しを取得できるように、各メソッドにトレースを追加する Python スクリプトを作成しています。

私のアプリケーションはいつもクラッシュします。エラー ログをコピーするように頼まないでください。それは私の質問のポイントではないからです。実際には、レジスタ宣言の直後にコードを挿入しようとしています。.locals

初めて.registersディレクティブを使用しましたが、ローカル レジスタとパラメータ レジスタのエイリアシングが原因でエラーが発生しました。

.locals代わりにディレクティブを使用できると思いましたが、まったく同じです。

私が行った別のテストは次のとおりです。

  • ローカル レジスタとパラメータ レジスタの差が 2 より大きい場合は、 と を使用v0v1ます。
  • それ以外の場合は、.localsディレクティブを 2 増やし、 and を使用v0v1ました。

しかし、VFY エラーが発生し続けます。

なぜ.locals0になることがありますがp0、たとえば次のようなパラメーターがあります。 p0でエイリアス化する必要がありますv0.locals、0 であるのに、これを.locals2 だけ変更してそのまま使用v0v1ても VFY が発生するのはなぜですか?

return ディレクティブの直前にコードを追加することを考えています。少なくとも、戻り変数でない限り、ローカル変数を変更しても問題ありません。

編集: @JesusFreke 良いコメントをありがとう。

私は現在、あなたの提案で私の python スクリプトを改善しようとしています。そのため、ルート フォルダーにコピーする CustomClass を作成しましたが、実際には、ルート フォルダー内のすべてのメソッドをループし、変数に格納するクラスとメソッド名を取得してから、このパラメーターの値を変更します。関数であり、各メソッド内で呼び出します。

しかし、実際には、新しいメソッドを入力するたびに静的関数のパラメーターの値が変化し、最後に入力した最後のメソッドの値のみが保持されるため、機能しません。

この場合、約 40.000 の smali フォルダーにあるメソッドと同じ数の静的関数を生成する必要があります...

これは私のコードの一部です:

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 に答える