2013-09-25 3 views
5

У меня проблема с запутыванием. Для лучшего воображение:JNI proguard obfuscation

JAVA CODE

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 оптимизирует метод оболочки, тем самым устраняя (незначительное) влияние производительности на перенос собственного вызова.

Заключение: исключено имя метода JNI из запущенного кода (как байт-код Dalvik, так и родная библиотека) с минимальным воздействием на читаемость и бездействие.

Источник: Obfuscating the JNI surface layer

Я до сих пор на охоту за инструмент, который может запутать машинный код Java и связанный с ним JNI автоматически.

+1

Процитировать связаную страницу в вашем ответе, если страница назначения когда-либо изменяется – mhlester

+0

А, я рассматривал это при создании оригинального сообщения, но решил против него уважать оригинал автора и в интересах терпения. Обоснование того, что этот ответ станет бесполезным, если ссылка идет вниз, имеет смысл. Спасибо за подсказку! – AndrewJC

Смежные вопросы