This part of the tutorial. we'll step into manipulating a code in a simple class file. as ease writing the tutorial and reading it. this can be simply be used at any class in the runescape.jar
Before starting on this tutorial. I would like you to read the basics of how BCEL and byte coding works.
Read the first two chapters from BCEL library.
First we write a basic class to learn how to manipulate it.
Code:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class BasicClass implements ActionListener {
private void initiateGUI() {
frame = new JFrame(title);
panel = new JPanel(new BorderLayout());
button = new button("Press this for an int!");
button.addActionListener(this);
button.setActionCommand("yeswai");
label = new JLabel("the int is: ");
panel.add(label, BorderLayout.NORTH);
panel.add(button, BorderLayout.SOUTH);
frame.add(panel);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private void newInt(int theInt) {
someInt = theInt;
}
private BasicClass() {
initiateGUI();
newInt(1235);
}
public static void main(String[] args) {
new BasicClass();
}
public void actionPerformed(ActionEvent evt) {
if (evt.getActionCommand().equals("nowai")) {
label.setText("yeswai!!");
} else {
label.setText("The int is " + someInt);
}
}
private JFrame frame;
private JPanel panel;
private JButton button;
private JLabel label;
private int someInt;
public static final String title = "orly?";
}
No we have a basic gui code. if you can't understand what does it say. please leave now and never come back!
There is many ways to manipulate this class. I will start by basics..
now I think the gui title is a little bit extreme... let's change it something like.. "dam you"
Code:
try {
cGen = new ClassGen(new ClassParser("BasicClass.class").parse());
}
catch (ClassFormatException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
Now.. the class is loaded.. we can actually manipulate it. can you believe that?
A certain way to change things in it. is to get all methods from the BasicClass. one way to do that is by using cGen.getMethods(); which will return an Method[] object. no we can check through the methods to see if we hit something unique. we can parse through the methods to check if the name of the method is actually newInt.
Code:
Method build = null;
for(Method m : cGen.getMethods())
{
if(m.getName().equals("initiateGUI"))
{
build = m;
System.out.println(“Found the method mentioned.”);
break;
}
}
now we have a way to find the method we want. (how adorable)
Now.. let's see if we can change the title of the gui..
If you read the two chapters I told you to read before You'll know that Opcode ldc is used to get a constant from the Constant Pool.
Look at the code below for clarification:
Code:
0 aload_0
1 new #25 <java/swing/jframe>
4 dup
5 ldc #20 <orly?>
7 invokespecial #27 <javax/swing/JFrame/<init>(Ljava/lang/String;)V>
10 putfield #31 <BasicClass/jFrame Ljavax/swing/JFrame;>
Those are the few lines of the initiateGUI method.. if you could not see where the title is placed. leave this tutorial.
Now lets get all instructions from the method.
Code:
ConstantPoolGen cPoolGen = cGen.getConstantPool();
MethodGen methGen = new MethodGen(build, cGen.getClassName(), cPoolGen);
InstructionList iList = methGen.getInstructionList();
now let's search all. if you can't understand this. feel free to ask.
Code:
InstructionHandle titleLDC = null;
InstructionHandle[] iHandles = iList.getInstructionHandles();
for(int f = 0; f < iHandles.length; f++)
{
if(iHandles[f].getInstruction() instanceof LDC)
{
titleLDC = iHandles[f];
System.out.println("found LDC");
break;
}
}
Now to change the title name we use
Code:
LDC ldcIns = new LDC(cPoolGen.addString("changed"));
Let's replace our old instructor with a new one..
Code:
titleLDC.setInstruction(ldcIns);
We edited our first bytecode. well done!
Now to add it. and do a cleanup you'll need this at the end of every BCEL code you use!
Code:
iList.setPositions();
methGen.setInstructionList(iList);
methGen.setMaxStack();
methGen.setMaxLocals();
methGen.removeLineNumbers();
now let's replace the old method with the new one..
Code:
cGen.replaceMethod(build, methGen.getMethod());
now to dump all of this into a new class we use
Code:
try
{
cGen.getJavaClass().dump("BasicClass.class");
}
catch(IOException ex)
{
ex.printStackTrace();
}
Let's put all of the codes to together we get this
Code:
import java.io.IOException;
import com.sun.org.apache.bcel.internal.classfile.ClassFormatException;
import com.sun.org.apache.bcel.internal.classfile.ClassParser;
import com.sun.org.apache.bcel.internal.classfile.Method;
import com.sun.org.apache.bcel.internal.generic.ClassGen;
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
import com.sun.org.apache.bcel.internal.generic.InstructionList;
import com.sun.org.apache.bcel.internal.generic.LDC;
import com.sun.org.apache.bcel.internal.generic.MethodGen;
public class Converter
{
private ClassGen cGen;
public Converter()
{
loadClass();
modify();
dumpClass();
}
private void loadClass()
{
try {
cGen = new ClassGen(new ClassParser("BasicClass.class").parse());
} catch (ClassFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void modify()
{
Method build = null;
for(Method m : cGen.getMethods())
{
if(m.getName().equals("initiateGUI"))
{
build = m;
System.out.println("Found the method mentioned");
break;
}
}
ConstantPoolGen cPoolGen = cGen.getConstantPool();
MethodGen methGen = new MethodGen(build, cGen.getClassName(), cPoolGen);
InstructionList iList = methGen.getInstructionList();
InstructionHandle titleLDC = null;
InstructionHandle[] iHandles = iList.getInstructionHandles();
for(int f = 0; f < iHandles.length; f++)
{
if(iHandles[f].getInstruction() instanceof LDC)
{
titleLDC = iHandles[f];
System.out.println("found LDC");
break;
}
}
LDC ldcIns = new LDC(cPoolGen.addString("changed"));
titleLDC.setInstruction(ldcIns);
iList.setPositions();
methGen.setInstructionList(iList);
methGen.setMaxStack();
methGen.setMaxLocals();
methGen.removeLineNumbers();
cGen.replaceMethod(build, methGen.getMethod());
}
public void dumpClass()
{
try
{
cGen.getJavaClass().dump("BasicClass.class");
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
public static void main(String[] args)
{
new Converter();
}
}
That will change the name of the gui! well done.
Now you are one step closer to making a bot. -- you should start right now! let's create a new bot!
If you face a problem in any kind. please post here. don't pm me about it!