Is there any way to query the name of the current method if you've obfuscated your code? I'm asking because there are times when I want to log a message with the executing method as a prefix.
Just add the method name directly to the string you are outputting. If you get the name of the current method via reflection, it will be the obfuscated name. If it was not this way, anybody would be able to figure out the original method, defeating the obfuscation (or dramatically hampering it).
Alternatively, obfuscation tools are supposed to be able to output their own obfuscation logs so you can write a tool to translate your application's obfuscated logs into something human-readable.
Of course, once you get there, development versions of your application could include the ability to access their own obfuscation logs and translate the result of reflection before they output logs.
You can have obfuscation logs on the file system, as an application resource in the jar file or download them from a remote server.
If you only keep decrypted obfuscation logs in your application memory, the VM sandbox is supposed to keep them fairly safe.
Please reconsider why you want to obfuscate. The things an obfuscator obfuscates is frequently those useful for debugging.
Related
I have a jnlp application that loads and executes a jar file ( client ) on a users computer. The user uses this jar to communicate with a server that provides a services. I've seen users using javassit and javasnoop to alter the functionality of the client. Is there any way I can remotelly detect changes created by the previously mentionted utilities ? For example, can I checksum the classes locally and send the result to the server ( who knows the correct checksum of each class ) ?
There is no way in general to prevent the client from running any code they wish to. The security of your system should never rely on assuming that clients are running specific code or are not aware of specific information contained in the jars you send them.
Furthermore, attempts to impose DRM tend to cause problems for legitimate users and alienate your customers while doing little to prevent people who actually do want to hack the system.
You can for example create a check sum of your java file and make your application to calculate the checksum at runtime and send it for verification to server. The simplest checksum is a hash code of whole jar.
The only question is why? And who is the super user that takes your jar and performs instrumentation on it? And why is he doing this? And even if he has reasons, who cares? If you are afraid that somebody is going to hack your server make it secure enough and do not care about client (IMHO).
You can open a classfile named p1.p2.ClName with Classloader.getResourceAsStream("/p1/p2/ClName.class"), read it, and compute its checksum.
But, as user can change the functionality, he can also remove that checksum checking.
Okay, so pretty much I'm trying to add security to my Java class file. I don't want it to get decompiled. So what I've done is created a login system where the java app checks it through a web request. If the login information is correct then it will run the script. However, I want to further improve security and have the class file hosted online.
How can I make it download & run the online hosted file?
Also, when the app/script stops running or it's closed the .class file is deleted.
I'd prefer where it did not have to download the file, just get from an online server and compile/run.
Let's go through the things you have done, and the things you are proposing to do and see if they will really work:
Asking for a password. This is easily to defeat:
Capture the classfile.
Decompile it.
Identify the place where it makes the remote call does the login check, and checks the response.
Modify the bytecodes to remove all of that.
Rather than installing the class file, download it on demand and delete it when it finishes. Also easy to defeat.
Capture network request made to download the file.
Replay the request using (say) curl or wget and capture the downloaded class file.
Proceed as above.
And variations are relatively easy to defeat too:
Obfuscation can always ultimately be defeated by manual decompilation and/or running the bytecodes using a debugger.
Downloading using one-time key or something can be defeated by reverse engineering the procedure and extracting the one-time key ... before it is used.
Encrypting the bytecodes can defeated because the JVM has to have the bytecodes in decrypted form at some point. So the means of decryption of the bytecodes must be embedded in code ... that can be reverse engineered.
The bottom line is that it is impossible to prevent a skilled and determined person from defeating security schemes that depend on keeping things secret from a user who controls his / her own execution platform.
The best you can hope to do is stop low-skilled attackers, and slow down skilled ones. You need to ask yourself ... is it really worth the effort?
(Note: you have the same problem no matter what implementation language you use.)
Create a new URLClassLoader (the "default" Java classloader) and point it at wherever you saved the file:
// the directory where you're saving the .class file
File tmpDir = new File("/tmp/yadda/blah/");
ClassLoader cl = new URLClassLoader(new URL[] { tmpDir.toURI().toURL() }, Thread.currentThread().getContextClassLoader());
Class<?> cls = cl.loadClass("SuperSecretClass");
// use reflection to instantiate cls, call methods, etc.
(Passing in the parent class loader might not be necessary in a non-webapp, but I'm too lazy to test that detail. Using the thread's classloader explicitly will work one way or the other.
This assumes that your secret class is not in a package, if it is you'll have to create the appropriate directory structure inside the temporary directory and point the classloader at the root of the package tree, as usual.
Also: this sort of security-by-obscurity sounds like a bad idea. You're still downloading the file, if it's over an unsecured connection a determined attacker can sniff it, and there's still the period of time during which it's on disk. You could create a completely custom ClassLoader that directly reads the stream, but even the class file could probably be recovered with a little more effort. (Like pointing a debugger at your main app and intercepting stream reads.) The javadoc for ClassLoader provides an example of how to do this.
We have used liquibase at our company for a while, and we've had a continuous integration environment set up for the database migrations that would break a job when a patch had an error.
An interesting "feature" of that CI environment is that the breakage had a "likely culprit", because all patches need to have an "author", and the error message shows the author name.
If you don't know what liquibase is, that's ok, its not the point.
The point is: having a person name attached to a error is really good to the software development proccess: problems get addressed way faster.
So I was thinking: Is that possible for Java stacktraces?
Could we possibly had a stacktrace with peoples names along with line numbers like the one below?
java.lang.NullPointerException
at org.hibernate.tuple.AbstractEntityTuplizer.createProxy(AbstractEntityTuplizer.java:372:john)
at org.hibernate.persister.entity.AbstractEntityPersister.createProxy(AbstractEntityPersister.java:3121:mike)
at org.hibernate.event.def.DefaultLoadEventListener.createProxyIfNecessary(DefaultLoadEventListener.java:232:bob)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:173:bob)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:87:bob)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:862:john)
That kind of information would have to be pulled out from a SCM system (like performing "svn blame" for each source file).
Now, forget about trashing the compilation time for a minute: Would that be even possible?
To add metadata to class files like that?
In principle you can add custom information to .class files (there's and attribute section where you can add stuff). You will have to write your own compiler/compiler extension to do so. There is no way to add something to your source code that then will show up in the class file.
You will also have major problems in practice:
The way stack-traces a built/printed is not aware of anything you add to the class file. So if you want this stuff printed like you show above, you have to hack some core JDK classes.
How much detail do you want? The last person who committed any change to a given file? That's not precise enough in practice, unless files are owned by a single developer.
Adding "last-committed-by" information at a finer granularity, say per method, or even worse, per line will quickly bloat your class file (and class files are limited in size to 64K)
As a side note, whether or not blaming people for bugs helps getting bugs fixed faster strongly depends on the culture of the development organization. Make sure you work in one where this helps before you spend a lot of time developing something like this.
Normally such feature can be implemented on top of the version control system. You need to know revision of your file in your version control system, then you can call blame/annotate command to get information on who has changed each individual line. You don't need to store this info into the class file, as long as you can identify revision of each class you deploy (e.g. you only deploy certain tag or label).
If you don't want to go into the version control when investigating stack trace, you could store line annotation info into the class file, e.g. using class post processor during your build that can add a custom annotation at the class level (this is relatively trivial to implement using ASM). Then logger that prints stack trace could read this annotation at runtime, similarly to showing jar versions.
One way to add add custom information to your class files using annotations in the source code. I don't know how you would put that information reliably in the stack trace, but you could create a tool to retrieve it.
As #theglauber correctly pointed out , you can use annotations to add custom metadata. Althougth i am not really sure you if you cant retrieve that information from your database implementing beans and decorating your custom exceptions manager.
I'm working in a project where we need to encrypt the .jar file so no one can access to the .class files which inside the jar file.... is there any java coding which can help me to encrypt the .jar file ?
Even if you encrypt the jar file, it must be decrypted before the JVM is able to run it, so you'll need another jar file containing classes that decrypt and loads in the JVM.
Since this second jar file cannot be itself encrypted, a malicious user wanting to see you class files, can simply look at classes in this second jar file, and then decrypt your super-secret jar file and have access to it.
Maybe you can increase security of your code using an obfuscator, but it will eventually protect (make it harder but not impossible) your class files from decompilation, not from being used.
If obfuscation is not enough, you could consider compiling your jar file to a DLL for windows or a SO for unix/linux, that will make it much harder to decompile, but it's not always possible to do that correctly and it's generally a PITA. GCJ is able to do this somehow, and there are other commercial products that will actually compile .class/.jar directly to machine code.
However please consider that it does not matter how much security you put in it, since the client computer MUST be able to execute it, it must be able to read it, so no matter what your code will be exposed, you can only make it harder.
If you really have an algorithm so secret you don't want to disclose no matter what, consider converting it to a web service, hosting it on your server, so that you don't have to send the actual code to the client machines and can also better prevent unauthorized copies of your application by checking access to that vital part of it.
I assume you are aware of the fact that any skilled java coder can reverse-engineer the Java tool you use (or write) and still decode the app's jars? Also writing custom classloaders which read your "encrypted" code can be decompiled and a tool could be written to bypass it.
Even with obfuscation and bytecode modification and custom classloaders, java is hackable/decompileable and the source can almost always be brought to a somewhat readable state.
You want to obfuscate, not encrypt, the jar file.
A popular choice for doing this in Java is ProGuard.
No. Since your program needs to be able to run the code it would be pointless anyway.
You can obfuscate your code though so decompiling the .class files results in less readable code (meaningless variable/class names etc).
As far as I know this is not supported by standard JVM. But you can do the following. Separate your application into 2 parts. First will not be encrypted. It will be a simple loader that will instantiate the rest using custom class loader. This class loader will get Classes as arrays of bytes, decrypt and load them.
if you don't want to provide an access to the class files inside the jar, why should you supply your jar with the application?
It feels like your question is kind of wrong conceptually...
If you need some custom way of loading the classes, consider to use custom classloader.
if you are packaging in jar -> just rename it to jarname.ABCD or any misleading extension or even take off the extension, and accordingly specify the jar name in your application.
i prefer jCrypt!
It is a simple tool where you can crypt the classes(and ressources)
Have you heard of any library which would allow me to set up tracing for specific methods at runtime?
Instead of adding (and removing) lots of System.out.println in my code (and having to re-compile and re-deploy) I would like to have a magic thing which would print out a line for each call of selected method without any change in the code. This would work without re-compiling, so some kind of JVM agent (or some non-standard JVM would be needed?). Sounds like a job for aspect programming?
A typical scenario would be to start an application, configure the traced methods dynamically (in a separate file or similar) and then everytime a selected method is called a line with its name (and arguments) is printed out to System.out (or some log file).
Naturally one could think of tens of additional features, but this basic set would be a great tool. BTW, I use Eclipse interactive debugger too, not only the System.out tracing technique, but both have some advantages and sometimes Eclipse is not enough.
Yes what you are referring to is known as Aspect oriented programming. A typical library providing this for Java is AspectJ. You define what are called pointcuts, essentially regular expressions for classes and method names, including wildcards, and the code to execute at each pointcut, known as an advice. This is useful for logging and also security checks and similar cross cutting concerns.
You can turn pointcut advices on and off through configuration. You can have an advice execute before a method call, after it returns or even after it throws an exception. Arguments are also available.
An aspectj java agent is needed for this to work.
In my experience, that kind of very detailed tracing (much more detailed than one would normally use for logging) as a debugging technique is indicative of insufficient unit testing and integration testing.
You can do this using a tool called InTrace.
NOTE: InTrace is a free and open source tool which I have written.
Log4J useful for disabling logging depending on "log-level" (DEBUG, INFO, WARN, FATAL).
You specify in configuration file what the least level you want to appear in logs, e.g., don't log anything below INFO level, and voila!
Looks like there's yet another solution - called Byteman. In their own words:
Byteman is a tool which simplifies tracing and testing of Java
programs. Byteman allows you to insert extra Java code into your
application, either as it is loaded during JVM startup or even after
it has already started running. The injected code is allowed to access
any of your data and call any application methods, including where
they are private. You can inject code almost anywhere you want and
there is no need to prepare the original source code in advance nor do
you have to recompile, repackage or redeploy your application. In fact
you can remove injected code and reinstall different code while the
application continues to execute.
Jackplay is the tool you are looking for.
It allows you to enable logging on method entry and exit points without any coding or redeployment.
It also allows redefining a method body. It gives you web based UI as control panel to enable or undo tracing on your class.methods.