-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathClassLoaderTest.java
More file actions
129 lines (119 loc) · 3.47 KB
/
Copy pathClassLoaderTest.java
File metadata and controls
129 lines (119 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package classLoader;
import java.io.*;
import java.lang.reflect.*;
import java.nio.file.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* This program demonstrates a custom class loader that decrypts class files.
* @version 1.23 2012-06-08
* @author Cay Horstmann
*/
public class ClassLoaderTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new ClassLoaderFrame();
frame.setTitle("ClassLoaderTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
/**
* This frame contains two text fields for the name of the class to load and the decryption key.
*/
class ClassLoaderFrame extends JFrame
{
private JTextField keyField = new JTextField("3", 4);
private JTextField nameField = new JTextField("Calculator", 30);
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
public ClassLoaderFrame()
{
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
setLayout(new GridBagLayout());
add(new JLabel("Class"), new GBC(0, 0).setAnchor(GBC.EAST));
add(nameField, new GBC(1, 0).setWeight(100, 0).setAnchor(GBC.WEST));
add(new JLabel("Key"), new GBC(0, 1).setAnchor(GBC.EAST));
add(keyField, new GBC(1, 1).setWeight(100, 0).setAnchor(GBC.WEST));
JButton loadButton = new JButton("Load");
add(loadButton, new GBC(0, 2, 2, 1));
loadButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
runClass(nameField.getText(), keyField.getText());
}
});
pack();
}
/**
* Runs the main method of a given class.
* @param name the class name
* @param key the decryption key for the class files
*/
public void runClass(String name, String key)
{
try
{
ClassLoader loader = new CryptoClassLoader(Integer.parseInt(key));
Class<?> c = loader.loadClass(name);
Method m = c.getMethod("main", String[].class);
m.invoke(null, (Object) new String[] {});
}
catch (Throwable e)
{
JOptionPane.showMessageDialog(this, e);
}
}
}
/**
* This class loader loads encrypted class files.
*/
class CryptoClassLoader extends ClassLoader
{
private int key;
/**
* Constructs a crypto class loader.
* @param k the decryption key
*/
public CryptoClassLoader(int k)
{
key = k;
}
protected Class<?> findClass(String name) throws ClassNotFoundException
{
try
{
byte[] classBytes = null;
classBytes = loadClassBytes(name);
Class<?> cl = defineClass(name, classBytes, 0, classBytes.length);
if (cl == null) throw new ClassNotFoundException(name);
return cl;
}
catch (IOException e)
{
throw new ClassNotFoundException(name);
}
}
/**
* Loads and decrypt the class file bytes.
* @param name the class name
* @return an array with the class file bytes
*/
private byte[] loadClassBytes(String name) throws IOException
{
String cname = name.replace('.', '/') + ".caesar";
byte[] bytes = Files.readAllBytes(Paths.get(cname));
for (int i = 0; i < bytes.length; i++)
bytes[i] = (byte) (bytes[i] - key);
return bytes;
}
}