I use a c++ native Library in my Android project, but when Proguard is Enabled, the app crashes. My code in c++ depends on the packagename, so I need to prevent the packagename from being renamed by Proguard.
I used this rule so far, but it's not working:
-keepclasseswithmembernames class * {
native <methods>;
}
I appreciate you support.
Try this configuration to prevent specified package names from being obfuscated.
-keeppackagenamesĀ [package_filter]
A filter is a list of comma-separated names that can contain wildcards.
Related
In my application I want use this library : https://github.com/xmuSistone/AndroidPileLayout
And I want use proguard in my project, when proguard my project show me may bugs.
For fix proguard, the library developer say:
proguard works wrong when you are using java.lang.reflect api, please
check your own code.
How can I fix it and keep java.lang.reflect?
Please help me
Reflection will need to have absolute path the the classes and its respective methods. So, you need to tell proguard to leave the stuff you need alone. You can describe this in your proguard-rules.pro file.
Example:
-keep public class fully_qualified_classname
-keepclassmembers public class fully_qualified_classname {
# will ignore all methods
public <methods>;
public static final String static_instance_variable_if_any;
}
I've checked here and it seems to be no answer for my particular question. I got to know that I one can use C .so library and refer the methods in it by somewhat overriding the library native methods like below:
#SuppressWarnings("JniMissingFunction")
public class MyNativeMethods {
static {
System.loadLibrary("libraryWithSoExtension");
}
public native boolean init();
}
My probelem is that I'd like to call the constructor in this lib. The lib contains only couple of classes, where each of them contains 1 or 2 methods. I see from here:
How to call methods on .so library in Android studio
that I do not need any h, c or jni (do I really?).
Questions:
Could you confirm that I do not need any JNI files to access native methods from .so file?
Can one actually access a constructor as described above and how does the importing work if it's possible
MAVEN/GRADLE - Is it correct that a will not work for .so file? And it's equivalent in gradle also?
Thank you in advance.
If you have a prebuilt .so file that implements some native methods, you don't need its sources to build your project in Android Studio.
The catch is that the names of native methods and classes that contain these methods are hardcoded, e.g. Java_com_example_test_MainActivity_stringFromJNI exported function in a shared library libmy.so is fit to
package com.example.test;
public class MainActivity extends Activity {
static {
System.loadLibrary("my");
}
public native String stringFromJNI();
}
and not some other Java class or method (there are tools to make such reverse engineering harder).
You can use the javah command to generate C declarations for your native methods, but it cannot reverse engineer the Java class that fits given library. But it will let you declare a native constructor, if you really want one.
Gradle plugin for Android Studio will pack the so files from src/main/jniLibs into your APK, unless you set a different jniLibs.srcDir directory in your build.gradle.
I am not sure whether this is what you are looking for, but take a look here:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo025
you will find there super simple code with C++ being called via JNI wrapper from Java.
Say an Android app uses a jar library and everything is working fine when the library is specified as a dependency:
dependencies {
...
...
compile 'org.example:example:1.1.1'
...
}
BUT : one of the classes in the org.example code needs to be tweaked.
One approach is to obtain the source code and put all of that in the java folder, and remove the module. When the tweak is made, that, and the entire library will be compiled.
Another approach is to make the tweak, compile, and replace the .class file within the .jar file.
Both of those methods have their drawbacks.
My question is: Is there an easier way to tweak code in a library?
When I tried just creating the package, placing the class that needed changing into the java folder, I got an error:
Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define Lorg/example/ClassNeedingChange;
I just wondered if there was a trick to getting code in the Java folder to override whats in a library jar file.
Additional Info:
Although not stated specifically above, the class that needs tweaking is buried in the library and is referenced by the library's code; I don't call it directly. For the simple case where the class that needed tweaking is one that my code (and only my code) called directly, then it would be a simple matter of extending the class using the Java construct. But for this simple case, I would not need to post this question.
Extend the class that needs tweaked in your code, and override the appropriate method.
Class A extends TweakMe {
#Override
public void someTweakedMethod() {
//Do stuff
}
}
I've been trying to use ProGuard to obfuscate an application of mine. I have disabled every option exception for obfuscate. Loader is my main class.
The screenshot below is the result when I try to run my obfuscated jar.
No errors were given while obfuscating either.
My config
-injars 'C:\Users\Corsair\Desktop\obfuscate\Example.jar'
-outjars 'C:\Users\Corsair\Desktop\obfuscate\ExampleOut.jar'
-libraryjars 'C:\Program Files\Java\jre1.8.0_91\lib\rt.jar'
-dontskipnonpubliclibraryclassmembers
-dontshrink
-dontoptimize
-dontusemixedcaseclassnames
-dontpreverify
-dontnote
-dontwarn
-verbose
-keep class Loader
If this is the only configuration that you are using, also native methods will get obfuscated. As a result, their name will not match the ones in the native library anymore, and thus you will see an error like this when trying to load the library using System.loadLibrary.
You need to add at least a rule like this:
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
This will instruct ProGuard to keep all native methods in any class it processes.
Edit:
Additional rules that are needed to get it working:
Remove -dontpreverify, preverify is needed for Java 7+
Keep the main method
This will keep the main method:
-keep class Loader {
public static void main(...);
}
You have to exclude certain classes from obfuscating like bean classes, callback classes and native classes. In the official examples the following is mentioned:
Processing native methods
If your application, applet, servlet, library, etc., contains native methods, you'll want to preserve their names and their classes' names, so they can still be linked to the native library.
-keepclasseswithmembernames,includedescriptorclasses class * {
native <methods>;
}
Note: We don't want to preserve all classes or all native methods; we just want to keep the relevant names from being obfuscated.
Processing callback methods
If your application, applet, servlet, library, etc., contains callback methods, which are called from external code (native code, scripts,...), you'll want to preserve them, and probably their classes too. They are just entry points to your code, much like, say, the main method of an application.
-keep class mypackage.MyCallbackClass {
void myCallbackMethod(java.lang.String);
}
Processing bean classes
If your application, applet, servlet, library, etc., makes extensive use of introspection on bean classes to find bean editor classes, or getter and setter methods, then configuration may become painful. There's not much else you can do than making sure the bean class names, or the getter and setter names don't change
Helpful: to use wildcards in class names and method signatures
-keep class mybeans.** {
void set*(***);
void set*(int, ***);
boolean is*();
boolean is*(int);
*** get*();
*** get*(int);
}
Also some other scenarios (Ressources, Serialization classes) can lead to problems. Please refer to the whole guide for these
ProGuard Official: Examples
I want to use ProGuard for my android app, but I have some trouble with it. When I build an unsigned apk via android tools (in eclipse) I got following errors:
Warning: com.millennialmedia.android.NVASpeechKit$7: can't find referenced class com.nuance.nmdp.speechkit.Recognizer
[...] //more warnings of the same type as above
You should check if you need to specify additional program jars.
Warning: there were 170 unresolved references to classes or interfaces.
You may need to specify additional library jars (using '-libraryjars').
java.io.IOException: Please correct the above warnings first.
at proguard.Initializer.execute(Initializer.java:321)
at proguard.ProGuard.initialize(ProGuard.java:211)
at proguard.ProGuard.execute(ProGuard.java:86)
at proguard.ProGuard.main(ProGuard.java:492)
I'm using 5 jar files within my app, which are all located in the libs-folder and are added to the build-path (So they propably appear in 'Referenced Libraries' as well as 'Android Private Libraries' again). Additionally, I put a so-library in libs/armeabi...
My proguard - file look pretty normal, yet:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontpreverify
-dontskipnonpubliclibraryclasses
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** e(...);
}
What should I do to fix this error?
regards
PS: I know that proguard can delete/change some important things (like class-files,..). So, will I notice such 'errors' by exceptions immediately when starting my app or do I have to check every detail and navigate to any part of my app at runtime to make sure that it runs as it should?
EDIT:
I'm using following jars:
alljoyn.jar (there's also a path varibale in linked resources to the alljoyn-sdk)
peergroupmanager.jar
android-support-v4.jar
MMSDK.jar
GoogleAdMobAdsSdk-6.4.1.jar
From http://docs.millennialmedia.com/android-SDK/AndroidFAQ.html
I am using ProGuard with my Android application, what should I do to ensure my Millennial ads still work?
To make sure you still receive ads while using ProGuard, add the following snippet to your proguard.cfg file.
-keepclassmembers class com.millennialmedia.android.* {
public *;
}
-keep class com.millennialmedia.android.**
When using ProGuard and not SpeechKit, add the following line to their proguard-project.txt:
-dontwarn com.millennialmedia.android.NVASpeechKit*