Merge jiqimaogou/jadx
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
package jadx.api;
|
||||
|
||||
import jadx.core.xmlgen.ResContainer;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import jadx.core.xmlgen.ResContainer;
|
||||
|
||||
public class ResourceFile {
|
||||
|
||||
public static final class ZipRef {
|
||||
@@ -56,7 +56,7 @@ public class ResourceFile {
|
||||
this.zipRef = zipRef;
|
||||
}
|
||||
|
||||
ZipRef getZipRef() {
|
||||
public ZipRef getZipRef() {
|
||||
return zipRef;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
package jadx.api;
|
||||
|
||||
import jadx.api.ResourceFile.ZipRef;
|
||||
import jadx.core.codegen.CodeWriter;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
import jadx.core.utils.files.InputFile;
|
||||
import jadx.core.xmlgen.ResContainer;
|
||||
import jadx.core.xmlgen.ResTableParser;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
@@ -19,8 +15,13 @@ import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import jadx.api.ResourceFile.ZipRef;
|
||||
import jadx.core.codegen.CodeWriter;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
import jadx.core.utils.files.InputFile;
|
||||
import jadx.core.xmlgen.ResContainer;
|
||||
import jadx.core.xmlgen.ResTableParser;
|
||||
|
||||
import static jadx.core.utils.files.FileUtils.READ_BUFFER_SIZE;
|
||||
import static jadx.core.utils.files.FileUtils.close;
|
||||
@@ -51,30 +52,35 @@ public final class ResourcesLoader {
|
||||
}
|
||||
|
||||
public static ResContainer decodeStream(ResourceFile rf, ResourceDecoder decoder) throws JadxException {
|
||||
ZipRef zipRef = rf.getZipRef();
|
||||
if (zipRef == null) {
|
||||
return null;
|
||||
}
|
||||
ZipFile zipFile = null;
|
||||
InputStream inputStream = null;
|
||||
ResContainer result = null;
|
||||
try {
|
||||
zipFile = new ZipFile(zipRef.getZipFile());
|
||||
ZipEntry entry = zipFile.getEntry(zipRef.getEntryName());
|
||||
if (entry == null) {
|
||||
throw new IOException("Zip entry not found: " + zipRef);
|
||||
long size;
|
||||
ZipRef zipRef = rf.getZipRef();
|
||||
if (zipRef == null) {
|
||||
File file = new File(rf.getName());
|
||||
inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||
size = file.length();
|
||||
} else {
|
||||
zipFile = new ZipFile(zipRef.getZipFile());
|
||||
ZipEntry entry = zipFile.getEntry(zipRef.getEntryName());
|
||||
if (entry == null) {
|
||||
throw new IOException("Zip entry not found: " + zipRef);
|
||||
}
|
||||
inputStream = new BufferedInputStream(zipFile.getInputStream(entry));
|
||||
size = entry.getSize();
|
||||
}
|
||||
inputStream = new BufferedInputStream(zipFile.getInputStream(entry));
|
||||
result = decoder.decode(entry.getSize(), inputStream);
|
||||
result = decoder.decode(size, inputStream);
|
||||
} catch (Exception e) {
|
||||
throw new JadxException("Error decode: " + zipRef.getEntryName(), e);
|
||||
throw new JadxException("Error decode: " + rf.getName(), e);
|
||||
} finally {
|
||||
try {
|
||||
if (zipFile != null) {
|
||||
zipFile.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error close zip file: {}", zipRef, e);
|
||||
LOG.error("Error close zip file: {}", rf.getName(), e);
|
||||
}
|
||||
close(inputStream);
|
||||
}
|
||||
@@ -133,6 +139,7 @@ public final class ResourcesLoader {
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.debug("Not a zip file: {}", file.getAbsolutePath());
|
||||
addResourceFile(list, file);
|
||||
} finally {
|
||||
if (zip != null) {
|
||||
try {
|
||||
@@ -144,6 +151,13 @@ public final class ResourcesLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private void addResourceFile(List<ResourceFile> list, File file) {
|
||||
String name = file.getAbsolutePath();
|
||||
ResourceType type = ResourceType.getFileType(name);
|
||||
ResourceFile rf = new ResourceFile(jadxRef, name, type);
|
||||
list.add(rf);
|
||||
}
|
||||
|
||||
private void addEntry(List<ResourceFile> list, File zipFile, ZipEntry entry) {
|
||||
if (entry.isDirectory()) {
|
||||
return;
|
||||
|
||||
@@ -10,6 +10,7 @@ import jadx.core.dex.info.FieldInfo;
|
||||
import jadx.core.dex.info.MethodInfo;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.DexNode;
|
||||
import jadx.core.dex.nodes.FieldNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.dex.nodes.RootNode;
|
||||
@@ -18,6 +19,7 @@ import jadx.core.utils.files.InputFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
@@ -33,13 +35,17 @@ public class RenameVisitor extends AbstractVisitor {
|
||||
public void init(RootNode root) {
|
||||
IJadxArgs args = root.getArgs();
|
||||
|
||||
InputFile firstInputFile = root.getDexNodes().get(0).getDexFile().getInputFile();
|
||||
List<DexNode> dexNodes = root.getDexNodes();
|
||||
if (dexNodes.size() == 0) {
|
||||
return;
|
||||
}
|
||||
InputFile firstInputFile = dexNodes.get(0).getDexFile().getInputFile();
|
||||
final String firstInputFileName = firstInputFile.getFile().getAbsolutePath();
|
||||
final String inputPath = FilenameUtils.getFullPathNoEndSeparator(firstInputFileName);
|
||||
final String inputName = FilenameUtils.getBaseName(firstInputFileName);
|
||||
|
||||
File deobfMapFile = new File(inputPath, inputName + ".jobf");
|
||||
deobfuscator = new Deobfuscator(args, root.getDexNodes(), deobfMapFile);
|
||||
deobfuscator = new Deobfuscator(args, dexNodes, deobfMapFile);
|
||||
boolean deobfuscationOn = args.isDeobfuscationOn();
|
||||
if (deobfuscationOn) {
|
||||
deobfuscator.execute();
|
||||
|
||||
@@ -48,7 +48,11 @@ public class AndroidResourcesUtils {
|
||||
}
|
||||
|
||||
private static ClassNode makeClass(RootNode root, String clsName) {
|
||||
DexNode firstDex = root.getDexNodes().get(0);
|
||||
List<DexNode> dexNodes = root.getDexNodes();
|
||||
if (dexNodes.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
DexNode firstDex = dexNodes.get(0);
|
||||
ClassInfo r = ClassInfo.fromName(firstDex, clsName);
|
||||
return new ClassNode(firstDex, r);
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
@@ -112,7 +112,7 @@ public class FileUtils {
|
||||
return null;
|
||||
}
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
for ( int j = 0; j < bytes.length; j++ ) {
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
int v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = hexArray[v >>> 4];
|
||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||
@@ -154,7 +154,7 @@ public class FileUtils {
|
||||
zipFile = new ZipFile(file);
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
|
||||
while(entries.hasMoreElements()){
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
filelist.add(entry.getName());
|
||||
System.out.println(entry.getName());
|
||||
@@ -180,7 +180,7 @@ public class FileUtils {
|
||||
|
||||
public static boolean isZipDexfile(File file) {
|
||||
boolean isZipDexFile = false;
|
||||
if (isZipfile(file)) {
|
||||
if (isZipfile(file) && isZipFileCanBeOpen(file)) {
|
||||
List<String> filelist = getZipfileList(file);
|
||||
if (filelist.contains("classes.dex")) {
|
||||
isZipDexFile = true;
|
||||
@@ -189,4 +189,22 @@ public class FileUtils {
|
||||
|
||||
return isZipDexFile;
|
||||
}
|
||||
|
||||
public static boolean isZipFileCanBeOpen(final File file) {
|
||||
ZipFile zipFile = null;
|
||||
try {
|
||||
zipFile = new ZipFile(file);
|
||||
return zipFile.entries().hasMoreElements();
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
} finally {
|
||||
if (zipFile != null) {
|
||||
try {
|
||||
zipFile.close();
|
||||
} catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +55,7 @@ public class InputFile {
|
||||
addDexFile(loadFromClassFile(file));
|
||||
return;
|
||||
}
|
||||
|
||||
if (fileName.endsWith(".apk") || fileName.endsWith(".zip") || isApkfile(file) || isZipDexfile(file)) {
|
||||
if (isApkfile(file) || isZipDexfile(file)) {
|
||||
loadFromZip(".dex");
|
||||
return;
|
||||
}
|
||||
@@ -65,14 +64,17 @@ public class InputFile {
|
||||
if (loadFromZip(".dex")) {
|
||||
return;
|
||||
}
|
||||
addDexFile(loadFromJar(file));
|
||||
if (fileName.endsWith(".jar")) {
|
||||
addDexFile(loadFromJar(file));
|
||||
return;
|
||||
}
|
||||
if (fileName.endsWith(".aar")) {
|
||||
loadFromZip(".jar");
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (fileName.endsWith(".aar")) {
|
||||
loadFromZip(".jar");
|
||||
return;
|
||||
}
|
||||
throw new DecodeException("Unsupported input file format: " + file);
|
||||
// throw new DecodeException("Unsupported input file format: " + file);
|
||||
}
|
||||
|
||||
private void addDexFile(Dex dexBuf) throws IOException {
|
||||
|
||||
@@ -136,9 +136,9 @@ public class ResTableParser extends CommonBinaryParser {
|
||||
}
|
||||
|
||||
PackageChunk pkg = new PackageChunk(id, name, typeStrings, keyStrings);
|
||||
if (id == 0x7F) {
|
||||
//if (id == 0x7F) {
|
||||
resStorage.setAppPackage(name);
|
||||
}
|
||||
//}
|
||||
|
||||
while (is.getPos() < endPos) {
|
||||
long chunkStart = is.getPos();
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package jadx.gui.treemodel;
|
||||
|
||||
import jadx.api.ResourceFile;
|
||||
import jadx.gui.JadxWrapper;
|
||||
import jadx.gui.treemodel.JResource.JResType;
|
||||
import jadx.gui.utils.Utils;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import jadx.api.ResourceFile;
|
||||
import jadx.gui.JadxWrapper;
|
||||
import jadx.gui.treemodel.JResource.JResType;
|
||||
import jadx.gui.utils.Utils;
|
||||
|
||||
public class JRoot extends JNode {
|
||||
private static final long serialVersionUID = 8888495789773527342L;
|
||||
|
||||
@@ -45,7 +46,13 @@ public class JRoot extends JNode {
|
||||
JResource root = new JResource(null, "Resources", JResType.ROOT);
|
||||
String splitPathStr = Pattern.quote(File.separator);
|
||||
for (ResourceFile rf : resources) {
|
||||
String[] parts = new File(rf.getName()).getPath().split(splitPathStr);
|
||||
String rfName;
|
||||
if (rf.getZipRef() != null) {
|
||||
rfName = rf.getName();
|
||||
} else {
|
||||
rfName = new File(rf.getName()).getName();
|
||||
}
|
||||
String[] parts = new File(rfName).getPath().split(splitPathStr);
|
||||
JResource curRf = root;
|
||||
int count = parts.length;
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
@@ -171,7 +171,7 @@ public class MainWindow extends JFrame {
|
||||
public void openFile() {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setAcceptAllFileFilterUsed(true);
|
||||
String[] exts = {"apk", "dex", "jar", "class", "zip", "aar"};
|
||||
String[] exts = {"apk", "dex", "jar", "class", "zip", "aar", "arsc"};
|
||||
String description = "supported files: " + Arrays.toString(exts).replace('[', '(').replace(']', ')');
|
||||
fileChooser.setFileFilter(new FileNameExtensionFilter(description, exts));
|
||||
fileChooser.setToolTipText(NLS.str("file.open"));
|
||||
|
||||
Reference in New Issue
Block a user