Refactored Resource Importing

This commit is contained in:
Konloch 2021-06-26 07:11:23 -07:00
parent 5290692c3e
commit efaae70d36
9 changed files with 354 additions and 153 deletions

View File

@ -53,157 +53,45 @@ public class ImportResource implements Runnable
{
try
{
for (final File f : files)
for (final File file : files)
{
final String fn = f.getName();
if (!f.exists()) {
final String fn = file.getName();
if (!file.exists())
{
update = false;
BytecodeViewer.showMessage("The file " + f.getAbsolutePath() + " could not be found.");
} else {
if (f.isDirectory()) {
FileContainer container = new FileContainer(f);
HashMap<String, byte[]> files1 = new HashMap<>();
boolean finished = false;
ArrayList<File> totalFiles = new ArrayList<>();
totalFiles.add(f);
String dir = f.getAbsolutePath();//f.getAbsolutePath().substring(0, f.getAbsolutePath
// ().length()-f.getName().length());
while (!finished) {
boolean added = false;
for (int i = 0; i < totalFiles.size(); i++) {
File child = totalFiles.get(i);
if (child.listFiles() != null)
for (File rocket : Objects.requireNonNull(child.listFiles()))
if (!totalFiles.contains(rocket)) {
totalFiles.add(rocket);
added = true;
}
}
if (!added) {
for (File child : totalFiles)
if (child.isFile()) {
String fileName = child.getAbsolutePath().substring(dir.length() + 1
).replaceAll("\\\\", "\\/");
files1.put(fileName,
Files.readAllBytes(Paths.get(child.getAbsolutePath())));
}
finished = true;
}
BytecodeViewer.showMessage("The file " + file.getAbsolutePath() + " could not be found.");
}
else
{
if (file.isDirectory())
{
ImportType.DIRECTORY.getImporter().open(file);
}
else
{
if (fn.endsWith(".jar") || fn.endsWith(".zip") || fn.endsWith(".war"))
{
if(!ImportType.ZIP.getImporter().open(file))
update = false;
}
container.files = files1;
BytecodeViewer.files.add(container);
} else {
if (fn.endsWith(".jar") || fn.endsWith(".zip") || fn.endsWith(".war")) {
try {
JarUtils.put(f);
} catch (IOException z) {
try {
JarUtils.put2(f);
} catch (final Exception e) {
new ExceptionUI(e);
update = false;
}
} catch (final Exception e) {
new ExceptionUI(e);
else if (fn.endsWith(".class"))
{
if(!ImportType.CLASS.getImporter().open(file))
update = false;
}
} else if (fn.endsWith(".class")) {
try {
byte[] bytes = JarUtils.getBytes(new FileInputStream(f));
String cafebabe = String.format("%02X", bytes[0]) + String.format("%02X",
bytes[1]) + String.format("%02X", bytes[2]) + String.format("%02X",
bytes[3]);
if (cafebabe.equalsIgnoreCase("cafebabe")) {
final ClassNode cn = JarUtils.getNode(bytes);
FileContainer container = new FileContainer(f);
container.classes.add(cn);
BytecodeViewer.files.add(container);
} else {
BytecodeViewer.showMessage(fn + ": Header does not start with CAFEBABE, ignoring.");
update = false;
}
} catch (final Exception e) {
new ExceptionUI(e);
update = false;
}
} else if (fn.endsWith(".apk")) {
try {
BytecodeViewer.viewer.updateBusyStatus(true);
File tempCopy = new File(tempDirectory + fs + MiscUtils.randomString(32) + ".apk");
FileUtils.copyFile(f, tempCopy);
FileContainer container = new FileContainer(tempCopy, f.getName());
if (BytecodeViewer.viewer.decodeAPKResources.isSelected()) {
File decodedResources =
new File(tempDirectory + fs + MiscUtils.randomString(32) + ".apk");
APKTool.decodeResources(tempCopy, decodedResources, container);
container.files = JarUtils.loadResources(decodedResources);
}
Objects.requireNonNull(container.files).putAll(JarUtils.loadResources(tempCopy)); //copy and rename
// to prevent unicode filenames
String name = MiscUtils.getRandomizedName() + ".jar";
File output = new File(tempDirectory + fs + name);
if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel()))
Dex2Jar.dex2Jar(tempCopy, output);
else if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel()))
Enjarify.apk2Jar(tempCopy, output);
container.classes = JarUtils.loadClasses(output);
BytecodeViewer.viewer.updateBusyStatus(false);
BytecodeViewer.files.add(container);
} catch (final Exception e) {
new ExceptionUI(e);
}
}
else if (fn.endsWith(".apk"))
{
ImportType.APK.getImporter().open(file);
return;
} else if (fn.endsWith(".dex")) {
try {
BytecodeViewer.viewer.updateBusyStatus(true);
File tempCopy = new File(tempDirectory + fs + MiscUtils.randomString(32) +
".dex");
FileUtils.copyFile(f, tempCopy); //copy and rename to prevent unicode filenames
FileContainer container = new FileContainer(tempCopy, f.getName());
String name = MiscUtils.getRandomizedName() + ".jar";
File output = new File(tempDirectory + fs + name);
if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel()))
Dex2Jar.dex2Jar(tempCopy, output);
else if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel()))
Enjarify.apk2Jar(tempCopy, output);
container.classes = JarUtils.loadClasses(output);
BytecodeViewer.viewer.updateBusyStatus(false);
BytecodeViewer.files.add(container);
} catch (final Exception e) {
new ExceptionUI(e);
}
}
else if (fn.endsWith(".dex"))
{
ImportType.DEX.getImporter().open(file);
return;
} else {
HashMap<String, byte[]> files1 = new HashMap<>();
byte[] bytes = JarUtils.getBytes(new FileInputStream(f));
files1.put(f.getName(), bytes);
FileContainer container = new FileContainer(f);
container.files = files1;
BytecodeViewer.files.add(container);
}
else
{
ImportType.FILE.getImporter().open(file);
}
}
}
@ -216,8 +104,7 @@ public class ImportResource implements Runnable
if (update)
try {
Objects.requireNonNull(MainViewerGUI.getComponent(ResourceListPane.class)).updateTree();
} catch (NullPointerException ignored) {
}
} catch (NullPointerException ignored) { }
}
}
}

View File

@ -1,15 +1,27 @@
package the.bytecode.club.bytecodeviewer.util.resources;
import the.bytecode.club.bytecodeviewer.util.resources.impl.*;
/**
* @author Konloch
* @since 6/26/2021
*/
public enum ImportType
{
DIRECTORY,
FILE,
ZIP,
CLASS,
APK,
DEX,
DIRECTORY(new DirectoryResourceImporter()),
FILE(new FileResourceImporter()),
ZIP(new ZipResourceImporter()),
CLASS(new ClassResourceImporter()),
APK(new APKResourceImporter()),
DEX(new DEXResourceImporter()),
;
private final Importer importer;
ImportType(Importer importer) {this.importer = importer;}
public Importer getImporter()
{
return importer;
}
}

View File

@ -0,0 +1,12 @@
package the.bytecode.club.bytecodeviewer.util.resources;
import java.io.File;
/**
* @author Konloch
* @since 6/26/2021
*/
public interface Importer
{
boolean open(File file) throws Exception;
}

View File

@ -0,0 +1,61 @@
package the.bytecode.club.bytecodeviewer.util.resources.impl;
import org.apache.commons.io.FileUtils;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.util.*;
import the.bytecode.club.bytecodeviewer.util.resources.Importer;
import java.io.File;
import java.util.Objects;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
/**
* @author Konloch
* @since 6/26/2021
*/
public class APKResourceImporter implements Importer
{
@Override
public boolean open(File file) throws Exception
{
try {
BytecodeViewer.viewer.updateBusyStatus(true);
File tempCopy = new File(tempDirectory + fs + MiscUtils.randomString(32) + ".apk");
FileUtils.copyFile(file, tempCopy);
FileContainer container = new FileContainer(tempCopy, file.getName());
if (BytecodeViewer.viewer.decodeAPKResources.isSelected()) {
File decodedResources =
new File(tempDirectory + fs + MiscUtils.randomString(32) + ".apk");
APKTool.decodeResources(tempCopy, decodedResources, container);
container.files = JarUtils.loadResources(decodedResources);
}
Objects.requireNonNull(container.files).putAll(JarUtils.loadResources(tempCopy)); //copy and rename
// to prevent unicode filenames
String name = MiscUtils.getRandomizedName() + ".jar";
File output = new File(tempDirectory + fs + name);
if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel()))
Dex2Jar.dex2Jar(tempCopy, output);
else if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel()))
Enjarify.apk2Jar(tempCopy, output);
container.classes = JarUtils.loadClasses(output);
BytecodeViewer.viewer.updateBusyStatus(false);
BytecodeViewer.files.add(container);
} catch (final Exception e) {
new ExceptionUI(e);
}
return true;
}
}

View File

