Refactored Resource Importing
This commit is contained in:
parent
5290692c3e
commit
efaae70d36
9 changed files with 354 additions and 153 deletions
|
@ -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) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue