I'm wondering if someone can tell me how to obfuscate a single file, or maybe just two files, inside a jar file using proguard. I'm hoping that keeping every single class but the one i want to obfuscate isn't my only option, where as that takes a ton of time and is very tedious.. So, Is it possible to only obfuscate a single class? If so, how.. Thanks in advance!
Obfuscating a single class is generally not very useful: it will be easy to find and easy to reverse-engineer, since other classes and references to them remain readable. ProGuard therefore obfuscates all classes (except the specified ones) by default.
That being said, this should work:
-keep class !mypackage.MySecretClass, !mypackage.MyOtherSecretClass {
*;
}
It preserves the class/field/method names of all classes except the specified one. In other words, it only obfuscates the specied classes.
You can exclude all the items except the ones you want to obfuscate; see How to keep/exclude a particular package path when using proguard?
If that doesn't seem practical, a workaround would be to package the files you want to obfuscate in their own jarfile, run ProGuard, then repackage those files with the other files you want to include in a new jarfile.
Related
By now I can keep some classes and methods etc via proguard, now that obfuscation works perfectly here is my question, I've noticed proguard happens to repackage some classes like this com.a.a, com.a.b, is there a way to avoid leaving hints like com.x.x and put all of the obfuscated classes in one package like a.a.**? (real life example of a hint I've seen looks like org.apache.a.x, anyone decompiling my code will immediately skip that particular package because it reeks of library jar, i want to merge obfuscated library and obfuscated original code into one package). i tried this config but it didn't work.
-allowaccessmodification
-mergeinterfacesaggressively
-useuniqueclassmembernames
-keeppackagenames doNotKeepAThing
-repackageclasses
this didn't put obscufated classes on a particular package, but this is what I intended to do, the remaining packages you see there are the ones I've explicitly kept, also if you have resources (files) embedded in a package those would still be retained in it original package structure but their obscufated .class files will be moved to the root
Update 1
yes you can, code below will move obfuscated classes from root to package a.a
-repackageclasses a/a
I have several interfaces (e.g. mypackage.IMyInterface) which are implemented in multiple software modules. On the other hand, I use a build script that puts these modules in seperate jar files (for versioning reasons).
Would it be "ok" to include the same interface in each individual jar file.
Just to make myself perfectly clear. The package mypackage would be included in all jar files, and they would all have a copy of the exact same mypackage\IMyInterface.class file.
I've seen this practice in some open-source jar files. But I'm not sure if it's good practice or if it happens by accident.
This is a bad practice.
A package shouldn't be shared between different jars.
At least an interface (or a class) should not be copied in multiple jars.
The best is to extract common interfaces (and classes) and put them in a separate jar and import that jar everywhere it is used.
So going from this situation:
mylibfirst.jar (jar1):
com.mygroup.mylib.MyCommonInterface
com.mygroup.mylib.MyClass1
mylibsecond.jar (Jar2):
com.mygroup.mylib.MyCommonInterface
com.mygroup.mylib.MyClass2
To the following:
mylibfirst.jar (Jar1, using mylib.jar):
com.mygroup.mylib.first.MyClass1
mylibsecond.jar (Jar2, using mylib.jar):
com.mygroup.mylib.second.MyClass2
mylib.jar (Jar3):
com.mygroup.mylib.MyCommonInterface
i want to compile child.java class an get child.class, child class extends parent class.
i want child.class include all necessary code from parent class, in fact i can use it independently.
is it possible?
second Question: suppose we have a .jar library containing a.class , b.class , c.class ... i have make an updated version of a.class, how can i replace the new one with the original a.class in jar? is it possible ?
sorry for bad English.
1) as Dmitry mentioned in the comment is impossible. Even if your parent class did absolutely nothing it's definition will still be checked, and if not found ClassNotFoundException (or similar) will be thrown
2) Is certainly possible and usefull in some situations (patching external library without recompiling everything from sources comes to mind) - see Is there are way to patch jar files?
Specifically the most usefull (IMO) is CoolBeans's answer:
jar uf test.jar com\test\Test.class
Note that you have to take care of correct packaging. And it will not work if the jar is signed.
Java class files inside jars can be easily replaced and modified. For instance, the following command can be used to replace a compiled class file within a jar:
jar uf JarFile.jar com\something\Class.class
If the class file was replaced with a file such that no dependencies were broken, then the code is still able to execute. The same happens with class files that are not inside jars.
Is there any way to validate a set of class files (whether inside a jar or not) to see if all their dependencies are present and not broken?
I do not want to prevent class files from being modified but rather to be able to verify that changes are valid (with respect to dependencies). The compiler does this check (dependency-check) at compile time, but once the classes are compiled, how can one verify the class files themselves?
You might have sealing and signing JARs in mind.
Update:
Apparently I've missed the mark with my first guess.
What do you plan to do if they're not? If they're a 3rd party, I'd say that you've got little choice besides reporting to the bug database that the download is bad.
If you mean "I want to make sure that all their 3rd party JAR dependencies are correct", you've got a much bigger problem. Most downloads that I know of (e.g. Spring) make dependencies available using Maven. That's the best you can do.
If you mean you want to check your own dependencies, I'd say that testing would reveal any errors you've made.
Just loading the class will ensure that.
no, you cannot.
at least: not really.
the problem is that java loads classes at runtime only when needed. so eventually it might be alright to remove a class from the jar file and as long as no code referencing that class is executed things run very smoothly.
consider this example:
class A{ public static void main( String args[] ){ out.println( "hello" ); } }
class B{}
compile this, put it in a jar, remove the B.class from it, no problem there :)
now you might think you can go through each .class file, check what classes it references and see if the files are all there. not only is this painful, it is also incomplete. you will never quite catch files loaded with reflection because their class names might be constructed just at runtime.
my advice: don't go there. if someone removes a class file it's their own fault.
the best thing you can do is (but only if this really really worries you) try to catch ClassNotFoundExceptions at runtime (look into thread.setUncaughtExceptionHandler)
I am new to java.My friend asked me this question today And i am looking for an answer to it.
How to make the number of class files in a package, constant?
i.e., even though one can access that package,they should not be able to add any new class to the exisiting package.
You want sealed packages. Once sealed, all classes from a package must come from the same JAR file. It basically boils down to adding the package to the manifest:
Name: myCompany/myPackage/
Sealed: true
See Sealing packages within a jar file
This is called sealing the package and works on the level of jar files.
From the official trail:
Packages within JAR files can be optionally sealed, which means that all classes defined in that package must be archived in the same JAR file. You might want to seal a package, for example, to ensure version consistency among the classes in your software.
To clarify: Since the classes must come from the same jar file, no one can add classes to your package, since the new classes wouldn't come from your jar file.