在Android中,JNI调用可用于从其他来源加载本机代码。通过链接http://bobao.360.cn/learning/detail/3765.html,以下示例代码显示了从本地库中调用函数“ decryptString”时,smali代码的外观。

const/16 v3, 0x57
new-array v1, v3, [B
fill-array-data v1, :array_2a
.local v1, "encryptedStringBytes":[B
invoke-static {}, Lorg/cf/nativeharness/Cryptor;->getInstance()Lorg/cf/nativeharness/Cryptor;
move-result-object v0
.line 21
.local v0, "c":Lorg/cf/nativeharness/Cryptor;
# v3 contains a String made from encrypted bytes
new-instance v3, Ljava/lang/String;
invoke-direct {v3, v1}, Ljava/lang/String;-><init>([B)V
# Call the decryption method, move result back to v3
invoke-virtual {v0, v3}, Lorg/cf/nativeharness/Cryptor;->decryptString(Ljava/lang/String;)Ljava/lang/String;
move-result-object v3


原始的Java代码看起来像这样:

public class Cryptor {
    private static Cryptor instance = null;
    public static Cryptor getInstance() {
        if (instance == null) {
            instance = new Cryptor();
        }
        return instance;
    }
    public native String decryptString(String encryptedString);
}


smali代码似乎没有迹象表明正在加载本机代码。 smali代码中的哪些“签名”将很好地表明正在从原始Java代码进行JNI调用?

#1 楼

您想查看被调用方法的定义。 decryptString方法的定义将包含native访问标志,类似于其相应的Java声明。例如类似的东西:

.method public native decryptString(Ljava/lang/String;)Ljava/lang/String


此外,您还可以查找对System.loadLibrary的调用,以表明应用程序正在加载库以执行JNI调用。