2013-09-25 113 views
5

我有混淆的問題。爲了更好地想象:JNI proguard obfuscation

Java代碼

class JniTest... 

public void test() 
{ 
    //some code 
} 

public void runJniCode() 
{ 
    //here I call native code 
} 

本地代碼,直到我要發佈一個模糊版本

JNIEXPORT void JNICALL 
Java_path_to_class_test(JNIEnv* env, jobject obj) 
{ 
    //here I call test method from Java 

} 

,一切工作正常。這個類中的Java類(例如JniTest)和方法test的名稱被proguard重命名爲「a」和「a()」(這可能不總是相同的),但在本地代碼中,方法的原始名稱和類保持,因爲它被硬編碼爲一個字符串,如:

jmethodID mid = env->GetMethodID(cls, "test", "someSignature"); 

...有什麼方法可以動態設置方法名嗎?

+0

嘿,你有沒有找到解決辦法? –

+0

不,我必須更改proguard中的設置以保留此方法:( – cecan89

回答

5

在研究這個完全相同的問題時,我遇到了一個我認爲合理的解決方案。不幸的是,該解決方案不會自動混淆本地Java代碼和JNI方法,但我仍然認爲它值得分享。從源

引用:

我在這裏一個簡單的一招,其允許JNI層的模糊,重命名的方法名無意義同時在Java和本機側的名稱,同時保持源代碼相對可讀性和可維護性,而不會影響性能。

讓我們來看一個例子,初始情況:

class Native { 
    native static int rotateRGBA(int rgb, int w, int h); 
} 

extern "C" int Java_pakage_Native_rotateRGBA(JNIEnv *env, jclass, int rgb, int w, int h); 

在上面Proguard的例子不能混淆方法名rotateRGBA,這在Java端和本機端仍然可見。

解決方案是在源代碼中直接使用無意義的方法名,同時注意最小化破壞代碼的可讀性和可維護性。

class Native { 
    private native static int a(int rgb, int w, int h); //rotateRGBA 

    static int rotateRGBA(int rgb, int w, int h) { 
     return a(rgb, w, h); 
    } 
} 

// rotateRGBA 
extern "C" int Java_pakage_Native_a(JNIEnv *env, jclass, int rgb, int w, int h); 

的JNI方法被重命名爲無意義的一個。但是Java方面的調用被有意義的方法rotateRGBA封裝。 Java客戶端像以前一樣繼續調用Native.rotateRGBA(),而不受重命名的影響。

有趣的是,新的Native.rotateRGBA方法不再是原生的,因此可以隨意將其重命名爲Proguard。結果是名稱rotateRGBA完全從混淆代碼中消失,在Dalvik和本機端。更重要的是,Proguard優化了包裝方法,從而消除了包裝本地調用的(可忽略的)性能影響。

結論:從被混淆的代碼(包括Dalvik字節碼和本地庫)中消除了JNI方法的名稱,對可讀性和最小的影響都沒有影響。

來源:Obfuscating the JNI surface layer

我仍然在尋找一個工具,它可以自動混淆本地Java代碼以及相關的JNI。

+1

請引用您的答案中的鏈接頁面,以防止目標網頁發生變化 – mhlester

+0

啊,我在創建原始帖子時考慮過這個問題,但決定不遵守它原作者和簡潔的利益。如果鏈接失敗,這個答案將變得毫無用處的理由,儘管如此,謝謝你的提示! – AndrewJC