Skip to content

Commit dd7f8a1

Browse files
committed
Merge pull request Konloch#86 from Szperak/master
Added Allatori string deofuscator
2 parents 198d0f2 + b75cb67 commit dd7f8a1

File tree

9 files changed

+400
-112
lines changed

9 files changed

+400
-112
lines changed

src/the/bytecode/club/bytecodeviewer/JarUtils.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,26 +63,28 @@ public static void put(final File jarFile) throws IOException {
6363
try {
6464
final String name = entry.getName();
6565
final byte[] bytes = getBytes(jis);
66-
if (!name.endsWith(".class")) {
67-
if(!entry.isDirectory())
68-
files.put(name, bytes);
69-
} else {
70-
String cafebabe = String.format("%02X", bytes[0])
71-
+ String.format("%02X", bytes[1])
72-
+ String.format("%02X", bytes[2])
73-
+ String.format("%02X", bytes[3]);
74-
if(cafebabe.toLowerCase().equals("cafebabe")) {
75-
try {
76-
final ClassNode cn = getNode(bytes);
77-
container.classes.add(cn);
78-
} catch(Exception e) {
79-
e.printStackTrace();
80-
}
66+
if(!files.containsKey(name)){
67+
if (!name.endsWith(".class")) {
68+
if(!entry.isDirectory())
69+
files.put(name, bytes);
8170
} else {
82-
System.out.println(jarFile+">"+name+": Header does not start with CAFEBABE, ignoring.");
71+
String cafebabe = String.format("%02X", bytes[0])
72+
+ String.format("%02X", bytes[1])
73+
+ String.format("%02X", bytes[2])
74+
+ String.format("%02X", bytes[3]);
75+
if(cafebabe.toLowerCase().equals("cafebabe")) {
76+
try {
77+
final ClassNode cn = getNode(bytes);
78+
container.classes.add(cn);
79+
} catch(Exception e) {
80+
e.printStackTrace();
81+
}
82+
} else {
83+
System.out.println(jarFile+">"+name+": Header does not start with CAFEBABE, ignoring.");
84+
}
85+
files.put(name, bytes);
8386
}
8487
}
85-
8688
} catch(Exception e) {
8789
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
8890
} finally {

src/the/bytecode/club/bytecodeviewer/api/BytecodeViewer.java

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package the.bytecode.club.bytecodeviewer.api;
22

33
import java.io.File;
4+
import java.io.IOException;
45
import java.net.URL;
56
import java.net.URLClassLoader;
67
import java.util.ArrayList;
@@ -62,50 +63,60 @@ public static URLClassLoader getClassLoaderInstance() {
6263
return cl;
6364
}
6465

66+
67+
6568
/**
6669
* Re-instances the URLClassLoader and loads a jar to it.
67-
* @param path
70+
*
71+
* @param nodeList
72+
* The list of ClassNodes to be loaded
6873
* @return The loaded classes into the new URLClassLoader instance
6974
* @author Cafebabe
75+
* @throws IOException
76+
* @throws ClassNotFoundException
7077
*/
71-
public static List<Class<?>> loadClassesIntoClassLoader() {
72-
try {
73-
File f = new File(
74-
the.bytecode.club.bytecodeviewer.BytecodeViewer.tempDirectory +
75-
the.bytecode.club.bytecodeviewer.BytecodeViewer.fs +
76-
"loaded_temp.jar");
77-
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), f.getAbsolutePath());
78-
JarFile jarFile = new JarFile(""+f.getAbsolutePath());
79-
Enumeration<JarEntry> e = jarFile.entries();
80-
URL[] urls = { new URL("jar:file:" + ""+f.getAbsolutePath()+"!/") };
81-
cl = URLClassLoader.newInstance(urls);
82-
List<Class<?>> ret = new ArrayList<Class<?>>();
83-
84-
while (e.hasMoreElements())
85-
{
86-
JarEntry je = (JarEntry) e.nextElement();
87-
if(je.isDirectory() || !je.getName().endsWith(".class"))
88-
continue;
89-
String className = je.getName().replace("/", ".").replace(".class", "");
90-
className = className.replace('/', '.');
91-
try{
92-
ret.add(cl.loadClass(className));
93-
}
94-
catch(Exception e2)
95-
{
96-
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e2);
97-
}
98-
}
99-
jarFile.close();
100-
101-
return ret;
102-
}
103-
catch(Exception e)
104-
{
105-
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
106-
}
107-
return null;
108-
}
78+
@SuppressWarnings("deprecation")
79+
public static List<Class<?>> loadClassesIntoClassLoader(
80+
ArrayList<ClassNode> nodeList) throws IOException,
81+
ClassNotFoundException {
82+
83+
File f = new File(
84+
the.bytecode.club.bytecodeviewer.BytecodeViewer.tempDirectory
85+
+ the.bytecode.club.bytecodeviewer.BytecodeViewer.fs
86+
+ "loaded_temp.jar");
87+
JarUtils.saveAsJarClassesOnly(nodeList, f.getAbsolutePath());
88+
89+
JarFile jarFile = new JarFile("" + f.getAbsolutePath());
90+
Enumeration<JarEntry> e = jarFile.entries();
91+
cl = URLClassLoader.newInstance(new URL[]{ f.toURL() });
92+
List<Class<?>> ret = new ArrayList<Class<?>>();
93+
94+
while (e.hasMoreElements()) {
95+
JarEntry je = (JarEntry) e.nextElement();
96+
if (je.isDirectory() || !je.getName().endsWith(".class"))
97+
continue;
98+
String className = je.getName().replace("/", ".").replace(".class", "");
99+
className = className.replace('/', '.');
100+
ret.add(cl.loadClass(className));
101+
102+
}
103+
jarFile.close();
104+
105+
return ret;
106+
107+
}
108+
109+
110+
/**
111+
* Re-instances the URLClassLoader and loads a jar to it.
112+
* @return The loaded classes into the new URLClassLoader instance
113+
* @author Cafebabe
114+
* @throws IOException
115+
* @throws ClassNotFoundException
116+
*/
117+
public static List<Class<?>> loadAllClassesIntoClassLoader() throws ClassNotFoundException, IOException {
118+
return loadClassesIntoClassLoader(getLoadedClasses());
119+
}
109120

110121
/**
111122
* Creates a new instance of the ClassNode loader.

src/the/bytecode/club/bytecodeviewer/api/ClassNodeLoader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public Class<?> findClass(String name) throws ClassNotFoundException {
110110
if (classes.containsKey(name)) {
111111
return nodeToClass(classes.get(name));
112112
} else {
113-
return super.loadClass(name);
113+
return super.findClass(name);
114114
}
115115
}
116116

src/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ protected String printLookupSwitchInsnNode(LookupSwitchInsnNode lin) {
304304

305305
protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin) {
306306
StringBuilder sb = new StringBuilder();
307-
sb.append(nameOpcode(idin.opcode()) + " " + idin.name + "(");
307+
sb.append(nameOpcode(idin.opcode()) + " " + idin.bsm.getName() + "(");
308308

309309
String desc = idin.desc;
310310
String partedDesc = idin.desc.substring(2);
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package the.bytecode.club.bytecodeviewer.gui;
2+
3+
import java.awt.Dimension;
4+
import java.awt.event.ActionEvent;
5+
import java.awt.event.ActionListener;
6+
7+
import javax.swing.JButton;
8+
import javax.swing.JFrame;
9+
import javax.swing.JLabel;
10+
import javax.swing.JTextField;
11+
12+
import the.bytecode.club.bytecodeviewer.Resources;
13+
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
14+
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.AllatoriStringDecrypter;
15+
16+
/***************************************************************************
17+
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
18+
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
19+
* *
20+
* This program is free software: you can redistribute it and/or modify *
21+
* it under the terms of the GNU General Public License as published by *
22+
* the Free Software Foundation, either version 3 of the License, or *
23+
* (at your option) any later version. *
24+
* *
25+
* This program is distributed in the hope that it will be useful, *
26+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
27+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
28+
* GNU General Public License for more details. *
29+
* *
30+
* You should have received a copy of the GNU General Public License *
31+
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
32+
***************************************************************************/
33+
34+
/**
35+
* The UI for replace strings plugin.
36+
*
37+
* @author Konloch
38+
*
39+
*/
40+
41+
public class AllatoriStringDecrypterOptions extends JFrame {
42+
public AllatoriStringDecrypterOptions() {
43+
this.setIconImages(Resources.iconList);
44+
setSize(new Dimension(250, 120));
45+
setResizable(false);
46+
setTitle("Allatori decrypter");
47+
getContentPane().setLayout(null);
48+
49+
JButton btnNewButton = new JButton("Decrypt");
50+
btnNewButton.setBounds(6, 56, 232, 23);
51+
getContentPane().add(btnNewButton);
52+
53+
54+
JLabel lblNewLabel = new JLabel("Class:");
55+
lblNewLabel.setBounds(6, 20, 67, 14);
56+
getContentPane().add(lblNewLabel);
57+
58+
textField = new JTextField();
59+
textField.setToolTipText("* will search all classes");
60+
textField.setText("*");
61+
textField.setBounds(80, 17, 158, 20);
62+
getContentPane().add(textField);
63+
textField.setColumns(10);
64+
65+
66+
btnNewButton.addActionListener(new ActionListener() {
67+
public void actionPerformed(ActionEvent arg0) {
68+
PluginManager.runPlugin(new AllatoriStringDecrypter(textField.getText()));
69+
dispose();
70+
}
71+
});
72+
this.setLocationRelativeTo(null);
73+
}
74+
75+
private static final long serialVersionUID = -2662514582647810868L;
76+
private JTextField textField;
77+
}

src/the/bytecode/club/bytecodeviewer/gui/FileNavigationPane.java

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -311,36 +311,6 @@ public void updateTree() {
311311
ImageRenderer renderer = new ImageRenderer();
312312
tree.setCellRenderer(renderer);
313313

314-
if(!container.classes.isEmpty()) {
315-
for(ClassNode c : container.classes) {
316-
String name = c.name;
317-
final String[] spl = name.split("/");
318-
if (spl.length < 2) {
319-
root.add(new MyTreeNode(name+".class"));
320-
} else {
321-
MyTreeNode parent = root;
322-
for (int i1 = 0; i1 < spl.length; i1++) {
323-
String s = spl[i1];
324-
MyTreeNode child = null;
325-
for (int i = 0; i < parent.getChildCount(); i++) {
326-
if (((MyTreeNode) parent.getChildAt(i)).getUserObject()
327-
.equals(s)) {
328-
child = (MyTreeNode) parent.getChildAt(i);
329-
break;
330-
}
331-
}
332-
if (child == null) {
333-
if(i1 == spl.length-1)
334-
child = new MyTreeNode(s+".class");
335-
else
336-
child = new MyTreeNode(s);
337-
parent.add(child);
338-
}
339-
parent = child;
340-
}
341-
}
342-
}
343-
}
344314

345315
if(!container.files.isEmpty()) {
346316
for (final Entry<String, byte[]> entry : container.files.entrySet()) {

src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2029,8 +2029,12 @@ public void actionPerformed(ActionEvent e) {
20292029
});
20302030
mntmNewMenuItem_2.addActionListener(new ActionListener() {
20312031
@Override
2032-
public void actionPerformed(ActionEvent e) {
2033-
PluginManager.runPlugin(new AllatoriStringDecrypter());
2032+
public void actionPerformed(ActionEvent arg0) {
2033+
if(BytecodeViewer.getLoadedClasses().isEmpty()) {
2034+
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
2035+
return;
2036+
}
2037+
new AllatoriStringDecrypterOptions().setVisible(true);
20342038
}
20352039
});
20362040
mntmNewMenuItem_1.addActionListener(new ActionListener() {

0 commit comments

Comments
 (0)