In Android, JNI calls could be used to load native code from other sources. From the link http://bobao.360.cn/learning/detail/3765.html, the following sample code shows how a smali code would look like when calling the function "decryptString" from a native library.

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

The original java code would look something like this:

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);

There seems to be no indication from the smali code that a native code is being loaded. What "signatures" in a smali code would be a good indicator that JNI calls are being made from the original java code?


You want to look at the definitions of the methods being called. The definition of the decryptString method will contain the native access flag, similar to it's corresponding java declaration. e.g. Something like:

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

Additionally, you can look for calls to System.loadLibrary as an indication that the application is loading a library in order to perform JNI calls.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.