I have one critical issue to solve. I have one critical application written in JAVA, Build executable JAR file out of it and now using launch4J to warp it in EXE for Windows.
My main aim is to hide JAVA code/Classes from the user as it contains some algorithms and info which is sensitive.
The problem I am facing here is explained step by step:
1) I have One JAVA Application
2) From IntelliJ, I have created an executable JAR file from my project which has main() method and other critical algorithms implemented.
3) To protect my Java Code from reverse engineering, I have used launch4J utility and I got one EXE file as an output
4) Now during testing I have right Clicked on this EXE file and Extracted using WinZip. (By selecting Extract here... option)
5) Now I can see all the classes extracted from the JAR file I have provided to build EXE.
6) By this, Now my code is clearly visible. ( Even after Obfuscation, Some keys (Strings) are visible which is a kind of sensitive info for our project)
Solution I am looking for
1) Can I encrypt my JAR file in such a way that, No one will be able to read the code (I know obfuscation is the way, but to as JVM will not understand machine level code, somewhere code has to be translated to byte code and that will be visible through java class de-compiler), but if still there is any other way to do this?
2) Is it possible to protect EXE to get UnZipped?
3) Can I protect my EXE to be unziped by using some Password?
4) Any IntelliJ plugin to build EXE file from java code? (Ahead Of time compilation I am talking about)
5) Any other possibility?
Related
I'd like to share how I implemented a solution to a problem I had, to get some feedback and maybe learn some new feature of buildbot.
Scenario:
Create a package of a given software, and upload the package to the buildmaster into a shared folder.
The package name contains some data that are known to the build system (i.e. Makefiles) specifically the sw version. Let's assume the package name is:
myapp-1.2.3-r2435.tar.gz
Question:
How do I send to the buildslave steps the required to build up the very same package name, so that the buildslave can upload the package?
Specifically I need to know the version number (but I guess this could be any param)
Implemented (and working) solution:
The makefile, once the compilation process is completed, writes a file with the required param.
The slave uses the SetProperty() step to read the content of the file into a custom named property
Once I have the value of interest in the property (let's say APP_VERSION) I use it to build the package name with the same pattern used by the build system.
The described solution works, but I do not really like it because:
1) it's complicated, hence, I guess, fragile
2) it is not OS independent (I use "echo $VAR > file" to write the file, and "cat file" to read it and set the buildslave Property)
Is there in your opinion a better way to solve this issue?
Do you have any suggestion to make the solution OS independent? (It will not work for sure on Windows, while my package shoudl be built on Windows OS too)
I'm trying to export my program as a runnable jar, packing the necessary libraries (Apache POI). The .jar is created, but it doesn't work. Is there a catch on deploying with these libraries? Because the program itself runs great from eclipse.
A few questions to ask yourself in this situation:
Where does the program fail? Are there any errors in the console? Are you running from the command line (java -jar myJAR.jar) so that you can see console output?
Okay, so you get a NullPointerException for the read file. Is the read file inside the JAR, or where is it? How does the program know where the read file is?
Is there really a problem with the way the JAR is packaged, or is it the way your code locates and reads in the file? Perhaps your code assumes a relative location which cannot be resolved when run from the JAR.
There are the following strategies.
Create your jar. Put it to chosen directory. Put there all dependencies of your application. Create script (shell script, batch file etc depending on your platform) where the java command line is either written hard coded or is generated. The line must include the class path, e.g.
java -cp myapp.jar;poi.jar com.company.MyMain
Create indeed runnable jar, i.e. jar that can be executed using command like java -jar myapp.jar. If your application has dependencies this jar must have MANIFEEST.MF file that defines class path using property Class-Path
Pack all your classes and all your dependencies into one large jar file.
Obviously all these operations should be automated either home made script or by one of available build tools.
HOW I CAME ACROSS THIS
I wrote code for a simple stopwatch which can also double up as a Rubik's cube timer. The source code and the executable are here:
Cube timer
Anyway my doubt is not regarding this code(It works fine).
I downloaded the executable that I had uploaded to check if it worked fine and at that time I was greeted with this screen:
Open file - security warning
And under this dialogue box there was a field that said:
Publisher : Unknown Publisher
SCREEN SHOT:
DOUBT
Is there some way programatically or otherwise by which I can change the publisher field?
SPECS
I have compiled the code with Microsoft Visual C++ 2010 Express.
You can easily change the publisher, either when linking/compiling by setting the appropriate resources for your project (e.g. CompanyName), or modifying the resources with a resource editor.
Your problem is really that there is no signature, so even if a publisher field is present it cannot be trusted.
You can find an example resource rc file near the end of http://msdn.microsoft.com/en-us/library/windows/desktop/aa381058%28v=vs.85%29.aspx.
To add resources to your VC project check:
How do I embed version information into a windows binary?
VC++ 2012: How to include version info from version.inc (maintained separately) into the .rc file
The .rc file(s) will be compiled to binary (.res) and linked into your final executable.
To add or modify an existing executable, you should be able to use this tool (login required, this will cause the signature to be invalid in an already signed binary of course).
The Microsoft Authenticode documentation includes tutorials.
CAcert.org will sign a certificate you can use, and have instructions for getting started with Authenticode.
Sorry I can't be more helpful with VC, I don't use it, I usually using mingw and make, from some time ago targetting win32:
given a VERSIONINFO in a text version.rc file use mingw32-windres to compile it to a .o file (I actually had a bunch of .rc files, they were each #include-d in a single resources.rc so I only needed to run windres on that single file, and link a single extra object file)
include that version.o (or combined resources.o) in the final CC command, assuming compile and link to executable in one step
I also included -lversion when linking, AFAIR this was just because I used GetFileVersionInfo() for the code to check and display its own version in the 'About' dialog.
Make your program in a batch file, then using Advanced BAT to EXE Converter, convert it to EXE & fill out all of the fields. This sure helped me! :)
I'm working on a Java ME/J2ME project which makes use of the Bouncy Castle J2ME library. When adding it to my project, however, I've noticed the resulting .jar file size increases 40 times (50kB vs. 2000kB). Other than setting ProGuard's obfuscator settings to level 9 (max), is there any other way I can minimize this increase in file size?
I'm only using a few of the libraries actual classes, namely:
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.crypto.digests.SHA256Digest;
Thanks in advance.
Now this is a very tricky one!
Before anything else please can you unzip your jar file and see if the Proguard has obfuscated the class files of BouncyCastle? Since you have included bouncycastle jar file as a library and there are class files in it so I am assuming the Proguard hasn't obfuscated these class files which are taking much of the space.
Anyways I have just downloaded the bouncy castle jar file and can see it is purely made up of class files, so there are no extra files which we might be able to delete and get rid of to reduce the resultant jar file.
Now If you really want to reduce then read on I am going to produce two solutions, both of them are risky:
Solution 1 (Not Recommended):
This is easy but I wouldn't recommend, It may cause runtime exceptions or errors:
Unzip the bouncycastle jar file. Then navigate to the directory src\org\bouncycastle
As you have mentioned you are only using these below packages
org.bouncycastle.util.*
org.bouncycastle.crypto.*
Now here I will be assuming that the source code inside these two packages is not dependant on the source code/class files inside other packages.
Now delete the other directories namely "asn1", "bcpg". At this stage I will not become a butcher and delete everything but will go by deleting a couple and then come back and delete others if it worked.
Now we will regenerate the jar file. After you have deleted the directories now go back to the root of the directory where you will see other directories like
META-INF
org
utils
This is an important step you need to this correctly otherwise jar file will not work. Select all the directories in the root directory and
then right click-> send to zip
Once the zip file is created then rename it to having *.jar instead of *.zip
The size of the jar file would have reduced and now include this jar file in your project. See if it compiles and executes. Then check
your functionality if it is working correctly at Runtime. If all goes fine, then you are done.
Now you can repeat from above steps to delete further directories to reduce the jar file size.
Solution 2:
Download the source code of the bouncycastle jar file that you are using.
You will have to remove the jar file from the project.
Include the source code into the project. Build the project and see if you dont get any compilation error. You have to be sure at this stage
that you are not using the original jar file, and only using the code.
Now start deleting the packages containing code that you dont need. Keep rebuilding the project that it doesn't come up compilation error,
and if it does then you dont want to delte that package and move on deleting others.
Once this butchring is done then Build the project and generate the jar file.
By this way the Proguard will obfuscate code of bouncy castle and because of deleting most of the code not needed you should get a substantial
decrease in the resultant jar file.
I'm trying to programmatically find the full path of a jar file while it's running. I know there are a number of other questions about this, but none of them seem to work for me - most notably, I've stumbled across
MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().gĀetPath()
a number of times. That particular method works for me when debugging in Eclipse, but once I compile to a jar, it returns a NullPointerException. Other methods have met similar problems after compiling.
I have a temporary workaround by using java.class.path, but that only returns the full path when I execute the jar from the GUI - in the terminal, it fails.
I should also note that the only system that I'm having this problem on is Linux. On Windows and Mac, I have no troubles.
Any help would be appreciated :)
Thanks!
Derek
EDIT: The jar is executable, if that changes anything.
You can't do it. There is no requirement for ClassLoaders to support this, and most don't.
Or, perhaps this formulation would be more helpful. Binary classes come into the JVM via ClassLoader objects. ClassLoader objects are not required to keep any track of the provenance of the classes they load. And they can load them from anywhere: a jar, over the web, a database, an old tin can.
So, if you want to always know the provenance of classes in your application, you have to always load code with a class loader that, indeed, does track provenance in a manner useful to you.
If you control the entire application, you can do that.
If you don't control the entire application, and are rather talking about an arbitrary jar loaded into an arbitrary class loader in an arbitrary app, you can't depend on learning its location.
The following works for me even when running from a jar file:
URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation();
String p = URLDecoder.decode(url.getFile(), "UTF-8");
File jarFile = new File(p);
Sending the path through the URLDecoder is important because otherwise a pathname with %20 in it will be created if the directory contains spaces.