Abstract
This article is especially designed to crack Java executables, by disassembling their corresponding bytes code. Disassembling of Java bytecodes is the act of transforming Java bytecodes into Java source code. Disassembling is an inherent issue in the software industry, causing revenue loss due to software piracy. Security engineers tend to resist disassembling techniques, including software watermarking and code obfuscation, in the context of Java byte code disassembling. A large portion of this paper is dedicated to tactics that are commonly considered to be Reverse Engineering. The methods presented here, are intended for professional software developers and each technique is based on custom created applications. We are not encouraging any kind of malicious hacking approach by presenting this article. In fact, the contents of this paper assist to pinpoint the vulnerability, in the source code, and learn the various methods gor developers to shield their intellectual property, from reversing. We shall come across with the process of disassembling in terms of obtaining sensitive information from source code and cracking a Java executable, without having the original source code.
Prerequisite
I presume that the reader has a thorough understanding of programming, debugging, and compiling in Java on various platforms, such as Linux, Windows and of course, a JVM inner working knowledge. Apart from that, the subsequent tools are required to manipulate byte code reverse engineering.
- JDK Toolkit [Javac, javap]
- Eclipse
- JVM
- JAD
Java Byte code
Engineers usually, construct software in a high-level language like Java that is comprehensible to them, but that in fact, cannot be executed by the machine directly. Such textual form of a computer program, known as source code, is converted into a form that the computer can directly execute. Java source code is compiled into an intermediate language known as Java bytecode, which is not directly executed by the CPU, but executed by a Java Virtual Machine. Compilation typically is the act of transforming a high-level language, into a low-level language, such as machine code or bytecode. We do not need to understand Java byte code, rather doing so can assist debugging and can improve performance and memory consumption.
The JVM is essentially a simple stack-based machine that can be separated into a couple of segments, such as stack, heap, registers, method area and native method stacks. An advantage of the virtual machine architecture is portability. Any machine that implements the Java Virtual Machine specification is able to execute Java bytecode, in a manner of “Write once, run anywhere". Java bytecode is not strictly linked to the Java language and there are many compilers and other tools available, that produce Java bytecode, such as the Eclipse IDE, Netbeans and Jasmin bytecode assembler. Another advantage of the Java Virtual Machine is the runtime type-safety of programs. The Java Virtual Machine defines the required behavior of a Java Virtual Machine,
but does not specify any implementation details. Therefore the implementation of the Java Virtual Machine specification can be designed in various ways for diverse platforms as long as it adheres to the specification.
Sample Cracked Application
The subsequent Java console application “LoginTest” is developed to reflect Java byte code disassembling. This application typically tests the valid users by passing them using a simple login user name and password mechanism. We have this application from other resources as an unregistered user and obviously, we don't possess the source code of this application. As a result, we are do not have the valid user name and password that is only provided to the registered user and could not log in eventually.
Without having the source code of the application or log in credential sets, we still can manage to login into this mechanism, by disassembling its byte code where we can expose sensitive information related to the user login.
Disassemble Bytecode
Disassembling is the reverse approach due to the standard and well-documented structure of bytecode that is an act of transforming a low-level language into a high-level language. It basically generates the source code from Java bytecode. We typically run a disassembler to obtain the source code for a given bytecode just as a compiler is run to yield bytecode from the source code. Disassembling is used to determine the implementation logic in the absence of the relevant documentation and the source code, which is why vendors explicitly prohibit disassembling and reverse engineering in the license agreement. Here are some of the reasons to decompile:
- Fixing critical bugs in the software for which no source code exists.
- Troubleshooting a software or jar that does not have proper documentation.
- Recovering the source code that was accidentally lost.
- Learning the implementation of a mechanism.
- Learning to protect your code from reverse engineering.
The process of disassembling Java byte code is quite simple, not as complex as a native C/C++ binary. The first step is to compile the Java source code file that has *.java extension using the javac utility that produces a *.class file from the original source code in which byte code typically resides. Finally, by using java that is a utility provided in the JDK toolkit, we can disassemble the byte code from the corresponding *.class file. The java utility stores its output in a *.bc file.


Join the conversation! Your thoughts help the community grow.