2013-09-25 10 views
5

Ho problemi con l'offuscamento. Per una migliore immaginazione:JNI proguard offuscamento

codice Java

class JniTest... 

public void test() 
{ 
    //some code 
} 

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

codice nativo

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

} 

Tutto funziona bene fino a quando ho voglia di rilasciare una versione offuscata. Il nome della classe Java (JniTest per esempio) e il metodo test in questa classe vengono rinominati da proguard in "a" e "a()" (questo potrebbe non essere sempre lo stesso), ma nel codice nativo il nome originale del metodo e la classe rimane, perché è hardcoded come una stringa, come:

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

... c'è un modo per impostare il nome del metodo in modo dinamico?

+0

ehi, hai trovato qualche soluzione? –

+0

no, ho dovuto modificare le impostazioni in proguard per mantenere questo metodo :( – cecan89

risposta

5

Durante la ricerca di questo stesso identico problema, mi sono imbattuto in una soluzione che ritengo ragionevole. Sfortunatamente, la soluzione non offusca automaticamente il codice Java nativo e i metodi JNI come richiesto, ma ho comunque pensato che sarebbe valsa la pena condividerlo.

citazione dalla fonte:

Vi presento qui un semplice trucco che permette di offuscamento dello strato JNI, rinominare i nomi dei metodi di senza senso nomi sia sul Java e lato nativo, mantenendo il codice sorgente relativamente leggibile e manutenibile e senza compromettere le prestazioni.

Consideriamo un esempio, situazione di partenza:

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

Nell'esempio sopra Proguard non può offuscare il nome del metodo rotateRGBA, che rimane visibile sul lato Java e sul lato nativo.

La soluzione consiste nell'utilizzare direttamente un nome di metodo privo di significato nella fonte, avendo cura di ridurre al minimo la leggibilità e la manutenibilità del codice.

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

Il metodo JNI viene rinominato in un insignificante a. Ma la chiamata sul lato Java è racchiusa nel metodo denominato ruotareRGBA. I client Java continuano a invocare Native.rotateRGBA() come prima, senza essere influenzati dal rinominare.

Ciò che è interessante è che il nuovo metodo Native.rotateRGBA non è più nativo e quindi può essere rinominato da Proguard a piacimento. Il risultato è che il nome rotateRGBA scompare completamente dal codice offuscato, sia sul lato Dalvik che sul lato nativo. Inoltre, Proguard ottimizza il metodo wrapper, rimuovendo così l'impatto (trascurabile) sulle prestazioni del wrapping della chiamata nativa.

Conclusione: eliminato il nome del metodo JNI dal codice offuscato (sia bytecode Dalvik che libreria nativa), con impatto minimo sulla leggibilità e nessun impatto sulle prestazioni.

Fonte: Obfuscating the JNI surface layer

Sono ancora alla ricerca di uno strumento che può offuscare il codice Java nativo e associati JNI automaticamente.

+1

Si prega di citare la pagina collegata nella tua risposta nel caso in cui quella pagina di destinazione cambia mai – mhlester

+0

Ah, avevo preso in considerazione questo durante la creazione del post originale ma ho deciso di rispettarlo per rispetto l'autore originale e nell'interesse della chiarezza.Il fondamento logico che questa risposta diverrà inutile se il collegamento si interrompe ha perfettamente senso però. Grazie per il suggerimento! – AndrewJC