2013-09-25 14 views
5

Ich habe ein Problem mit der Verschleierung. Für eine bessere Vorstellungskraft:JNI Proguard Verschleierung

Java-Code

class JniTest... 

public void test() 
{ 
    //some code 
} 

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

nativem Code

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

} 

Alles funktioniert gut, bis ich eine verschleierte Version freigeben möchte. Der Name der Java-Klasse (JniTest zum Beispiel) und die Methode test in dieser Klasse werden von proguard in "a" und "a()" umbenannt (dies ist möglicherweise nicht immer derselbe), aber im ursprünglichen Code der ursprüngliche Name der Methode und Klasse bleiben, weil sie als String fest einprogrammiert ist, wie:

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

... ist es eine Möglichkeit, den Namen der Methode dynamisch zu setzen?

+0

hey, hast du irgendeine Lösung gefunden? –

+0

nein, ich musste die Einstellungen ändern, um diese Methode beizubehalten :( – cecan89

Antwort

5

Bei der Untersuchung genau dieses Problem stieß ich auf eine Lösung, die ich für sinnvoll halte. Leider verschleiert die Lösung nicht automatisch den nativen Java-Code und die JNI-Methoden wie gewünscht, aber ich dachte immer noch, dass es sich lohnt, sie zu teilen.

Zitat aus der Quelle:

stellt ich hier einen einfachen Trick, die Verschleierung der JNI-Schicht ermöglicht, die Methodennamen umbenennen Namen bedeutungslos sowohl auf der Java und nativer Seite, während den Source-Code zu halten relativ lesbar und wartbar und ohne die Leistung zu beeinträchtigen.

Nehmen wir ein Beispiel, Ausgangssituation berücksichtigen:

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

Im Beispiel oben Proguard kann den Methodennamen rotateRGBA nicht verschleiern, die auf der Java-Seite und auf der nativen Seite sichtbar bleibt.

Die Lösung besteht darin, direkt in der Quelle einen sinnlosen Methodennamen zu verwenden, wobei die Lesbarkeit und Wartbarkeit des Codes minimal zu stören ist.

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

Die JNI-Methode A zu einem bedeutungslosen umbenannt. Aber der Aufruf auf der Java-Seite wird von der sinnvoll benannten Methode rotateRGBA umschlossen. Die Java-Clients rufen weiterhin Native.rotateRGBA() wie zuvor auf, ohne von der Umbenennung betroffen zu sein.

Interessant ist, dass die neue Native.rotateRGBA-Methode nicht mehr nativ ist und daher von Proguard beliebig umbenannt werden kann. Das Ergebnis ist, dass der Name rotateRGBA sowohl auf Dalvik als auch auf der nativen Seite vollständig aus dem verschleierten Code verschwindet. Darüber hinaus optimiert Proguard die Wrapper-Methode und entfernt damit die (vernachlässigbare) Performance-Wirkung des Wrapping des nativen Calls.

Fazit: Der Name der JNI-Methode wurde aus dem verschleierten Code (sowohl Dalvik-Bytecode als auch native Bibliothek) entfernt, mit minimalen Auswirkungen auf die Lesbarkeit und ohne Auswirkungen auf die Leistung.

Quelle: Obfuscating the JNI surface layer

Ich bin immer noch auf der Suche nach einem Werkzeug, das automatisch nativen Java-Code und die zugehörige JNI verschleiern kann.

+1

Bitte zitieren Sie die verknüpfte Seite in Ihrer Antwort für den Fall, dass sich die Zielseite ändert – mhlester

+0

Ah, ich hatte dies beim Erstellen des ursprünglichen Posts berücksichtigt, aber mich dagegen entschieden zu respektieren Der Begründer, dass diese Antwort nutzlos werden wird, wenn die Verbindung ausfällt, macht jedoch Sinn. Danke für den Tipp! – AndrewJC

Verwandte Themen