Statistics

Members: 1928
News: 293
Web Links: 1
Visitors: 5960303

Who's Online

We have 18 guests online
Damn Vulnerable LinuxDamn Vulnerable Linux (DVL) is a Linux-based (modified Damn Small Linux) tool for IT-Security & IT-Anti- Security and Attack & Defense. [CLICK HERE FOR MORE INFOS! ]

Featured Conference Video

T16-Recon2006-Joe_Stewart-OllyBonE.gif OllyBone - Semi-Automatic Unpacking on IA-32. View the conference video here!
Home
An Intro to the Java Virtual Machine
User Rating: / 0
PoorBest 
Written by Cynical Pinnacle   


For awhile C/C++ reigned supreme and nothing challenged it but then along comes Java, creating a splash, and causing outright corporate warfare to claim right of ownership. Strangely enough the result of this war has not been dead bodies but buckets and buckets of API's all given away for free. Just stop by and take a look at Java's Official Website (http://java.sun.com) and what do you find a good development kit with compiler, symbolic debugger, disassembler, complete toolkit for creating GUI's, built in support for compression, encryption, http, ftp, SMTP, POP3, IHMP, and more. Wow! But how can we take advantage of all this?

First we have to step back a look at what Java really is. Because one of the main goals of Java is platform independence (both from the chip and the OS). The JVM, which supports Java, has to be both a chip and an OS. If any of us (well lets say us programmers) were to design a chip and a OS in one, we would fill it with features like built in security, automatic dependency resolution and linking, network support, video and audio acceleration, along with more common things such as built in data types (ints, floats, arrays, and objects ), support for local variables, exception handling, support for debugging, and on and on. This is really what Java is because it does all the things I mentioned above and more. This is what Sun has tried to do - design an "Ideal" environment for writing and executing code, or write once run anywhere. But this wealth of features comes at the price of speed of execution and further distance further from the native code of your machine (unless you are running on a real Java machine). And if you are like me the latter hurts as much as the former.

Still there are a alot of really appealing things about Java. And so the challenge is to use these appealing features on our own terms. We can do this by programming at a lower level to at least touch the native language of the Java Virtual Machine (Java Assembly language!!)

The JVM:

I am going to take a programmers view of the JVM and say it is simple because from our perspective it is. But for the sake of completeness I will list the other components of the JVM:

Memory Manager: This is the unit responsible for the famous garbage collection and heap management. I say clean up your own garbage.

Error/Exception Manager: Handles unforseen conditions.

Native Method Support: This is to allow you to call WaitForSingleObject from within Java. It is responsible for loading DLLs, resolving entry points and executing them. Note Java only supports dynamic linking.

Threads: Java doesn't have to worry so much about memory because it is all allocated on the stack. Each thread gets its own stack frame (chunk of stack for its personal use). Switching threads in a stack based machine is easy. You just make the threads stack top the machine's stack top and go.

Class Loader: This is just like the loaders in NT and 95. It brings up class files from the disk initializes them (headers memory etc) and passes execution to the classes entry point.

Security Manager: Want to find out whether or not you can do something. Ask him.

Execution Engine: This is where the JVM opcodes are translated into native opcodes. This is the part of the JVM which a low level Java programmer will interact with most. The Execution engine has a much simpler structure than a Pentium. At its heart is a stack where instuctions are executed. Note that the JVM has no registers, which is more a trait of Virtual machines than Java. Basically opcodes and operands are popped off of the stack and executed by the VM bases upon a mapping between Java opcodes and Native opcodes. In addition, there is built in support for local variables (more later). And as mentioned before the stack is symbollically divided up by the JVM. Each method (read method to mean function) gets it own stack frame which is allocated when the method starts and deallocated when the method exits (sound familiar eg x86 push bp -- mov bp, sp .. leave instructions). The Execution engine understands the int, long, float, double, byte, char, short, reference (eg pointer) and the instructions it understands are strongly typed (for example: there is an instruction called iload which loads an integer from a local variable onto the stack (like mov eax, myLocalVariable) but there is also a dload, lload, and fload for doubles, longs, and floats).

Now with a little background it is time to learn or burn but first we need some tools. First you will need to download the JDK from http://java.sun.com (I recommend 1.1.x and the current I think is 7) you will also need a Java assembler which is called Jasmin also free at

http://www.cat.nyu.edu/meyer/jasmin/ and you will need a good editor (I heartily recommend Visual SlickEdit 3.0 or 4.0 at http://www.slickedit.com ). You can get docs about the JVM from

http://www.javasoft.com/
And the best book I have found on the JVM (and Jasmin) is "Java Virtual Machine" by Jon Meyer and Troy Denning. There are several useful tools with the JDK comes a program called javap which is a Java .class file disassembler! With the -c switch it will produce JASM code from any .class file. Note that reversing Java programs is not nearly as hard as x86. Try it. Take some Java .class file you have laying around ( Keep it small so you don't get confused ) and disassemble it then you will see what I mean. I can see a very difficult future for Java Shareware programmers. There are also many other 3rd party tools out there for mainpulating .class files.

With all of those tools installed we are ready to write the mandatory "Hello from JASM!" program. First comes the Java Assembler code followed by its Java equivilant.

;*************************************************************** ;Export the class name so Java can find it class public Hello

;Simplest class to derive from
super java/lang/Object

; General facts
; .method - means this is a function
;
; public - means you are it is visible externally (low ; level Object Orientedness)
;
; Java always uses explicit paths in Unix notation hence you ; end up with a lot of notation like java/lan/Object. ; java/lang/Object is the path to the superclass. In a lot ; of the functions there is a V, this means it returns void ; the syntax for specifying arguments is strange. I ; recommend reading Jonathan Meyer's Jasmin documentation ; http://www.cat.nyu.edu/meyer/jasmin/

; This method is called init and is in every class ; all that is done here is to push the contents of local ; variable 0 onto the stack and call the superclass's ; (Object) init method. Local variable 0 is always ; the reference (pointer) to the equivalent of C++'s this

.method public ()V

aload_0

; This just calls the superclasses init method

invokenonvirtual java/lang/Object/()V

; Get out

return
end method

; Here is the main function which is publically visible ; is static and thus shared by all instances of the class, ; it takes one argument of type [ljava/lang/String, which ; is an array of strings eg: argv**, and returns void hence ; the V.

.method public static main([Ljava/lang/String;)V

; Delcare your stack memory usage
.limit stack 2
.limit locals 1

; Push 5 onto the stack and store it in local variable 1

bipush 5
istore_1

LoopTop

; These next two lines put the parameters for the println ; function onto the stack in the right order. Java uses ; the pascal calling convention (push left to right and ; the callee cleans up). First a reference to the stream ; object doing the work is pushed onto the stack. Next a ; reference to the string to be printed is pushed.

;get the pointer to the stream object and push it getstatic java/lang/System/out Ljava/io/PrintStream; ;get the pointer to the string and push it ldc "Hello from JASM!"
;call println
invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V

; These next three lines are the loop condition ; iinc adds -1 to local variable 1. iload_1 pushes ; local variable 1 onto the stack and ifne compares it to ; zero (just like jnz in x86). If it is not equal to zero ; we jump to LoopTop

iinc 1 -1
iload_1
ifne LoopTop

; Go home

return
;Declare the end of the function
end method

;
; Java equivalent:
;
; public class Hello
; {

;       public static void main ( String args[] )
;      {
;         int i;
;         for( i = 0;i