@ -0,0 +1,53 @@
package the.bytecode.club.bytecodeviewer.util.resources.impl;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.util.FileContainer;
import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.resources.Importer;
import java.io.File;
import java.io.FileInputStream;
/**
* @author Konloch
* @since 6/26/2021
*/
public class ClassResourceImporter implements Importer
{
@Override
public boolean open(File file) throws Exception
{
final String fn = file.getName();
try
{
byte[] bytes = JarUtils.getBytes(new FileInputStream(file));
String cafebabe = String.format("%02X", bytes[0])
+ String.format("%02X", bytes[1])
+ String.format("%02X", bytes[2])
+ String.format("%02X", bytes[3]);
if (cafebabe.equalsIgnoreCase("cafebabe"))
{
final ClassNode cn = JarUtils.getNode(bytes);
FileContainer container = new FileContainer(file);
container.classes.add(cn);
BytecodeViewer.files.add(container);
}
else
{
BytecodeViewer.showMessage(fn + ": Header does not start with CAFEBABE, ignoring.");
return false;
}
}
catch (final Exception e)
{
new ExceptionUI(e);
return false;
}
return true;
}
}

View File

@ -0,0 +1,50 @@
package the.bytecode.club.bytecodeviewer.util.resources.impl;
import org.apache.commons.io.FileUtils;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.util.*;
import the.bytecode.club.bytecodeviewer.util.resources.Importer;
import java.io.File;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
/**
* @author Konloch
* @since 6/26/2021
*/
public class DEXResourceImporter implements Importer
{
@Override
public boolean open(File file) throws Exception
{
try {
BytecodeViewer.viewer.updateBusyStatus(true);
File tempCopy = new File(tempDirectory + fs + MiscUtils.randomString(32) + ".dex");
FileUtils.copyFile(file, tempCopy); //copy and rename to prevent unicode filenames
FileContainer container = new FileContainer(tempCopy, file.getName());
String name = MiscUtils.getRandomizedName() + ".jar";
File output = new File(tempDirectory + fs + name);
if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel()))
Dex2Jar.dex2Jar(tempCopy, output);
else if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel()))
Enjarify.apk2Jar(tempCopy, output);
container.classes = JarUtils.loadClasses(output);
BytecodeViewer.viewer.updateBusyStatus(false);
BytecodeViewer.files.add(container);
} catch (final Exception e) {
new ExceptionUI(e);
}
return true;
}
}

View File

@ -0,0 +1,60 @@
package the.bytecode.club.bytecodeviewer.util.resources.impl;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.util.FileContainer;
import the.bytecode.club.bytecodeviewer.util.resources.Importer;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Objects;
/**
* @author Konloch
* @since 6/26/2021
*/
public class DirectoryResourceImporter implements Importer
{
@Override
public boolean open(File file) throws Exception
{
FileContainer container = new FileContainer(file);
HashMap<String, byte[]> files1 = new HashMap<>();
boolean finished = false;
ArrayList<File> totalFiles = new ArrayList<>();
totalFiles.add(file);
String dir = file.getAbsolutePath();//f.getAbsolutePath().substring(0, f.getAbsolutePath
// ().length()-f.getName().length());
while (!finished) {
boolean added = false;
for (int i = 0; i < totalFiles.size(); i++) {
File child = totalFiles.get(i);
if (child.listFiles() != null)
for (File rocket : Objects.requireNonNull(child.listFiles()))
if (!totalFiles.contains(rocket)) {
totalFiles.add(rocket);
added = true;
}
}
if (!added) {
for (File child : totalFiles)
if (child.isFile()) {
String fileName = child.getAbsolutePath().substring(dir.length() + 1
).replaceAll("\\\\", "\\/");
files1.put(fileName, Files.readAllBytes(Paths.get(child.getAbsolutePath())));
}
finished = true;
}
}
container.files = files1;
BytecodeViewer.files.add(container);
return true;
}
}

View File

@ -0,0 +1,31 @@
package the.bytecode.club.bytecodeviewer.util.resources.impl;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.util.FileContainer;
import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.resources.Importer;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
/**
* @author Konloch
* @since 6/26/2021
*/
public class FileResourceImporter implements Importer
{
@Override
public boolean open(File file) throws Exception
{
HashMap<String, byte[]> files1 = new HashMap<>();
byte[] bytes = JarUtils.getBytes(new FileInputStream(file));
files1.put(file.getName(), bytes);
FileContainer container = new FileContainer(file);
container.files = files1;
BytecodeViewer.files.add(container);
return true;
}
}

View File

@ -0,0 +1,35 @@
package the.bytecode.club.bytecodeviewer.util.resources.impl;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.resources.Importer;
import java.io.File;
import java.io.IOException;
/**
* @author Konloch
* @since 6/26/2021
*/
public class ZipResourceImporter implements Importer
{
@Override
public boolean open(File file) throws Exception
{
try {
JarUtils.put(file);
} catch (IOException z) {
try {
JarUtils.put2(file);
} catch (final Exception e) {
new ExceptionUI(e);
return false;
}
} catch (final Exception e) {
new ExceptionUI(e);
return false;
}
return true;
}
}