introduction
The following text highlights
some easy experimenting with java class files. The necessary tools which
you will require are a decent binary file editor. The Cygnus shareware
hex editor was used to modify the following few programs.
The extremely in depth
description of the HelloWorld program previously, allows us to observe
how the Java Virtual Machine works. It also gives us an insight as to how
we may go about infecting a compiled class file with viral code. From the
previous example, the following code caused the string Hello World! to
be printed to the screen.
Method void main(java.lang.String[])
0 getstatic
#7 <Field java.io.PrintStream out>
3 ldc #1
<String "Hello World!">
5 invokevirtual
#8 <Method void println(java.lang.String)>
8 return
This code is represented
by the hexadecimal sequence 0xB200071201B60008B1.
analysis
experiment
#1
Lets
try an experiment whereby we shall attempt to insert executable code into
the HelloWorld class file.
If
we take all of the instructions before the return instruction (0xB1) and
insert them again so that the new code_attribute looks like this 0xB200071201B60008B200071201B60008B1,
then by logical reasoning this code should print out Hello World! twice.
So that
the code passes the verifier adjust the code_length by eight bytes to become
0x0011 and the attribute_length by the same amount to become 0x002D. Behold!
the program prints out Hello World! twice. Thus illustrating how we can
insert code into a class file.
experiment
#2
Lets try
another experiment where we will attempt to add new entries to the constant_pool.
Our aim is to insert enough code so that the program will now print Hello
World! followed by Hello Australia! To accomplish this we must insert a
new CONSTANT_String as well as a new CONSTANT_Utf8 which is required by
the PrintStream() method. To ensure that the code passes the verifier,
we must then increment the constant_pool_count to account for the new entries.
First things
first, the new CONSTANT_String entry will look like this:
constant_pool[20]
tag 0x08 CONSTANT_String
string_index 0x0021 constant_pool[21]
CONSTANT_Utf8 Hello
Australia!
The
new CONSTANT_Utf8 entry will thus look like this:
constant_pool[1E]
tag 0x01 CONSTANT_Utf8
length 0x0010
bytes[length]
0x48656C6C6F204175737472616C696121
Hello Australia!
We
then increment constant_pool_count to become 0x0022. There is one step
left to finish it all off and that is to insert new executable code to
execute the new constants. The old code looked like this 0xB200071201B60008B200071201B60008B1
so if we change the second reference to the CONSTANT_String from constant_pool[01]
to constant_pool[20] the code becomes 0xB200071201B60008B200071220B60008B1.
Run
the file by typing java HelloWorld.
Yippee!
we have successfully inserted constants into the class file.
conclusion
We
have had an easy time with these simple examples because we have known
the offset of the constants (distance from start of the constant_pool)
that we are inserting into the class file. For us to be able to write some
viral code we must be able to calculate the offset (easy) and allow for
the offset to change references in all of the code that we insert (harder).
However, before we continue onto bigger things, it is important to learn
some basic concepts from the above examples. Inserting constants and code
into a class file is as simple as 1,2,3. We only have to make sure we stick
it in the right part and fix up the lengths of some of the fields in the
file.