is = new ArrayList<>();
@Override
public void push() {
diff --git a/dex-reader/src/main/java/com/googlecode/d2j/util/Escape.java b/dex-reader/src/main/java/com/googlecode/d2j/util/Escape.java
index 5f349756d..01657b6f9 100644
--- a/dex-reader/src/main/java/com/googlecode/d2j/util/Escape.java
+++ b/dex-reader/src/main/java/com/googlecode/d2j/util/Escape.java
@@ -1,12 +1,12 @@
/*
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,7 +15,12 @@
*/
package com.googlecode.d2j.util;
-import com.googlecode.d2j.*;
+import com.googlecode.d2j.DexConstants;
+import com.googlecode.d2j.DexType;
+import com.googlecode.d2j.Field;
+import com.googlecode.d2j.Method;
+import com.googlecode.d2j.MethodHandle;
+import com.googlecode.d2j.Proto;
/**
* @author Panxiaobo
@@ -162,6 +167,7 @@ public static String v(Method m) {
return String.format("new Method(%s,%s,%s,%s)", v(m.getOwner()), v(m.getName()), v(m.getParameterTypes()),
v(m.getReturnType()));
}
+
public static String v(Proto m) {
return String.format("new Proto(%s,%s)", v(m.getParameterTypes()), v(m.getReturnType()));
}
diff --git a/dex-reader/src/main/java/com/googlecode/d2j/util/Mutf8.java b/dex-reader/src/main/java/com/googlecode/d2j/util/Mutf8.java
index 7e639dc03..aa598bd17 100644
--- a/dex-reader/src/main/java/com/googlecode/d2j/util/Mutf8.java
+++ b/dex-reader/src/main/java/com/googlecode/d2j/util/Mutf8.java
@@ -21,7 +21,7 @@
/**
* Modified UTF-8 as described in the dex file format spec.
- *
+ *
*
* Derived from libcore's MUTF-8 encoder at java.nio.charset.ModifiedUtf8.
*/
diff --git a/dex-reader/src/main/java/com/googlecode/d2j/util/Utf8Utils.java b/dex-reader/src/main/java/com/googlecode/d2j/util/Utf8Utils.java
index e97b17553..cb94a313a 100644
--- a/dex-reader/src/main/java/com/googlecode/d2j/util/Utf8Utils.java
+++ b/dex-reader/src/main/java/com/googlecode/d2j/util/Utf8Utils.java
@@ -35,9 +35,8 @@ public final class Utf8Utils {
/**
* Converts a string into its Java-style UTF-8 form. Java-style UTF-8 differs from normal UTF-8 in the handling of
* character '\0' and surrogate pairs.
- *
- * @param string
- * non-null; the string to convert
+ *
+ * @param string non-null; the string to convert
* @return non-null; the UTF-8 bytes for it
*/
public static byte[] stringToUtf8Bytes(String string) {
@@ -71,15 +70,12 @@ public static byte[] stringToUtf8Bytes(String string) {
/**
* Converts an array of UTF-8 bytes into a string.
- *
+ *
* This method uses a global buffer to avoid having to allocate one every time, so it is *not* thread-safe
- *
- * @param bytes
- * non-null; the bytes to convert
- * @param start
- * the start index of the utf8 string to convert
- * @param length
- * the length of the utf8 string to convert, not including any null-terminator that might be present
+ *
+ * @param bytes non-null; the bytes to convert
+ * @param start the start index of the utf8 string to convert
+ * @param length the length of the utf8 string to convert, not including any null-terminator that might be present
* @return non-null; the converted string
*/
public static String utf8BytesToString(byte[] bytes, int start, int length) {
@@ -172,14 +168,11 @@ public static String utf8BytesToString(byte[] bytes, int start, int length) {
/**
* Helper for {@link #utf8BytesToString}, which throws the right exception for a bogus utf-8 byte.
- *
- * @param value
- * the byte value
- * @param offset
- * the file offset
+ *
+ * @param value the byte value
+ * @param offset the file offset
* @return never
- * @throws IllegalArgumentException
- * always thrown
+ * @throws IllegalArgumentException always thrown
*/
private static String throwBadUtf8(int value, int offset) {
throw new IllegalArgumentException("bad utf-8 byte " + String.format("%02x", value) + " at offset "
diff --git a/dex-reader/src/main/java/com/googlecode/d2j/util/zip/AutoSTOREDZipOutputStream.java b/dex-reader/src/main/java/com/googlecode/d2j/util/zip/AutoSTOREDZipOutputStream.java
index 942ff9b2f..72fa12aca 100644
--- a/dex-reader/src/main/java/com/googlecode/d2j/util/zip/AutoSTOREDZipOutputStream.java
+++ b/dex-reader/src/main/java/com/googlecode/d2j/util/zip/AutoSTOREDZipOutputStream.java
@@ -18,8 +18,9 @@
import java.io.IOException;
import java.io.OutputStream;
-import java.util.zip.*;
+import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
/**
* Auto calc size/crc for STORED
diff --git a/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipConstants.java b/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipConstants.java
index ad0cad83e..cda896b09 100644
--- a/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipConstants.java
+++ b/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipConstants.java
@@ -5,9 +5,9 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,9 +22,9 @@
*/
interface ZipConstants {
- public static final long LOCSIG = 0x4034b50, EXTSIG = 0x8074b50, CENSIG = 0x2014b50, ENDSIG = 0x6054b50;
+ long LOCSIG = 0x4034b50, EXTSIG = 0x8074b50, CENSIG = 0x2014b50, ENDSIG = 0x6054b50;
- public static final int LOCHDR = 30, EXTHDR = 16, CENHDR = 46, ENDHDR = 22, LOCVER = 4, LOCFLG = 6, LOCHOW = 8,
+ int LOCHDR = 30, EXTHDR = 16, CENHDR = 46, ENDHDR = 22, LOCVER = 4, LOCFLG = 6, LOCHOW = 8,
LOCTIM = 10, LOCCRC = 14, LOCSIZ = 18, LOCLEN = 22, LOCNAM = 26, LOCEXT = 28, EXTCRC = 4, EXTSIZ = 8,
EXTLEN = 12, CENVEM = 4, CENVER = 6, CENFLG = 8, CENHOW = 10, CENTIM = 12, CENCRC = 16, CENSIZ = 20,
CENLEN = 24, CENNAM = 28, CENEXT = 30, CENCOM = 32, CENDSK = 34, CENATT = 36, CENATX = 38, CENOFF = 42,
diff --git a/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipEntry.java b/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipEntry.java
index 0bbf97bbc..61397d4e1 100644
--- a/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipEntry.java
+++ b/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipEntry.java
@@ -5,9 +5,9 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -34,19 +34,19 @@ public final class ZipEntry implements ZipConstants, Cloneable {
String name;
String comment;
- long crc = -1; // Needs to be a long to distinguish -1 ("not set") from the 0xffffffff CRC32.
+ long crc; // Needs to be a long to distinguish -1 ("not set") from the 0xffffffff CRC32.
- long compressedSize = -1;
- long size = -1;
+ long compressedSize;
+ long size;
- int compressionMethod = -1;
- int time = -1;
- int modDate = -1;
+ int compressionMethod;
+ int time;
+ int modDate;
byte[] extra;
- int nameLength = -1;
- long localHeaderRelOffset = -1;
+ int nameLength;
+ long localHeaderRelOffset;
/**
* Zip entry state: Deflated.
@@ -68,7 +68,7 @@ public String getComment() {
/**
* Gets the compressed size of this {@code android.ZipEntry}.
- *
+ *
* @return the compressed size, or -1 if the compressed size has not been set.
*/
public long getCompressedSize() {
@@ -77,7 +77,7 @@ public long getCompressedSize() {
/**
* Gets the checksum for this {@code android.ZipEntry}.
- *
+ *
* @return the checksum, or -1 if the checksum has not been set.
*/
public long getCrc() {
@@ -86,7 +86,7 @@ public long getCrc() {
/**
* Gets the extra information for this {@code android.ZipEntry}.
- *
+ *
* @return a byte array containing the extra information, or {@code null} if there is none.
*/
public byte[] getExtra() {
@@ -95,7 +95,7 @@ public byte[] getExtra() {
/**
* Gets the compression method for this {@code android.ZipEntry}.
- *
+ *
* @return the compression method, either {@code DEFLATED}, {@code STORED} or -1 if the compression method has not
* been set.
*/
@@ -105,7 +105,7 @@ public int getMethod() {
/**
* Gets the name of this {@code android.ZipEntry}.
- *
+ *
* @return the entry name.
*/
public String getName() {
@@ -114,7 +114,7 @@ public String getName() {
/**
* Gets the uncompressed size of this {@code android.ZipEntry}.
- *
+ *
* @return the uncompressed size, or {@code -1} if the size has not been set.
*/
public long getSize() {
@@ -123,7 +123,7 @@ public long getSize() {
/**
* Gets the last modification time of this {@code android.ZipEntry}.
- *
+ *
* @return the last modification time as the number of milliseconds since Jan. 1, 1970.
*/
public long getTime() {
@@ -139,7 +139,7 @@ public long getTime() {
/**
* Determine whether or not this {@code android.ZipEntry} is a directory.
- *
+ *
* @return {@code true} when this {@code android.ZipEntry} is a directory, {@code false} otherwise.
*/
public boolean isDirectory() {
@@ -148,7 +148,7 @@ public boolean isDirectory() {
/**
* Returns the string representation of this {@code android.ZipEntry}.
- *
+ *
* @return the string representation of this {@code android.ZipEntry}.
*/
@Override
diff --git a/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipFile.java b/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipFile.java
index f8211f13d..55190cc43 100644
--- a/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipFile.java
+++ b/dex-reader/src/main/java/com/googlecode/d2j/util/zip/ZipFile.java
@@ -5,9 +5,9 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,7 +16,10 @@
*/
package com.googlecode.d2j.util.zip;
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
@@ -29,13 +32,12 @@
/**
* This is code is get from Android 4.4.2 intent to read as more zip as possible
- *
+ *
* Ignore GPBF_ENCRYPTED_FLAG
- *
+ *
* Allow duplicate ZipEntry
- *
+ *
* Allow Nul byte in ZipEntry name
- *
*/
public class ZipFile implements AutoCloseable, ZipConstants {
/**
@@ -93,9 +95,8 @@ public List extends ZipEntry> entries() {
/**
* Returns this file's comment, or null if it doesn't have one. See {@link java.util.zip.ZipOutputStream#setComment}
* .
- *
- * @throws IllegalStateException
- * if this zip file has been closed.
+ *
+ * @throws IllegalStateException if this zip file has been closed.
* @since 1.7
*/
public String getComment() {
@@ -131,16 +132,11 @@ public long getEntryDataStart(ZipEntry entry) {
/**
* Returns an input stream on the data of the specified {@code android.ZipEntry}.
- *
- * @param entry
- * the android.ZipEntry.
+ *
+ * @param entry the android.ZipEntry.
* @return an input stream of the data contained in the {@code android.ZipEntry}.
- * @throws java.io.IOException
- * if an {@code IOException} occurs.
- * @throws IllegalStateException
- * if this zip file has been closed.
*/
- public InputStream getInputStream(ZipEntry entry) throws IOException {
+ public InputStream getInputStream(ZipEntry entry) {
long entryDataStart = getEntryDataStart(entry);
ByteBuffer is = (ByteBuffer) raf.duplicate().position((int) entryDataStart);
@@ -161,10 +157,9 @@ static void skip(ByteBuffer is, int i) {
/**
* Returns the number of {@code ZipEntries} in this {@code android.ZipFile}.
- *
+ *
* @return the number of entries in this file.
- * @throws IllegalStateException
- * if this zip file has been closed.
+ * @throws IllegalStateException if this zip file has been closed.
*/
public int size() {
return entries.size();
@@ -172,12 +167,12 @@ public int size() {
/**
* Find the central directory and read the contents.
- *
+ *
*
* The central directory can be followed by a variable-length comment field, so we have to scan through it
* backwards. The comment is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff itself, plus
* apparently sometimes people throw random junk on the end just for the fun of it.
- *
+ *
*
* This is all a little wobbly. If the wrong value ends up in the EOCD area, we're hosed. This appears to be the way
* that everybody handles it though, so we're in good company if this fails.
@@ -272,7 +267,7 @@ static void throwZipException(String msg, int magic) throws ZipException {
@Override
public void close() throws IOException {
- if(file!=null){
+ if (file != null) {
file.close();
}
}
@@ -318,7 +313,7 @@ public ByteBufferBackedInputStream(ByteBuffer buf) {
}
@Override
- public int read() throws IOException {
+ public int read() {
if (!buf.hasRemaining()) {
return -1;
}
@@ -326,7 +321,7 @@ public int read() throws IOException {
}
@Override
- public int read(byte[] b, int off, int len) throws IOException {
+ public int read(byte[] b, int off, int len) {
if (!buf.hasRemaining()) {
return -1;
}
diff --git a/dex-reader/src/test/java/com/googlecode/d2j/reader/test/AsmfierTest.java b/dex-reader/src/test/java/com/googlecode/d2j/reader/test/AsmfierTest.java
index 7ac732158..d56b937aa 100644
--- a/dex-reader/src/test/java/com/googlecode/d2j/reader/test/AsmfierTest.java
+++ b/dex-reader/src/test/java/com/googlecode/d2j/reader/test/AsmfierTest.java
@@ -1,12 +1,12 @@
/*
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,10 +16,6 @@
package com.googlecode.d2j.reader.test;
-import java.io.File;
-
-import org.junit.Test;
-
import com.googlecode.d2j.DexConstants;
import com.googlecode.d2j.Field;
import com.googlecode.d2j.Method;
@@ -32,10 +28,11 @@
import com.googlecode.d2j.visitors.DexCodeVisitor;
import com.googlecode.d2j.visitors.DexFieldVisitor;
import com.googlecode.d2j.visitors.DexMethodVisitor;
+import java.io.File;
+import org.junit.Test;
/**
* @author bob
- *
*/
public class AsmfierTest implements DexConstants {
@Test
@@ -50,7 +47,7 @@ public void test() {
DexAnnotationVisitor dav = pv.visitAnnotation("Leeeff;", Visibility.BUILD);
dav.visitEnd();
DexCodeVisitor dcv = mv.visitCode();
- dcv.visitConstStmt(Op.FILL_ARRAY_DATA, 0, new int[] { 1, 2, 3 });
+ dcv.visitConstStmt(Op.FILL_ARRAY_DATA, 0, new int[]{1, 2, 3});
dcv.visitStmt0R(Op.RETURN_VOID);
dcv.visitEnd();
mv.visitEnd();
diff --git a/dex-reader/src/test/java/com/googlecode/d2j/reader/test/BadZipEntryFlagTest.java b/dex-reader/src/test/java/com/googlecode/d2j/reader/test/BadZipEntryFlagTest.java
index 6e3c96c1d..a1082bd12 100644
--- a/dex-reader/src/test/java/com/googlecode/d2j/reader/test/BadZipEntryFlagTest.java
+++ b/dex-reader/src/test/java/com/googlecode/d2j/reader/test/BadZipEntryFlagTest.java
@@ -1,25 +1,22 @@
package com.googlecode.d2j.reader.test;
-import java.io.IOException;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
import com.googlecode.d2j.reader.zip.ZipUtil;
import com.googlecode.d2j.util.zip.ZipFile;
+import java.io.IOException;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.junit.Test;
/**
* Test case for issue 169
- *
+ *
* @author bob
- *
*/
public class BadZipEntryFlagTest {
@Test
public void test1() throws IOException {
- ZipArchiveInputStream zis = new ZipArchiveInputStream(BadZipEntryFlagTest.class.getResourceAsStream("/bad.zip"));
+ ZipArchiveInputStream zis = new ZipArchiveInputStream(BadZipEntryFlagTest.class.getResourceAsStream("/bad"
+ + ".zip"));
for (ZipArchiveEntry e = zis.getNextZipEntry(); e != null; e = zis.getNextZipEntry()) {
e.getGeneralPurposeBit().useEncryption(false);
if (!e.isDirectory()) {
diff --git a/dex-reader/src/test/java/com/googlecode/d2j/reader/test/SkipDupMethod.java b/dex-reader/src/test/java/com/googlecode/d2j/reader/test/SkipDupMethod.java
index 2a0d63670..fdbe27f96 100644
--- a/dex-reader/src/test/java/com/googlecode/d2j/reader/test/SkipDupMethod.java
+++ b/dex-reader/src/test/java/com/googlecode/d2j/reader/test/SkipDupMethod.java
@@ -3,11 +3,10 @@
import com.googlecode.d2j.node.DexFileNode;
import com.googlecode.d2j.reader.DexFileReader;
-import org.junit.Assert;
-import org.junit.Test;
-
import java.io.IOException;
import java.io.InputStream;
+import org.junit.Assert;
+import org.junit.Test;
public class SkipDupMethod {
@Test
diff --git a/dex-tools/src/main/assemble/package.xml b/dex-tools/src/main/assemble/package.xml
index 4ec18f543..a655e8f75 100644
--- a/dex-tools/src/main/assemble/package.xml
+++ b/dex-tools/src/main/assemble/package.xml
@@ -1,7 +1,7 @@
+ xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
distribution
zip
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/signapk/AbstractJarSign.java b/dex-tools/src/main/java/com/googlecode/d2j/signapk/AbstractJarSign.java
index ce4741253..6a2f345ed 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/signapk/AbstractJarSign.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/signapk/AbstractJarSign.java
@@ -43,10 +43,12 @@
import java.util.regex.Pattern;
public abstract class AbstractJarSign {
- /** Write to another stream and also feed it to the Signature object. */
+ /**
+ * Write to another stream and also feed it to the Signature object.
+ */
private static class SignatureOutputStream extends FilterOutputStream {
private int mCount;
- private Signature mSignature;
+ private final Signature mSignature;
public SignatureOutputStream(OutputStream out, Signature sig) {
super(out);
@@ -93,7 +95,7 @@ public void write(int b) throws IOException {
}
// Files matching this pattern are not copied to the output.
- private static Pattern stripPattern = Pattern.compile("^META-INF/(.*)[.](SF|RSA|DSA)$");
+ private static final Pattern stripPattern = Pattern.compile("^META-INF/(.*)[.](SF|RSA|DSA)$");
private static final byte[] EOL = "\r\n".getBytes(StandardCharsets.UTF_8);
private static final byte[] COL = ": ".getBytes(StandardCharsets.UTF_8);
private static final byte[] NAMES = "Name: ".getBytes(StandardCharsets.UTF_8);
@@ -113,7 +115,7 @@ private static void copyFiles(Manifest manifest, JarFile in, JarOutputStream out
Collections.sort(names);
for (String name : names) {
JarEntry inEntry = in.getJarEntry(name);
- JarEntry outEntry = null;
+ JarEntry outEntry;
if (inEntry.getMethod() == JarEntry.STORED) {
// Preserve the STORED method of the input entry.
outEntry = new JarEntry(inEntry);
@@ -150,7 +152,9 @@ public AbstractJarSign(PrivateKey privateKey, String digestAlg, String signAlg)
final protected String signAlg;
- /** Add the SHA1 of every file to the manifest, creating it if necessary. */
+ /**
+ * Add the SHA1 of every file to the manifest, creating it if necessary.
+ */
private Manifest addDigestsToManifest(JarFile jar) throws IOException, GeneralSecurityException {
Manifest input = jar.getManifest();
Manifest output = new Manifest();
@@ -159,7 +163,8 @@ private Manifest addDigestsToManifest(JarFile jar) throws IOException, GeneralSe
main.putAll(input.getMainAttributes());
}
main.putValue("Manifest-Version", "1.0");
- main.putValue("Created-By", "1.6.0_21 (d2j-" + AbstractJarSign.class.getPackage().getImplementationVersion() + ")");
+ main.putValue("Created-By",
+ "1.6.0_21 (d2j-" + AbstractJarSign.class.getPackage().getImplementationVersion() + ")");
MessageDigest md = MessageDigest.getInstance(digestAlg);
byte[] buffer = new byte[4096];
@@ -169,9 +174,9 @@ private Manifest addDigestsToManifest(JarFile jar) throws IOException, GeneralSe
// output manifest in sorted order. We expect that the output
// map will be deterministic.
- TreeMap byName = new TreeMap();
+ TreeMap byName = new TreeMap<>();
- for (Enumeration e = jar.entries(); e.hasMoreElements();) {
+ for (Enumeration e = jar.entries(); e.hasMoreElements(); ) {
JarEntry entry = e.nextElement();
byName.put(entry.getName(), entry);
}
@@ -199,13 +204,13 @@ private Manifest addDigestsToManifest(JarFile jar) throws IOException, GeneralSe
}
protected String encodeBase64(byte[] data) {
- return Base64.encodeToString(data, Base64.NO_WRAP);
+ return Base64.encodeToString(data, Base64.NO_WRAP);
}
public void sign(File in, File out) throws IOException, GeneralSecurityException {
JarFile inputJar = null;
- JarOutputStream outputJar = null;
+ JarOutputStream outputJar;
FileOutputStream outputFile = null;
try {
@@ -254,7 +259,6 @@ public void sign(File in, File out) throws IOException, GeneralSecurityException
copyFiles(manifest, inputJar, outputJar, timestamp);
outputJar.close();
- outputJar = null;
outputStream.flush();
} finally {
@@ -271,32 +275,37 @@ public void sign(File in, File out) throws IOException, GeneralSecurityException
}
}
- /** Write a .RSA file with a digital signature. */
+ /**
+ * Write a .RSA file with a digital signature.
+ */
protected abstract void writeSignatureBlock(byte[] signature, OutputStream out) throws IOException;
- /** Write a .SF file with a digest of the specified manifest. */
+ /**
+ * Write a .SF file with a digest of the specified manifest.
+ */
private void writeSignatureFile(Manifest manifest, SignatureOutputStream out) throws IOException,
GeneralSecurityException {
Manifest sf = new Manifest();
Attributes main = sf.getMainAttributes();
main.putValue("Signature-Version", "1.0");
- main.putValue("Created-By", "1.6.0_21 (d2j-" + AbstractJarSign.class.getPackage().getImplementationVersion() + ")");
+ main.putValue("Created-By",
+ "1.6.0_21 (d2j-" + AbstractJarSign.class.getPackage().getImplementationVersion() + ")");
MessageDigest md = MessageDigest.getInstance(digestAlg);
DigestOutputStream print = new DigestOutputStream(new OutputStream() {
@Override
- public void write(byte[] b) throws IOException {
+ public void write(byte[] b) {
}
@Override
- public void write(byte[] b, int off, int len) throws IOException {
+ public void write(byte[] b, int off, int len) {
}
@Override
- public void write(int b) throws IOException {
+ public void write(int b) {
}
}, md);
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/signapk/Base64.java b/dex-tools/src/main/java/com/googlecode/d2j/signapk/Base64.java
index 91289297c..d405f2e08 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/signapk/Base64.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/signapk/Base64.java
@@ -14,7 +14,8 @@
* limitations under the License.
*/
package com.googlecode.d2j.signapk;
-import java.io.UnsupportedEncodingException;
+
+import java.nio.charset.StandardCharsets;
/**
* Utilities for encoding and decoding the Base64 representation of
@@ -56,7 +57,7 @@ public class Base64 {
public static final int URL_SAFE = 8;
/**
- * Flag to pass to {@link Base64OutputStream} to indicate that it
+ * Flag to pass to the Base64OutputStream to indicate that it
* should not close the output stream it is wrapping when it
* itself is closed.
*/
@@ -77,9 +78,8 @@ public class Base64 {
* of the coded data.
*
* @param finish true if this is the final call to process for
- * this object. Will finalize the coder state and
- * include any final bytes in the output.
- *
+ * this object. Will finalize the coder state and
+ * include any final bytes in the output.
* @return true if the input so far is good; false if some
* error has been detected in the input stream..
*/
@@ -87,8 +87,8 @@ public class Base64 {
/**
* @return the maximum number of bytes a call to process()
- * could produce for the given number of input bytes. This may
- * be an overestimate.
+ * could produce for the given number of input bytes. This may
+ * be an overestimate.
*/
public abstract int maxOutputSize(int len);
}
@@ -104,13 +104,12 @@ public class Base64 {
* The padding '=' characters at the end are considered optional, but
* if any are present, there must be the correct number of them.
*
- * @param str the input String to decode, which is converted to
- * bytes using the default charset
- * @param flags controls certain features of the decoded output.
- * Pass {@code DEFAULT} to decode standard Base64.
- *
+ * @param str the input String to decode, which is converted to
+ * bytes using the default charset
+ * @param flags controls certain features of the decoded output.
+ * Pass {@code DEFAULT} to decode standard Base64.
* @throws IllegalArgumentException if the input contains
- * incorrect padding
+ * incorrect padding
*/
public static byte[] decode(String str, int flags) {
return decode(str.getBytes(), flags);
@@ -124,11 +123,10 @@ public static byte[] decode(String str, int flags) {
* if any are present, there must be the correct number of them.
*
* @param input the input array to decode
- * @param flags controls certain features of the decoded output.
- * Pass {@code DEFAULT} to decode standard Base64.
- *
+ * @param flags controls certain features of the decoded output.
+ * Pass {@code DEFAULT} to decode standard Base64.
* @throws IllegalArgumentException if the input contains
- * incorrect padding
+ * incorrect padding
*/
public static byte[] decode(byte[] input, int flags) {
return decode(input, 0, input.length, flags);
@@ -146,14 +144,13 @@ public static byte[] decode(byte[] input, int flags) {
* @param len the number of bytes of input to decode
* @param flags controls certain features of the decoded output.
* Pass {@code DEFAULT} to decode standard Base64.
- *
* @throws IllegalArgumentException if the input contains
- * incorrect padding
+ * incorrect padding
*/
public static byte[] decode(byte[] input, int offset, int len, int flags) {
// Allocate space for the most data the input could represent.
// (It could contain less if it contains whitespace, etc.)
- Decoder decoder = new Decoder(flags, new byte[len*3/4]);
+ Decoder decoder = new Decoder(flags, new byte[len * 3 / 4]);
if (!decoder.process(input, offset, len, true)) {
throw new IllegalArgumentException("bad base-64");
@@ -176,49 +173,51 @@ public static byte[] decode(byte[] input, int offset, int len, int flags) {
* Lookup table for turning bytes into their position in the
* Base64 alphabet.
*/
- private static final int DECODE[] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
- -1, 0, 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, -1, -1, -1, -1, -1,
- -1, 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, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ private static final int[] DECODE = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
+ -1, 0, 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, -1, -1, -1, -1, -1,
+ -1, 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, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
/**
* Decode lookup table for the "web safe" variant (RFC 3548
* sec. 4) where - and _ replace + and /.
*/
- private static final int DECODE_WEBSAFE[] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
- -1, 0, 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, -1, -1, -1, -1, 63,
- -1, 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, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ private static final int[] DECODE_WEBSAFE = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
+ -1, 0, 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, -1, -1, -1, -1, 63,
+ -1, 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, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
- /** Non-data values in the DECODE arrays. */
+ /**
+ * Non-data values in the DECODE arrays.
+ */
private static final int SKIP = -1;
private static final int EQUALS = -2;
@@ -246,10 +245,10 @@ public Decoder(int flags, byte[] output) {
/**
* @return an overestimate for the number of bytes {@code
- * len} bytes could decode to.
+ * len} bytes could decode to.
*/
public int maxOutputSize(int len) {
- return len * 3/4 + 10;
+ return len * 3 / 4 + 10;
}
/**
@@ -291,13 +290,13 @@ public boolean process(byte[] input, int offset, int len, boolean finish) {
// You can remove this whole block and the output should
// be the same, just slower.
if (state == 0) {
- while (p+4 <= len &&
- (value = ((alphabet[input[p] & 0xff] << 18) |
- (alphabet[input[p+1] & 0xff] << 12) |
- (alphabet[input[p+2] & 0xff] << 6) |
- (alphabet[input[p+3] & 0xff]))) >= 0) {
- output[op+2] = (byte) value;
- output[op+1] = (byte) (value >> 8);
+ while (p + 4 <= len &&
+ (value = ((alphabet[input[p] & 0xff] << 18) |
+ (alphabet[input[p + 1] & 0xff] << 12) |
+ (alphabet[input[p + 2] & 0xff] << 6) |
+ (alphabet[input[p + 3] & 0xff]))) >= 0) {
+ output[op + 2] = (byte) value;
+ output[op + 1] = (byte) (value >> 8);
output[op] = (byte) (value >> 16);
op += 3;
p += 4;
@@ -352,15 +351,15 @@ public boolean process(byte[] input, int offset, int len, boolean finish) {
if (d >= 0) {
// Emit the output triple and return to state 0.
value = (value << 6) | d;
- output[op+2] = (byte) value;
- output[op+1] = (byte) (value >> 8);
+ output[op + 2] = (byte) value;
+ output[op + 1] = (byte) (value >> 8);
output[op] = (byte) (value >> 16);
op += 3;
state = 0;
} else if (d == EQUALS) {
// Emit the last (partial) output tuple;
// expect no further data or padding characters.
- output[op+1] = (byte) (value >> 2);
+ output[op + 1] = (byte) (value >> 2);
output[op] = (byte) (value >> 10);
op += 2;
state = 5;
@@ -444,18 +443,13 @@ public boolean process(byte[] input, int offset, int len, boolean finish) {
* Base64-encode the given data and return a newly allocated
* String with the result.
*
- * @param input the data to encode
- * @param flags controls certain features of the encoded output.
- * Passing {@code DEFAULT} results in output that
- * adheres to RFC 2045.
+ * @param input the data to encode
+ * @param flags controls certain features of the encoded output.
+ * Passing {@code DEFAULT} results in output that
+ * adheres to RFC 2045.
*/
public static String encodeToString(byte[] input, int flags) {
- try {
- return new String(encode(input, flags), "US-ASCII");
- } catch (UnsupportedEncodingException e) {
- // US-ASCII is guaranteed to be available.
- throw new AssertionError(e);
- }
+ return new String(encode(input, flags), StandardCharsets.US_ASCII);
}
/**
@@ -471,22 +465,17 @@ public static String encodeToString(byte[] input, int flags) {
* adheres to RFC 2045.
*/
public static String encodeToString(byte[] input, int offset, int len, int flags) {
- try {
- return new String(encode(input, offset, len, flags), "US-ASCII");
- } catch (UnsupportedEncodingException e) {
- // US-ASCII is guaranteed to be available.
- throw new AssertionError(e);
- }
+ return new String(encode(input, offset, len, flags), StandardCharsets.US_ASCII);
}
/**
* Base64-encode the given data and return a newly allocated
* byte[] with the result.
*
- * @param input the data to encode
- * @param flags controls certain features of the encoded output.
- * Passing {@code DEFAULT} results in output that
- * adheres to RFC 2045.
+ * @param input the data to encode
+ * @param flags controls certain features of the encoded output.
+ * Passing {@code DEFAULT} results in output that
+ * adheres to RFC 2045.
*/
public static byte[] encode(byte[] input, int flags) {
return encode(input, 0, input.length, flags);
@@ -517,16 +506,21 @@ public static byte[] encode(byte[] input, int offset, int len, int flags) {
}
} else {
switch (len % 3) {
- case 0: break;
- case 1: output_len += 2; break;
- case 2: output_len += 3; break;
+ case 0:
+ break;
+ case 1:
+ output_len += 2;
+ break;
+ case 2:
+ output_len += 3;
+ break;
}
}
// Account for the newlines, if any.
if (encoder.do_newline && len > 0) {
- output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *
- (encoder.do_cr ? 2 : 1);
+ output_len += (((len - 1) / (3 * Encoder.LINE_GROUPS)) + 1) *
+ (encoder.do_cr ? 2 : 1);
}
encoder.output = new byte[output_len];
@@ -549,22 +543,22 @@ public static byte[] encode(byte[] input, int offset, int len, int flags) {
* Lookup table for turning Base64 alphabet positions (6 bits)
* into output bytes.
*/
- private static final byte ENCODE[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
+ private static final byte[] ENCODE = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
};
/**
* Lookup table for turning Base64 alphabet positions (6 bits)
* into output bytes.
*/
- private static final byte ENCODE_WEBSAFE[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
+ private static final byte[] ENCODE_WEBSAFE = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
};
final private byte[] tail;
@@ -592,10 +586,10 @@ public Encoder(int flags, byte[] output) {
/**
* @return an overestimate for the number of bytes {@code
- * len} bytes could encode to.
+ * len} bytes could encode to.
*/
public int maxOutputSize(int len) {
- return len * 8/5 + 10;
+ return len * 8 / 5 + 10;
}
public boolean process(byte[] input, int offset, int len, boolean finish) {
@@ -614,30 +608,30 @@ public boolean process(byte[] input, int offset, int len, boolean finish) {
// the tail.
switch (tailLen) {
- case 0:
- // There was no tail.
- break;
+ case 0:
+ // There was no tail.
+ break;
- case 1:
- if (p+2 <= len) {
- // A 1-byte tail with at least 2 bytes of
- // input available now.
- v = ((tail[0] & 0xff) << 16) |
+ case 1:
+ if (p + 2 <= len) {
+ // A 1-byte tail with at least 2 bytes of
+ // input available now.
+ v = ((tail[0] & 0xff) << 16) |
((input[p++] & 0xff) << 8) |
(input[p++] & 0xff);
- tailLen = 0;
- };
- break;
+ tailLen = 0;
+ }
+ break;
- case 2:
- if (p+1 <= len) {
- // A 2-byte tail with at least 1 byte of input.
- v = ((tail[0] & 0xff) << 16) |
+ case 2:
+ if (p + 1 <= len) {
+ // A 2-byte tail with at least 1 byte of input.
+ v = ((tail[0] & 0xff) << 16) |
((tail[1] & 0xff) << 8) |
(input[p++] & 0xff);
- tailLen = 0;
- }
- break;
+ tailLen = 0;
+ }
+ break;
}
if (v != -1) {
@@ -657,14 +651,14 @@ public boolean process(byte[] input, int offset, int len, boolean finish) {
// The main loop, turning 3 input bytes into 4 output bytes on
// each iteration.
- while (p+3 <= len) {
+ while (p + 3 <= len) {
v = ((input[p] & 0xff) << 16) |
- ((input[p+1] & 0xff) << 8) |
- (input[p+2] & 0xff);
+ ((input[p + 1] & 0xff) << 8) |
+ (input[p + 2] & 0xff);
output[op] = alphabet[(v >> 18) & 0x3f];
- output[op+1] = alphabet[(v >> 12) & 0x3f];
- output[op+2] = alphabet[(v >> 6) & 0x3f];
- output[op+3] = alphabet[v & 0x3f];
+ output[op + 1] = alphabet[(v >> 12) & 0x3f];
+ output[op + 2] = alphabet[(v >> 6) & 0x3f];
+ output[op + 3] = alphabet[v & 0x3f];
p += 3;
op += 4;
if (--count == 0) {
@@ -680,7 +674,7 @@ public boolean process(byte[] input, int offset, int len, boolean finish) {
// remaining in input; there should be at most two bytes
// total.
- if (p-tailLen == len-1) {
+ if (p - tailLen == len - 1) {
int t = 0;
v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;
tailLen -= t;
@@ -694,10 +688,10 @@ public boolean process(byte[] input, int offset, int len, boolean finish) {
if (do_cr) output[op++] = '\r';
output[op++] = '\n';
}
- } else if (p-tailLen == len-2) {
+ } else if (p - tailLen == len - 2) {
int t = 0;
v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |
- (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);
+ (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);
tailLen -= t;
output[op++] = alphabet[(v >> 12) & 0x3f];
output[op++] = alphabet[(v >> 6) & 0x3f];
@@ -720,11 +714,11 @@ public boolean process(byte[] input, int offset, int len, boolean finish) {
// Save the leftovers in tail to be consumed on the next
// call to encodeInternal.
- if (p == len-1) {
+ if (p == len - 1) {
tail[tailLen++] = input[p];
- } else if (p == len-2) {
+ } else if (p == len - 2) {
tail[tailLen++] = input[p];
- tail[tailLen++] = input[p+1];
+ tail[tailLen++] = input[p + 1];
}
}
@@ -735,5 +729,6 @@ public boolean process(byte[] input, int offset, int len, boolean finish) {
}
}
- private Base64() { } // don't instantiate
+ private Base64() {
+ } // don't instantiate
}
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/signapk/SunJarSignImpl.java b/dex-tools/src/main/java/com/googlecode/d2j/signapk/SunJarSignImpl.java
index 4e1ab535b..55c563c77 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/signapk/SunJarSignImpl.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/signapk/SunJarSignImpl.java
@@ -5,7 +5,6 @@
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
-
import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7;
import sun.security.pkcs.SignerInfo;
@@ -20,15 +19,17 @@ public SunJarSignImpl(X509Certificate cert, PrivateKey privateKey) {
this.cert = cert;
}
- /** Write a .RSA file with a digital signature. */
+ /**
+ * Write a .RSA file with a digital signature.
+ */
@SuppressWarnings("all")
protected void writeSignatureBlock(byte[] signature, OutputStream out) throws IOException {
try {
SignerInfo signerInfo = new SignerInfo(new X500Name(cert.getIssuerX500Principal().getName()),
cert.getSerialNumber(), AlgorithmId.get(digestAlg), AlgorithmId.get("RSA"), signature);
- PKCS7 pkcs7 = new PKCS7(new AlgorithmId[] { AlgorithmId.get(digestAlg) }, new ContentInfo(
- ContentInfo.DATA_OID, null), new X509Certificate[] { cert }, new SignerInfo[] { signerInfo });
+ PKCS7 pkcs7 = new PKCS7(new AlgorithmId[]{AlgorithmId.get(digestAlg)}, new ContentInfo(
+ ContentInfo.DATA_OID, null), new X509Certificate[]{cert}, new SignerInfo[]{signerInfo});
pkcs7.encodeSignedData(out);
} catch (NoSuchAlgorithmException e) {
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/signapk/TinySignImpl.java b/dex-tools/src/main/java/com/googlecode/d2j/signapk/TinySignImpl.java
index 56c2a11dd..50c121731 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/signapk/TinySignImpl.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/signapk/TinySignImpl.java
@@ -12,9 +12,8 @@
* get from
* https://code.google.com/p/tiny-sign/source/browse/src/main/java/pxb/android
* /tinysign/TinySign.java
- *
+ *
* @author bob
- *
*/
public final class TinySignImpl extends AbstractJarSign {
@@ -23,7 +22,7 @@ private static PrivateKey buildPrivateKey() {
PrivateKey privateKey;
try {
privateKey = KeyFactory.getInstance("RSA").generatePrivate(
- new PKCS8EncodedKeySpec(Base64.decode(sPrivateKey,0)));
+ new PKCS8EncodedKeySpec(Base64.decode(sPrivateKey, 0)));
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
@@ -34,8 +33,16 @@ public TinySignImpl() {
super(buildPrivateKey(), "SHA1", "SHA1withRSA");
}
- private static final String sPrivateKey = "MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEAoiZSqWnFDHA5sXKoDiUUO9JuL7cm/2dCck5MKumVvv+WfSg0jsovnywsFN0pifmdRSLmOdUkh0d0J+tOnSgtsQIDAQABAkEAihag5u3Qhds9BsViIUmqhZebhr8vUuqZR8cuTo1GnbSoOHIPbAgD3J8TDbC/CVqae8NrgwLp325Pem1Tuof/0QIhAN1hqft1K307bsljgw3iYKopGVZBHRXsjRnNL4edV9QrAiEAu4F+XtS1wohGLz5QtfuMFsQNo4l31mCjt6WpBDmSi5MCIQCB++YijxmJ3mueM5+vd0vqnVcTHghF5y6yB5fwuKHpIQIgInnS1Hjj2prX3MPmby+LOHxfzZvvDtnCAHhTNVWonkUCIQCvV8l+SpL6Vh1nQ/2EKFJo2dbZB3wKG/BEYsFkPFbn9w==";
- private static final String sSigPrefix = "MIIB5gYJKoZIhvcNAQcCoIIB1zCCAdMCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCATYwggEyMIHdoAMCAQICBCunMokwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAxMEVGVzdDAeFw0xMjA0MjIwODQ1NDdaFw0xMzA0MjIwODQ1NDdaMA8xDTALBgNVBAMTBFRlc3QwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAoiZSqWnFDHA5sXKoDiUUO9JuL7cm/2dCck5MKumVvv+WfSg0jsovnywsFN0pifmdRSLmOdUkh0d0J+tOnSgtsQIDAQABoyEwHzAdBgNVHQ4EFgQUVL2yOinUwpARE1tOPxc1bf4WrTgwDQYJKoZIhvcNAQELBQADQQAnj/eZwhqwb2tgSYNvgRo5bBNNCpJbQ4alEeP/MLSIWf2nZpAix8T3oS9X2affQtAgctPATcKQaiH2B4L7FKlVMXoweAIBATAXMA8xDTALBgNVBAMTBFRlc3QCBCunMokwCQYFKw4DAhoFADANBgkqhkiG9w0BAQEFAARA";
+ private static final String sPrivateKey =
+ "MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEAoiZSqWnFDHA5sXKoDiUUO9JuL7cm/2dCck5MKumVvv"
+ + "+WfSg0jsovnywsFN0pifmdRSLmOdUkh0d0J"
+ + "+tOnSgtsQIDAQABAkEAihag5u3Qhds9BsViIUmqhZebhr8vUuqZR8cuTo1GnbSoOHIPbAgD3J8TDbC"
+ + "/CVqae8NrgwLp325Pem1Tuof/0QIhAN1hqft1K307bsljgw3iYKopGVZBHRXsjRnNL4edV9QrAiEAu4F"
+ + "+XtS1wohGLz5QtfuMFsQNo4l31mCjt6WpBDmSi5MCIQCB++YijxmJ3mueM5"
+ + "+vd0vqnVcTHghF5y6yB5fwuKHpIQIgInnS1Hjj2prX3MPmby+LOHxfzZvvDtnCAHhTNVWonkUCIQCvV8l+SpL6Vh1nQ"
+ + "/2EKFJo2dbZB3wKG/BEYsFkPFbn9w==";
+ private static final String sSigPrefix =
+ "MIIB5gYJKoZIhvcNAQcCoIIB1zCCAdMCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCATYwggEyMIHdoAMCAQICBCunMokwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAxMEVGVzdDAeFw0xMjA0MjIwODQ1NDdaFw0xMzA0MjIwODQ1NDdaMA8xDTALBgNVBAMTBFRlc3QwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAoiZSqWnFDHA5sXKoDiUUO9JuL7cm/2dCck5MKumVvv+WfSg0jsovnywsFN0pifmdRSLmOdUkh0d0J+tOnSgtsQIDAQABoyEwHzAdBgNVHQ4EFgQUVL2yOinUwpARE1tOPxc1bf4WrTgwDQYJKoZIhvcNAQELBQADQQAnj/eZwhqwb2tgSYNvgRo5bBNNCpJbQ4alEeP/MLSIWf2nZpAix8T3oS9X2affQtAgctPATcKQaiH2B4L7FKlVMXoweAIBATAXMA8xDTALBgNVBAMTBFRlc3QCBCunMokwCQYFKw4DAhoFADANBgkqhkiG9w0BAQEFAARA";
@Override
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/BaseWeaver.java b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/BaseWeaver.java
index 697babc79..fc2af2306 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/BaseWeaver.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/BaseWeaver.java
@@ -16,8 +16,6 @@
*/
package com.googlecode.d2j.tools.jar;
-import org.objectweb.asm.Type;
-
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -25,7 +23,13 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.objectweb.asm.Type;
public class BaseWeaver {
@@ -34,14 +38,14 @@ public class BaseWeaver {
protected static final String DEFAULT_RET_TYPE = "L888;";
protected static final String DEFAULT_DESC = "(L;)" + DEFAULT_RET_TYPE;
- protected List callbacks = new ArrayList();
+ protected List callbacks = new ArrayList<>();
protected int currentInvocationIdx = 0;
protected int seqIndex = 1;
protected MtdInfo key = new MtdInfo();
- protected Set ignores = new HashSet();
- protected Map clzDescMap = new HashMap();
- protected Map mtdMap = new HashMap();
- protected Map defMap = new HashMap();
+ protected Set ignores = new HashSet<>();
+ protected Map clzDescMap = new HashMap<>();
+ protected Map mtdMap = new HashMap<>();
+ protected Map defMap = new HashMap<>();
protected String buildMethodAName(String oldName) {
return String.format("%s_A%03d", oldName, seqIndex++);
@@ -116,62 +120,62 @@ public void withConfig(String ln) {
return;
}
switch (Character.toLowerCase(ln.charAt(0))) {
- case 'i':
- ignores.add(ln.substring(2));
- break;
- case 'c':
- int index = ln.lastIndexOf('=');
- if (index > 0) {
- String key = toInternal(ln.substring(2, index));
- String value = toInternal(ln.substring(index + 1));
- clzDescMap.put(key, value);
- ignores.add(value);
- }
- break;
- case 'r':
- index = ln.lastIndexOf('=');
- if (index > 0) {
- String key = ln.substring(2, index);
- String value = ln.substring(index + 1);
- MtdInfo mi = buildMethodInfo(key);
-
- index = value.indexOf('.');
- MtdInfo mtdValue = new MtdInfo();
- mtdValue.owner = value.substring(0, index);
-
- int index2 = value.indexOf('(', index);
- mtdValue.name = value.substring(index + 1, index2);
- mtdValue.desc = value.substring(index2);
-
- mtdMap.put(mi, mtdValue);
-
- }
- break;
- case 'd':
- index = ln.lastIndexOf('=');
- if (index > 0) {
- String key = ln.substring(2, index);
- String value = ln.substring(index + 1);
- MtdInfo mi = buildMethodInfo(key);
-
- index = value.indexOf('.');
- MtdInfo mtdValue = new MtdInfo();
- mtdValue.owner = value.substring(0, index);
-
- int index2 = value.indexOf('(', index);
- mtdValue.name = value.substring(index + 1, index2);
- mtdValue.desc = value.substring(index2);
-
- defMap.put(mi, mtdValue);
- }
- break;
-
- case 'o':
- setInvocationInterfaceDesc(ln.substring(2));
- break;
- case 'p':
- invocationTypePrefix = ln.substring(2);
- break;
+ case 'i':
+ ignores.add(ln.substring(2));
+ break;
+ case 'c':
+ int index = ln.lastIndexOf('=');
+ if (index > 0) {
+ String key = toInternal(ln.substring(2, index));
+ String value = toInternal(ln.substring(index + 1));
+ clzDescMap.put(key, value);
+ ignores.add(value);
+ }
+ break;
+ case 'r':
+ index = ln.lastIndexOf('=');
+ if (index > 0) {
+ String key = ln.substring(2, index);
+ String value = ln.substring(index + 1);
+ MtdInfo mi = buildMethodInfo(key);
+
+ index = value.indexOf('.');
+ MtdInfo mtdValue = new MtdInfo();
+ mtdValue.owner = value.substring(0, index);
+
+ int index2 = value.indexOf('(', index);
+ mtdValue.name = value.substring(index + 1, index2);
+ mtdValue.desc = value.substring(index2);
+
+ mtdMap.put(mi, mtdValue);
+
+ }
+ break;
+ case 'd':
+ index = ln.lastIndexOf('=');
+ if (index > 0) {
+ String key = ln.substring(2, index);
+ String value = ln.substring(index + 1);
+ MtdInfo mi = buildMethodInfo(key);
+
+ index = value.indexOf('.');
+ MtdInfo mtdValue = new MtdInfo();
+ mtdValue.owner = value.substring(0, index);
+
+ int index2 = value.indexOf('(', index);
+ mtdValue.name = value.substring(index + 1, index2);
+ mtdValue.desc = value.substring(index2);
+
+ defMap.put(mi, mtdValue);
+ }
+ break;
+
+ case 'o':
+ setInvocationInterfaceDesc(ln.substring(2));
+ break;
+ case 'p':
+ invocationTypePrefix = ln.substring(2);
+ break;
}
}
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ClassInfo.java b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ClassInfo.java
index 4f0bf800d..76be513cf 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ClassInfo.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ClassInfo.java
@@ -8,8 +8,8 @@
public class ClassInfo {
final public String name;
- public List members = new ArrayList(5);
- public Set parent = new HashSet();
+ public List members = new ArrayList<>(5);
+ public Set parent = new HashSet<>();
public ClassInfo(String name) {
this.name = name;
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/DexWeaver.java b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/DexWeaver.java
index 65f7cabeb..a6de9b4aa 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/DexWeaver.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/DexWeaver.java
@@ -27,12 +27,11 @@
import com.googlecode.d2j.visitors.DexCodeVisitor;
import com.googlecode.d2j.visitors.DexFileVisitor;
import com.googlecode.d2j.visitors.DexMethodVisitor;
-import org.objectweb.asm.Type;
-
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
+import org.objectweb.asm.Type;
/**
* only implement sub set of InvocationWeaver
@@ -52,7 +51,8 @@ public String buildInvocationClz(DexFileVisitor dfv) {
dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL,
new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"), null).visitEnd();
- dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"), null)
+ dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, "args", "[Ljava"
+ + "/lang/Object;"), null)
.visitEnd();
dcv.visitField(DexConstants.ACC_PRIVATE | DexConstants.ACC_FINAL, new Field(typeNameDesc, "idx", "I"), null)
.visitEnd();
@@ -60,7 +60,8 @@ public String buildInvocationClz(DexFileVisitor dfv) {
{
DexMethodVisitor mv = dcv
- .visitMethod(DexConstants.ACC_PUBLIC | DexConstants.ACC_CONSTRUCTOR, new Method(typeNameDesc, "", new String[]{
+ .visitMethod(DexConstants.ACC_PUBLIC | DexConstants.ACC_CONSTRUCTOR, new Method(typeNameDesc,
+ "", new String[]{
"Ljava/lang/Object;", "[Ljava/lang/Object;", "I"}, "V"));
DexCodeVisitor codeVisitor = mv.visitCode();
codeVisitor.visitRegister(4);
@@ -72,29 +73,15 @@ public String buildInvocationClz(DexFileVisitor dfv) {
mv.visitEnd();
}
{
- genSwitchMethod(dcv, typeNameDesc, "getMethodOwner", new CB() {
- @Override
- public String getKey(Method mtd) {
- return toInternal(mtd.getOwner());
- }
- });
- genSwitchMethod(dcv, typeNameDesc, "getMethodName", new CB() {
- @Override
- public String getKey(Method mtd) {
- return mtd.getName();
- }
- });
- genSwitchMethod(dcv, typeNameDesc, "getMethodDesc", new CB() {
- @Override
- public String getKey(Method mtd) {
- return mtd.getDesc();
- }
- });
+ genSwitchMethod(dcv, typeNameDesc, "getMethodOwner", mtd -> toInternal(mtd.getOwner()));
+ genSwitchMethod(dcv, typeNameDesc, "getMethodName", Method::getName);
+ genSwitchMethod(dcv, typeNameDesc, "getMethodDesc", Method::getDesc);
}
{
DexMethodVisitor mv = dcv
- .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "getArguments", new String[0], "[Ljava/lang/Object;"));
+ .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "getArguments", new String[0],
+ "[Ljava/lang/Object;"));
DexCodeVisitor code = mv.visitCode();
code.visitRegister(2);
code.visitFieldStmt(Op.IGET, 0, 1, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"));
@@ -106,7 +93,8 @@ public String getKey(Method mtd) {
{
DexMethodVisitor mv = dcv
- .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "getThis", new String[0], "Ljava/lang/Object;"));
+ .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "getThis", new String[0], "Ljava"
+ + "/lang/Object;"));
DexCodeVisitor code = mv.visitCode();
code.visitRegister(2);
code.visitFieldStmt(Op.IGET, 0, 1, new Field(typeNameDesc, "thiz", "Ljava/lang/Object;"));
@@ -116,7 +104,8 @@ public String getKey(Method mtd) {
}
{
DexMethodVisitor mv = dcv
- .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "proceed", new String[0], "Ljava/lang/Object;"));
+ .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, "proceed", new String[0], "Ljava"
+ + "/lang/Object;"));
DexCodeVisitor code = mv.visitCode();
code.visitRegister(4);
@@ -125,7 +114,7 @@ public String getKey(Method mtd) {
code.visitFieldStmt(Op.IGET, 1, 3, new Field(typeNameDesc, "args", "[Ljava/lang/Object;"));
code.visitFieldStmt(Op.IGET, 2, 3, new Field(typeNameDesc, "idx", "I"));
- DexLabel labels[] = new DexLabel[callbacks.size()];
+ DexLabel[] labels = new DexLabel[callbacks.size()];
for (int i = 0; i < labels.length; i++) {
labels[i] = new DexLabel();
}
@@ -162,12 +151,13 @@ public String getKey(Method mtd) {
private void genSwitchMethod(DexClassVisitor dcv, String typeNameDesc, String methodName, CB callback) {
DexMethodVisitor dmv = dcv
- .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, methodName, new String[0], "Ljava/lang/String;"));
+ .visitMethod(DexConstants.ACC_PUBLIC, new Method(typeNameDesc, methodName, new String[0], "Ljava/lang"
+ + "/String;"));
DexCodeVisitor code = dmv.visitCode();
code.visitRegister(3);
code.visitFieldStmt(Op.IGET, 0, 2, new Field(typeNameDesc, "idx", "I"));
- DexLabel labels[] = new DexLabel[callbacks.size()];
+ DexLabel[] labels = new DexLabel[callbacks.size()];
Map strMap = new TreeMap<>();
for (int i = 0; i < labels.length; i++) {
@@ -199,7 +189,8 @@ private void genSwitchMethod(DexClassVisitor dcv, String typeNameDesc, String me
public DexFileVisitor wrap(DexFileVisitor dcv) {
return dcv == null ? null : new DexFileVisitor(dcv) {
@Override
- public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {
+ public DexClassVisitor visit(int access_flags, String className, String superClass,
+ String[] interfaceNames) {
return wrap(className, super.visit(access_flags, className, superClass, interfaceNames));
}
};
@@ -235,7 +226,8 @@ public void visitEnd() {
}
generateMtdACode(opcode, t, mapTo, dmv, src);
- int newAccess = (access & ~(DexConstants.ACC_PRIVATE | DexConstants.ACC_PROTECTED)) | DexConstants.ACC_PUBLIC; // make sure public
+ int newAccess =
+ (access & ~(DexConstants.ACC_PRIVATE | DexConstants.ACC_PROTECTED)) | DexConstants.ACC_PUBLIC; // make sure public
code.accept(wrap(superVisitDexMethod(newAccess, t), dcv));
}
};
@@ -275,7 +267,8 @@ public void visitMethodStmt(Op op, int[] args, Method method) {
dmv.visitEnd();
cache.put(buildKey(method.getOwner(), method.getName(), method.getDesc()), methodA);
}
- super.visitMethodStmt(isRange(op) ? Op.INVOKE_STATIC_RANGE : Op.INVOKE_STATIC, args, methodA);
+ super.visitMethodStmt(isRange(op) ? Op.INVOKE_STATIC_RANGE : Op.INVOKE_STATIC, args,
+ methodA);
} else {
super.visitMethodStmt(op, args, method);
}
@@ -327,31 +320,31 @@ private void generateMtdACode(Op opcode, Method t, MtdInfo mapTo, DexMethodVisit
dcv.visitMethodStmt(Op.INVOKE_STATIC, new int[]{3}, call);
if (!"V".equals(t.getReturnType())) {
switch (call.getReturnType().charAt(0)) {
- case '[':
- case 'L':
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);
- break;
- case 'J':
- case 'D':
- dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, 0);
- break;
- default:
- dcv.visitStmt1R(Op.MOVE_RESULT, 0);
- break;
+ case '[':
+ case 'L':
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);
+ break;
+ case 'J':
+ case 'D':
+ dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, 0);
+ break;
+ default:
+ dcv.visitStmt1R(Op.MOVE_RESULT, 0);
+ break;
}
unbox(t.getReturnType(), 0, dcv);
switch (t.getReturnType().charAt(0)) {
- case '[':
- case 'L':
- dcv.visitStmt1R(Op.RETURN_OBJECT, 0);
- break;
- case 'J':
- case 'D':
- dcv.visitStmt1R(Op.RETURN_WIDE, 0);
- break;
- default:
- dcv.visitStmt1R(Op.RETURN, 0);
- break;
+ case '[':
+ case 'L':
+ dcv.visitStmt1R(Op.RETURN_OBJECT, 0);
+ break;
+ case 'J':
+ case 'D':
+ dcv.visitStmt1R(Op.RETURN_WIDE, 0);
+ break;
+ default:
+ dcv.visitStmt1R(Op.RETURN, 0);
+ break;
}
} else {
dcv.visitStmt0R(Op.RETURN_VOID);
@@ -393,14 +386,14 @@ private Method newMethodCallback(Op opcode, Method t) {
argStart = totalRegs - 2;
}
dcv.visitRegister(totalRegs);
- int args[] = new int[countArgs(t) + (isStatic ? 0 : 1)];
+ int[] args = new int[countArgs(t) + (isStatic ? 0 : 1)];
int args_index = 0;
int i = 1;
if (!isStatic) {
if (i != argStart) {
dcv.visitStmt2R(Op.MOVE_OBJECT, i, argStart);
}
- if(!isSuper) {
+ if (!isSuper) {
dcv.visitTypeStmt(Op.CHECK_CAST, i, -1, t.getOwner());
}
args[args_index++] = i;
@@ -428,17 +421,17 @@ private Method newMethodCallback(Op opcode, Method t) {
dcv.visitConstStmt(Op.CONST, 0, 0);
} else {
switch (t.getReturnType().charAt(0)) {
- case '[':
- case 'L':
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);
- break;
- case 'J':
- case 'D':
- dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, 0);
- break;
- default:
- dcv.visitStmt1R(Op.MOVE_RESULT, 0);
- break;
+ case '[':
+ case 'L':
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, 0);
+ break;
+ case 'J':
+ case 'D':
+ dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, 0);
+ break;
+ default:
+ dcv.visitStmt1R(Op.MOVE_RESULT, 0);
+ break;
}
box(t.getReturnType().charAt(0), 0, 0, dcv);
}
@@ -454,7 +447,7 @@ private DexMethodVisitor superVisitDexMethod(int accessFlags, Method method) {
}
private String[] join(String a, String[] b) {
- String joined[] = new String[b.length + 1];
+ String[] joined = new String[b.length + 1];
joined[0] = a;
System.arraycopy(b, 0, joined, 1, b.length);
return joined;
@@ -466,71 +459,71 @@ private boolean isStatic(Op op) {
private boolean isRange(Op op) {
switch (op) {
- case INVOKE_STATIC_RANGE:
- case INVOKE_DIRECT_RANGE:
- case INVOKE_INTERFACE_RANGE:
- case INVOKE_SUPER_RANGE:
- case INVOKE_VIRTUAL_RANGE:
- return true;
- default:
- return false;
+ case INVOKE_STATIC_RANGE:
+ case INVOKE_DIRECT_RANGE:
+ case INVOKE_INTERFACE_RANGE:
+ case INVOKE_SUPER_RANGE:
+ case INVOKE_VIRTUAL_RANGE:
+ return true;
+ default:
+ return false;
}
}
private void unbox(String argType, int i, DexCodeVisitor dcv) {
switch (argType.charAt(0)) {
- case '[':
- case 'L':
- dcv.visitTypeStmt(Op.CHECK_CAST, i, i, argType);
- break;
- case 'Z':
- dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Boolean;");
- dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
- i}, new Method("Ljava/lang/Boolean;", "booleanValue", new String[]{}, "Z"));
- dcv.visitStmt1R(Op.MOVE_RESULT, i);
- break;
- case 'B':
- dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Byte;");
- dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
- i}, new Method("Ljava/lang/Byte;", "byteValue", new String[]{}, "B"));
- dcv.visitStmt1R(Op.MOVE_RESULT, i);
- break;
- case 'S':
- dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Short;");
- dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
- i}, new Method("Ljava/lang/Short;", "shortValue", new String[]{}, "S"));
- dcv.visitStmt1R(Op.MOVE_RESULT, i);
- break;
- case 'C':
- dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Character;");
- dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
- i}, new Method("Ljava/lang/Character;", "charValue", new String[]{}, "C"));
- dcv.visitStmt1R(Op.MOVE_RESULT, i);
- break;
- case 'I':
- dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Integer;");
- dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
- i}, new Method("Ljava/lang/Integer;", "intValue", new String[]{}, "I"));
- dcv.visitStmt1R(Op.MOVE_RESULT, i);
- break;
- case 'F':
- dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Float;");
- dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
- i}, new Method("Ljava/lang/Float;", "floatValue", new String[]{}, "F"));
- dcv.visitStmt1R(Op.MOVE_RESULT, i);
- break;
- case 'D':
- dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Double;");
- dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
- i}, new Method("Ljava/lang/Double;", "doubleValue", new String[]{}, "D"));
- dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, i);
- break;
- case 'J':
- dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Long;");
- dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
- i}, new Method("Ljava/lang/Long;", "longValue", new String[]{}, "J"));
- dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, i);
- break;
+ case '[':
+ case 'L':
+ dcv.visitTypeStmt(Op.CHECK_CAST, i, i, argType);
+ break;
+ case 'Z':
+ dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Boolean;");
+ dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
+ i}, new Method("Ljava/lang/Boolean;", "booleanValue", new String[]{}, "Z"));
+ dcv.visitStmt1R(Op.MOVE_RESULT, i);
+ break;
+ case 'B':
+ dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Byte;");
+ dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
+ i}, new Method("Ljava/lang/Byte;", "byteValue", new String[]{}, "B"));
+ dcv.visitStmt1R(Op.MOVE_RESULT, i);
+ break;
+ case 'S':
+ dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Short;");
+ dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
+ i}, new Method("Ljava/lang/Short;", "shortValue", new String[]{}, "S"));
+ dcv.visitStmt1R(Op.MOVE_RESULT, i);
+ break;
+ case 'C':
+ dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Character;");
+ dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
+ i}, new Method("Ljava/lang/Character;", "charValue", new String[]{}, "C"));
+ dcv.visitStmt1R(Op.MOVE_RESULT, i);
+ break;
+ case 'I':
+ dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Integer;");
+ dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
+ i}, new Method("Ljava/lang/Integer;", "intValue", new String[]{}, "I"));
+ dcv.visitStmt1R(Op.MOVE_RESULT, i);
+ break;
+ case 'F':
+ dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Float;");
+ dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
+ i}, new Method("Ljava/lang/Float;", "floatValue", new String[]{}, "F"));
+ dcv.visitStmt1R(Op.MOVE_RESULT, i);
+ break;
+ case 'D':
+ dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Double;");
+ dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
+ i}, new Method("Ljava/lang/Double;", "doubleValue", new String[]{}, "D"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, i);
+ break;
+ case 'J':
+ dcv.visitTypeStmt(Op.CHECK_CAST, i, i, "Ljava/lang/Long;");
+ dcv.visitMethodStmt(Op.INVOKE_VIRTUAL_RANGE, new int[]{
+ i}, new Method("Ljava/lang/Long;", "longValue", new String[]{}, "J"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_WIDE, i);
+ break;
}
}
@@ -540,7 +533,7 @@ private boolean isSuper(Op opcode) {
private Method build(MtdInfo mapTo) {
Type[] ts = Type.getArgumentTypes(mapTo.desc);
- String ss[] = new String[ts.length];
+ String[] ss = new String[ts.length];
for (int i = 0; i < ss.length; i++) {
ss[i] = ts[i].getDescriptor();
}
@@ -549,53 +542,53 @@ private Method build(MtdInfo mapTo) {
private void box(char type, int from, int to, DexCodeVisitor dcv) {
switch (type) {
- case 'L':
- case '[':
- dcv.visitStmt2R(Op.MOVE_OBJECT, from, to);
- break;
- case 'Z':
- dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
- from}, new Method("Ljava/lang/Boolean;", "valueOf", new String[]{"Z"}, "Ljava/lang/Boolean;"));
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
- break;
- case 'B':
- dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
- from}, new Method("Ljava/lang/Byte;", "valueOf", new String[]{"B"}, "Ljava/lang/Byte;"));
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
- break;
- case 'S':
- dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
- from}, new Method("Ljava/lang/Short;", "valueOf", new String[]{"S"}, "Ljava/lang/Short;"));
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
- break;
- case 'C':
- dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
- from}, new Method("Ljava/lang/Character;", "valueOf", new String[]{
- "C"}, "Ljava/lang/Character;"));
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
- break;
- case 'I':
- dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
- from}, new Method("Ljava/lang/Integer;", "valueOf", new String[]{"I"}, "Ljava/lang/Integer;"));
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
- break;
- case 'F':
- dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
- from}, new Method("Ljava/lang/Float;", "valueOf", new String[]{"F"}, "Ljava/lang/Float;"));
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
- break;
- case 'D':
- dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
- from, from + 1}, new Method("Ljava/lang/Double;", "valueOf", new String[]{
- "D"}, "Ljava/lang/Double;"));
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
- break;
- case 'J':
- dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
- from, from + 1}, new Method("Ljava/lang/Long;", "valueOf", new String[]{
- "J"}, "Ljava/lang/Long;"));
- dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
- break;
+ case 'L':
+ case '[':
+ dcv.visitStmt2R(Op.MOVE_OBJECT, from, to);
+ break;
+ case 'Z':
+ dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
+ from}, new Method("Ljava/lang/Boolean;", "valueOf", new String[]{"Z"}, "Ljava/lang/Boolean;"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
+ break;
+ case 'B':
+ dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
+ from}, new Method("Ljava/lang/Byte;", "valueOf", new String[]{"B"}, "Ljava/lang/Byte;"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
+ break;
+ case 'S':
+ dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
+ from}, new Method("Ljava/lang/Short;", "valueOf", new String[]{"S"}, "Ljava/lang/Short;"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
+ break;
+ case 'C':
+ dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
+ from}, new Method("Ljava/lang/Character;", "valueOf", new String[]{
+ "C"}, "Ljava/lang/Character;"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
+ break;
+ case 'I':
+ dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
+ from}, new Method("Ljava/lang/Integer;", "valueOf", new String[]{"I"}, "Ljava/lang/Integer;"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
+ break;
+ case 'F':
+ dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
+ from}, new Method("Ljava/lang/Float;", "valueOf", new String[]{"F"}, "Ljava/lang/Float;"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
+ break;
+ case 'D':
+ dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
+ from, from + 1}, new Method("Ljava/lang/Double;", "valueOf", new String[]{
+ "D"}, "Ljava/lang/Double;"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
+ break;
+ case 'J':
+ dcv.visitMethodStmt(Op.INVOKE_STATIC_RANGE, new int[]{
+ from, from + 1}, new Method("Ljava/lang/Long;", "valueOf", new String[]{
+ "J"}, "Ljava/lang/Long;"));
+ dcv.visitStmt1R(Op.MOVE_RESULT_OBJECT, to);
+ break;
}
}
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InitOut.java b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InitOut.java
index b3aeadd62..6b5503f9c 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InitOut.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InitOut.java
@@ -2,26 +2,45 @@
import com.googlecode.dex2jar.tools.BaseCmd;
import com.googlecode.dex2jar.tools.Constants;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.tree.*;
-
-import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.*;
-
-import static com.googlecode.d2j.util.AccUtils.*;
-import static org.objectweb.asm.Opcodes.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TypeInsnNode;
+
+import static com.googlecode.d2j.util.AccUtils.isEnum;
+import static com.googlecode.d2j.util.AccUtils.isFinal;
+import static com.googlecode.d2j.util.AccUtils.isPrivate;
+import static com.googlecode.d2j.util.AccUtils.isProtected;
+import static com.googlecode.d2j.util.AccUtils.isPublic;
+import static com.googlecode.d2j.util.AccUtils.isStatic;
+import static com.googlecode.d2j.util.AccUtils.isSynthetic;
+import static org.objectweb.asm.Opcodes.DUP;
+import static org.objectweb.asm.Opcodes.LDC;
+import static org.objectweb.asm.Opcodes.NEW;
+import static org.objectweb.asm.Opcodes.PUTSTATIC;
public class InitOut {
- private static final Set keywords = new HashSet(Arrays.asList("abstract", "continue", "for", "new",
+ private static final Set keywords = new HashSet<>(Arrays.asList("abstract", "continue", "for", "new",
"switch", "assert", "default", "goto", "package", "synchronized", "boolean", "do", "if", "private", "this",
"break", "double", "implements", "protected", "throw", "byte", "else", "import", "public", "throws",
"case", "enum", "instanceof", "return", "transient", "catch", "extends", "int", "short", "try", "char",
@@ -156,7 +175,8 @@ public void visitSource(String source, String debug) {
}
@Override
- public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature,
+ String[] exceptions) {
clz.addMethod(access, name, desc);
if (initEnumNames && isEnum && name.equals("")) {
final String thisDesc = "L" + clz.name + ";";
@@ -194,7 +214,7 @@ public void visitEnd() {
} else {
status = 0;
}
- } else if (status == 3) { //find LDC
+ } else { //find LDC
if (p.getOpcode() == PUTSTATIC) {
FieldInsnNode fin = (FieldInsnNode) p;
if (fin.owner.equals(thisDesc) && fin.desc.equals(thisDesc)) {
@@ -254,20 +274,21 @@ public void visitEnd() {
}
@Override
- public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+ public void visit(int version, int access, String name, String signature, String superName,
+ String[] interfaces) {
this.clz = new ClassInfo(name);
isEnum = isEnum(access);
}
};
- try(FileSystem fs = BaseCmd.openZip(file)) {
- BaseCmd.walkJarOrDir(fs.getPath("/"), (file1, relative) -> {
- if (relative.endsWith(".class")) {
- byte[] data = Files.readAllBytes(file1);
- new ClassReader(data).accept(collectVisitor, ClassReader.EXPAND_FRAMES);
- }
- });
- }
+ try (FileSystem fs = BaseCmd.openZip(file)) {
+ BaseCmd.walkJarOrDir(fs.getPath("/"), (file1, relative) -> {
+ if (relative.endsWith(".class")) {
+ byte[] data = Files.readAllBytes(file1);
+ new ClassReader(data).accept(collectVisitor, ClassReader.EXPAND_FRAMES);
+ }
+ });
+ }
return clzList;
}
@@ -316,7 +337,7 @@ public void to(Path config) throws IOException {
list.addAll(pkgMap);
list.addAll(clzMap);
list.addAll(memberMap);
- Files.write(config,list, StandardCharsets.UTF_8);
+ Files.write(config, list, StandardCharsets.UTF_8);
}
private void transformerMember(String owner, List members) {
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InvocationWeaver.java b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InvocationWeaver.java
index 2fd75a0ad..f1be76d0a 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InvocationWeaver.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/InvocationWeaver.java
@@ -18,24 +18,34 @@
import com.googlecode.dex2jar.tools.BaseCmd;
import com.googlecode.dex2jar.tools.Constants;
-import org.objectweb.asm.*;
-import org.objectweb.asm.commons.ClassRemapper;
-import org.objectweb.asm.commons.Remapper;
-import org.objectweb.asm.tree.InsnList;
-import org.objectweb.asm.tree.LocalVariableNode;
-import org.objectweb.asm.tree.MethodNode;
-import org.objectweb.asm.tree.TryCatchBlockNode;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
import java.util.jar.Attributes.Name;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.ClassRemapper;
+import org.objectweb.asm.commons.Remapper;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.LocalVariableNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
/**
* 1. Replace class A to another class B, include superclass, new for
@@ -125,36 +135,36 @@ public String mapDesc(String desc) {
static private void box(Type arg, MethodVisitor mv) {
switch (arg.getSort()) {
- case Type.OBJECT:
- case Type.ARRAY:
- return;
- case Type.INT:
- mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
- break;
- case Type.LONG:
- mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
- break;
- case Type.FLOAT:
- mv.visitMethodInsn(INVOKESTATIC, "java/lang/Floag", "valueOf", "(F)Ljava/lang/Floag;", false);
- break;
- case Type.DOUBLE:
- mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
- break;
- case Type.SHORT:
- mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
- break;
- case Type.CHAR:
- mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
- break;
- case Type.BOOLEAN:
- mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
- break;
- case Type.BYTE:
- mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
- break;
- case Type.VOID:
- mv.visitInsn(ACONST_NULL);
- break;
+ case Type.OBJECT:
+ case Type.ARRAY:
+ return;
+ case Type.INT:
+ mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
+ break;
+ case Type.LONG:
+ mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
+ break;
+ case Type.FLOAT:
+ mv.visitMethodInsn(INVOKESTATIC, "java/lang/Floag", "valueOf", "(F)Ljava/lang/Floag;", false);
+ break;
+ case Type.DOUBLE:
+ mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
+ break;
+ case Type.SHORT:
+ mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
+ break;
+ case Type.CHAR:
+ mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
+ break;
+ case Type.BOOLEAN:
+ mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
+ break;
+ case Type.BYTE:
+ mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
+ break;
+ case Type.VOID:
+ mv.visitInsn(ACONST_NULL);
+ break;
}
}
@@ -169,42 +179,42 @@ static private void unBox(Type orgRet, Type nRet, MethodVisitor mv) {
throw new RuntimeException("invalid ret type:" + nRet);
}
switch (orgRet.getSort()) {
- case Type.OBJECT:
- case Type.ARRAY:
- mv.visitTypeInsn(CHECKCAST, orgRet.getInternalName());
- break;
- case Type.INT:
- mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I", false);
- break;
- case Type.FLOAT:
- mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "floatValue", "()F", false);
- break;
- case Type.LONG:
- mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "longValue", "()J", false);
- break;
- case Type.DOUBLE:
- mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "doubleValue", "()D", false);
- break;
- case Type.BYTE:
- mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "byteValue", "()B", false);
- break;
- case Type.SHORT:
- mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "shortValue", "()S", false);
- break;
- case Type.CHAR:
- mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
- break;
- case Type.BOOLEAN:
- mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
- mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
- break;
+ case Type.OBJECT:
+ case Type.ARRAY:
+ mv.visitTypeInsn(CHECKCAST, orgRet.getInternalName());
+ break;
+ case Type.INT:
+ mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I", false);
+ break;
+ case Type.FLOAT:
+ mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "floatValue", "()F", false);
+ break;
+ case Type.LONG:
+ mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "longValue", "()J", false);
+ break;
+ case Type.DOUBLE:
+ mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "doubleValue", "()D", false);
+ break;
+ case Type.BYTE:
+ mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "byteValue", "()B", false);
+ break;
+ case Type.SHORT:
+ mv.visitTypeInsn(CHECKCAST, "java/lang/Number");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "shortValue", "()S", false);
+ break;
+ case Type.CHAR:
+ mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
+ break;
+ case Type.BOOLEAN:
+ mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
+ mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
+ break;
}
}
@@ -304,7 +314,7 @@ private void genMethodACode(int opcode, MtdInfo t, MtdInfo mapTo, MethodVisitor
private MtdInfo newMethodCallback(int opcode, MtdInfo t) {
MtdInfo n = new MtdInfo();
n.owner = "L" + className + ";";
- n.name = buildCallbackMethodName(t.name) ;
+ n.name = buildCallbackMethodName(t.name);
if (opcode == INVOKESPECIAL || opcode == INVOKESTATIC) {
n.desc = "([Ljava/lang/Object;)Ljava/lang/Object;";
} else {
@@ -355,7 +365,7 @@ public MethodVisitor visitMethod(int access, final String name, String desc, Str
if (mapTo != null) {
final MtdInfo t1 = new MtdInfo();
t1.owner = "L" + clzName + ";";
- t1.name = buildMethodAName(name) ;
+ t1.name = buildMethodAName(name);
t1.desc = desc;
final MtdInfo src = new MtdInfo();
src.owner = t1.owner;
@@ -385,7 +395,7 @@ public void visitEnd() {
int newAccess = (access & ~(ACC_PRIVATE | ACC_PROTECTED)) | ACC_PUBLIC; // make sure public
MethodVisitor rmv = wrap(superMethodVisitor(newAccess, t1.name, desc, null, null));
- if(rmv!=null) {
+ if (rmv != null) {
rmv.visitCode();
int n, i;
n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
@@ -409,13 +419,15 @@ public void visitEnd() {
}
}
- private MethodVisitor superMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) {
+ private MethodVisitor superMethodVisitor(int access, String name, String desc, String signature,
+ String[] exceptions) {
return super.visitMethod(access, name, desc, signature, exceptions);
}
- MethodVisitor wrap(MethodVisitor mv){
- return mv==null?null: new ReplaceMethodVisitor(mv);
+ MethodVisitor wrap(MethodVisitor mv) {
+ return mv == null ? null : new ReplaceMethodVisitor(mv);
}
+
class ReplaceMethodVisitor extends MethodVisitor {
public ReplaceMethodVisitor(MethodVisitor mv) {
super(Constants.ASM_VERSION, mv);
@@ -464,7 +476,8 @@ public void visitMethodInsn(int opcode, String owner, String name, String desc,
}
}
// replace it!
- super.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc, isInterface);
+ super.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc,
+ isInterface);
unBox(orgRet, nRet, this.mv);
}
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ScanBridgeAdapter.java b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ScanBridgeAdapter.java
index 344647b16..bddf76c64 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ScanBridgeAdapter.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/ScanBridgeAdapter.java
@@ -2,20 +2,19 @@
import com.googlecode.d2j.tools.jar.ClassInfo.MemberInfo;
import com.googlecode.dex2jar.tools.Constants;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
import static com.googlecode.d2j.util.AccUtils.isBridge;
import static com.googlecode.d2j.util.AccUtils.isSynthetic;
public class ScanBridgeAdapter extends ClassVisitor implements Opcodes {
- private Map bridge = new HashMap();
+ private Map bridge = new HashMap<>();
public ScanBridgeAdapter(ClassVisitor cv) {
super(Constants.ASM_VERSION, cv);
diff --git a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/WebApp.java b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/WebApp.java
index dcfc65411..66f73b5ca 100644
--- a/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/WebApp.java
+++ b/dex-tools/src/main/java/com/googlecode/d2j/tools/jar/WebApp.java
@@ -1,7 +1,6 @@
package com.googlecode.d2j.tools.jar;
import com.googlecode.dex2jar.tools.BaseCmd;
-
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@@ -16,8 +15,7 @@
public class WebApp {
/**
- * @param args
- * @throws IOException
+ *
*/
public static void main(String[] args) throws IOException {
if (args.length < 2) {
@@ -42,7 +40,7 @@ public static void main(String[] args) throws IOException {
final File lib = new File(webApp, "WEB-INF/lib");
Path tmpLib = new File(webApp, "WEB-INF/Nlib").toPath();
- final Set ignores = new HashSet();
+ final Set ignores = new HashSet<>();
if (jarIgnore != null && Files.exists(jarIgnore)) {
ignores.addAll(Files.readAllLines(jarIgnore, StandardCharsets.UTF_8));
} else {
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/bin_gen/BinGen.java b/dex-tools/src/main/java/com/googlecode/dex2jar/bin_gen/BinGen.java
index f8f3783e4..eebbb998f 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/bin_gen/BinGen.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/bin_gen/BinGen.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,13 +17,17 @@
package com.googlecode.dex2jar.bin_gen;
import com.googlecode.dex2jar.tools.BaseCmd;
-
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
-import java.nio.file.*;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.Properties;
@@ -31,8 +35,7 @@
public class BinGen {
/**
- * @param args
- * @throws IOException
+ *
*/
public static void main(String[] args) throws IOException {
if (args.length < 2) {
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ApkSign.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ApkSign.java
index 0ab8b6778..238f95563 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ApkSign.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ApkSign.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,8 +16,11 @@
*/
package com.googlecode.dex2jar.tools;
+import com.googlecode.d2j.reader.zip.ZipUtil;
+import com.googlecode.d2j.signapk.AbstractJarSign;
+import com.googlecode.d2j.signapk.SunJarSignImpl;
+import com.googlecode.d2j.signapk.TinySignImpl;
import java.io.File;
-import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -27,12 +30,8 @@
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
-import com.googlecode.d2j.reader.zip.ZipUtil;
-import com.googlecode.d2j.signapk.AbstractJarSign;
-import com.googlecode.d2j.signapk.SunJarSignImpl;
-import com.googlecode.d2j.signapk.TinySignImpl;
-
-@BaseCmd.Syntax(cmd = "d2j-apk-sign", syntax = "[options] ", desc = "Sign an android apk file use a test certificate.")
+@BaseCmd.Syntax(cmd = "d2j-apk-sign", syntax = "[options] ", desc = "Sign an android apk file use a test "
+ + "certificate.")
public class ApkSign extends BaseCmd {
public static void main(String... args) {
new ApkSign().doMain(args);
@@ -40,7 +39,8 @@ public static void main(String... args) {
@Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite")
private boolean forceOverwrite = false;
- @Opt(opt = "o", longOpt = "output", description = "output .apk file, default is $current_dir/[apk-name]-signed.apk", argName = "out-apk-file")
+ @Opt(opt = "o", longOpt = "output", description = "output .apk file, default is $current_dir/[apk-name]-signed"
+ + ".apk", argName = "out-apk-file")
private Path output;
@Opt(opt = "t", longOpt = "tiny", hasArg = false, description = "use tiny sign")
private boolean tiny = false;
@@ -81,13 +81,10 @@ protected void doCommandLine() throws Exception {
System.out.println("zipping " + apkIn + " -> " + realJar);
try (FileSystem fs = createZip(realJar)) {
final Path outRoot = fs.getPath("/");
- walkJarOrDir(apkIn, new FileVisitorX() {
- @Override
- public void visitFile(Path file, String relative) throws IOException {
- Path target = outRoot.resolve(relative);
- createParentDirectories(target);
- Files.copy(file, target);
- }
+ walkJarOrDir(apkIn, (file, relative) -> {
+ Path target = outRoot.resolve(relative);
+ createParentDirectories(target);
+ Files.copy(file, target);
});
}
} else {
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/AsmVerify.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/AsmVerify.java
index ffde075ce..46ea76806 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/AsmVerify.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/AsmVerify.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,8 +16,8 @@
*/
package com.googlecode.dex2jar.tools;
+import com.googlecode.dex2jar.tools.BaseCmd.Syntax;
import java.io.File;
-import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Field;
@@ -26,7 +26,6 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
-
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
@@ -40,8 +39,6 @@
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceMethodVisitor;
-import com.googlecode.dex2jar.tools.BaseCmd.Syntax;
-
@Syntax(cmd = "d2j-asm-verify", syntax = "[options] [jar1 ... jarN]", desc = "Verify .class in jar")
public class AsmVerify extends BaseCmd {
@@ -55,6 +52,7 @@ public static void main(String... args) {
}
static Field buf;
+
static {
try {
buf = Printer.class.getDeclaredField("buf");
@@ -92,7 +90,7 @@ static void printAnalyzerResult(MethodNode method, Analyzer a, final PrintWriter
e.printStackTrace();
}
}
- for (TryCatchBlockNode tryCatchBlockNode: method.tryCatchBlocks) {
+ for (TryCatchBlockNode tryCatchBlockNode : method.tryCatchBlocks) {
tryCatchBlockNode.accept(mv);
try {
pw.print(" " + buf.get(t));
@@ -127,26 +125,24 @@ protected void doCommandLine() throws Exception {
for (Path file : files) {
System.out.println("verify " + file);
- walkJarOrDir(file, new FileVisitorX() {
- @Override
- public void visitFile(Path file, String relative) throws IOException {
- if (file.getFileName().toString().endsWith(".class")) {
- ClassReader cr = new ClassReader(Files.readAllBytes(file));
- ClassNode cn = new ClassNode();
- cr.accept(new CheckClassAdapter(cn, false),
- ClassReader.SKIP_DEBUG | ClassReader.EXPAND_FRAMES | ClassReader.SKIP_FRAMES);
- for (MethodNode method : cn.methods) {
- BasicVerifier verifier = new BasicVerifier();
- Analyzer a = new Analyzer<>(verifier);
- try {
- a.analyze(cn.name, method);
- } catch (Exception ex) {
- System.err.println("Error verify method " + cr.getClassName() + "." + method.name + " "
- + method.desc);
- if (detail) {
- ex.printStackTrace(System.err);
- printAnalyzerResult(method, a, new PrintWriter(new OutputStreamWriter(System.err, StandardCharsets.UTF_8)));
- }
+ walkJarOrDir(file, (file1, relative) -> {
+ if (file1.getFileName().toString().endsWith(".class")) {
+ ClassReader cr = new ClassReader(Files.readAllBytes(file1));
+ ClassNode cn = new ClassNode();
+ cr.accept(new CheckClassAdapter(cn, false),
+ ClassReader.SKIP_DEBUG | ClassReader.EXPAND_FRAMES | ClassReader.SKIP_FRAMES);
+ for (MethodNode method : cn.methods) {
+ BasicVerifier verifier = new BasicVerifier();
+ Analyzer a = new Analyzer<>(verifier);
+ try {
+ a.analyze(cn.name, method);
+ } catch (Exception ex) {
+ System.err.println("Error verify method " + cr.getClassName() + "." + method.name + " "
+ + method.desc);
+ if (detail) {
+ ex.printStackTrace(System.err);
+ printAnalyzerResult(method, a, new PrintWriter(new OutputStreamWriter(System.err,
+ StandardCharsets.UTF_8)));
}
}
}
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/BaksmaliBaseDexExceptionHandler.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/BaksmaliBaseDexExceptionHandler.java
index 5fc6e216a..e8a8e04a0 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/BaksmaliBaseDexExceptionHandler.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/BaksmaliBaseDexExceptionHandler.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -24,8 +24,6 @@
import com.googlecode.d2j.smali.BaksmaliDumper;
import com.googlecode.d2j.smali.Smali;
import com.googlecode.dex2jar.ir.ET;
-import org.objectweb.asm.MethodVisitor;
-
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
@@ -34,17 +32,24 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TimeZone;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
+import org.objectweb.asm.MethodVisitor;
public class BaksmaliBaseDexExceptionHandler extends BaseDexExceptionHandler {
- public static final String REPORT_MESSAGE = "Please report this file to one of following link if possible (any one).\n" + //
- " https://sourceforge.net/p/dex2jar/tickets/\n" + //
- " https://bitbucket.org/pxb1988/dex2jar/issues\n" + //
- " https://github.com/pxb1988/dex2jar/issues\n" + //
- " dex2jar@googlegroups.com";
+ public static final String REPORT_MESSAGE = "Please report this file to one of following link if possible (any "
+ + "one).\n" + //
+ " https://github.com/ThexXTURBOXx/dex2jar/issues\n" + //
+ " nico.mexis@kabelmail.de";
private Map exceptionMap = new HashMap<>();
private List fileExceptions = new ArrayList<>();
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ClassVersionSwitch.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ClassVersionSwitch.java
index 9e34efe88..cfc3e99bc 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ClassVersionSwitch.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ClassVersionSwitch.java
@@ -1,11 +1,6 @@
package com.googlecode.dex2jar.tools;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
-
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -14,9 +9,13 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
public class ClassVersionSwitch {
- static final int jVersions[] = new int[]{
+ static final int[] jVersions = new int[]{
0,
Opcodes.V1_1,
Opcodes.V1_2,
@@ -54,11 +53,12 @@ public static void main(String... args) throws IOException {
ClassWriter cw = new ClassWriter(0);
ClassVisitor cv = new ClassVisitor(Constants.ASM_VERSION, cw) {
@Override
- public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+ public void visit(int version, int access, String name, String signature,
+ String superName, String[] interfaces) {
super.visit(jVersion, access, name, signature, superName, interfaces);
}
};
- cr.accept(cv, ClassReader.EXPAND_FRAMES|ClassReader.SKIP_FRAMES);
+ cr.accept(cv, ClassReader.EXPAND_FRAMES | ClassReader.SKIP_FRAMES);
zos.write(cw.toByteArray());
} else {
for (int c = is.read(buff); c > 0; c = is.read(buff)) {
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DeObfInitCmd.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DeObfInitCmd.java
index a0c17f1fa..8684d2b86 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DeObfInitCmd.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DeObfInitCmd.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,7 +17,6 @@
package com.googlecode.dex2jar.tools;
import com.googlecode.d2j.tools.jar.InitOut;
-
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -25,11 +24,14 @@
public class DeObfInitCmd extends BaseCmd {
@Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite")
private boolean forceOverwrite = false;
- @Opt(opt = "o", longOpt = "output", description = "output .jar file, default is $current_dir/[file-name]-deobf-init.txt", argName = "out-file")
+ @Opt(opt = "o", longOpt = "output", description = "output .jar file, default is "
+ + "$current_dir/[file-name]-deobf-init.txt", argName = "out-file")
private Path output;
- @Opt(opt = "min", longOpt = "min-length", description = "do the rename if the length < MIN, default is 2", argName = "MIN")
+ @Opt(opt = "min", longOpt = "min-length", description = "do the rename if the length < MIN, default is 2",
+ argName = "MIN")
private int min = 2;
- @Opt(opt = "max", longOpt = "max-length", description = "do the rename if the length > MIN, default is 40", argName = "MAX")
+ @Opt(opt = "max", longOpt = "max-length", description = "do the rename if the length > MIN, default is 40",
+ argName = "MAX")
private int max = 40;
public DeObfInitCmd() {
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DecryptStringCmd.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DecryptStringCmd.java
index e2b7470e9..91f3af297 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DecryptStringCmd.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DecryptStringCmd.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,16 +21,26 @@
import com.googlecode.d2j.util.Escape;
import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.StmtTraveler;
-import com.googlecode.dex2jar.ir.expr.*;
-import com.googlecode.dex2jar.ir.ts.*;
+import com.googlecode.dex2jar.ir.expr.Constant;
+import com.googlecode.dex2jar.ir.expr.Exprs;
+import com.googlecode.dex2jar.ir.expr.FilledArrayExpr;
+import com.googlecode.dex2jar.ir.expr.InvokeExpr;
+import com.googlecode.dex2jar.ir.expr.Value;
+import com.googlecode.dex2jar.ir.ts.AggTransformer;
+import com.googlecode.dex2jar.ir.ts.CleanLabel;
+import com.googlecode.dex2jar.ir.ts.DeadCodeTransformer;
+import com.googlecode.dex2jar.ir.ts.ExceptionHandlerTrim;
+import com.googlecode.dex2jar.ir.ts.Ir2JRegAssignTransformer;
+import com.googlecode.dex2jar.ir.ts.NewTransformer;
+import com.googlecode.dex2jar.ir.ts.NpeTransformer;
+import com.googlecode.dex2jar.ir.ts.RemoveConstantFromSSA;
+import com.googlecode.dex2jar.ir.ts.RemoveLocalFromSSA;
+import com.googlecode.dex2jar.ir.ts.TypeTransformer;
+import com.googlecode.dex2jar.ir.ts.UnSSATransformer;
+import com.googlecode.dex2jar.ir.ts.VoidInvokeTransformer;
+import com.googlecode.dex2jar.ir.ts.ZeroTransformer;
import com.googlecode.dex2jar.ir.ts.array.FillArrayTransformer;
import com.googlecode.dex2jar.tools.BaseCmd.Syntax;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
-import org.objectweb.asm.Type;
-import org.objectweb.asm.tree.*;
-
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
@@ -42,9 +52,25 @@
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.IntInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MethodNode;
-@Syntax(cmd = "d2j-decrypt-string", syntax = "[options] ", desc = "Decrypt in class file", onlineHelp = "https://sourceforge.net/p/dex2jar/wiki/DecryptStrings\nhttps://bitbucket.org/pxb1988/dex2jar/wiki/DecryptStrings")
+@Syntax(cmd = "d2j-decrypt-string", syntax = "[options] ", desc = "Decrypt in class file", onlineHelp = "https"
+ + "://sourceforge.net/p/dex2jar/wiki/DecryptStrings\nhttps://bitbucket.org/pxb1988/dex2jar/wiki/DecryptStrings")
public class DecryptStringCmd extends BaseCmd {
public static void main(String... args) {
new DecryptStringCmd().doMain(args);
@@ -52,24 +78,34 @@ public static void main(String... args) {
@Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite")
private boolean forceOverwrite = false;
- @Opt(opt = "o", longOpt = "output", description = "output of .jar files, default is $current_dir/[jar-name]-decrypted.jar", argName = "out")
+ @Opt(opt = "o", longOpt = "output", description = "output of .jar files, default is "
+ + "$current_dir/[jar-name]-decrypted.jar", argName = "out")
private Path output;
- @Opt(opt = "m", longOpt = "methods", description = "a file contain a list of methods, each line like: La/b;->decrypt(III)Ljava/lang/String;", argName = "cfg")
+ @Opt(opt = "m", longOpt = "methods", description = "a file contain a list of methods, each line like: La/b;"
+ + "->decrypt(III)Ljava/lang/String;", argName = "cfg")
private Path method;
- @Opt(opt = "mo", longOpt = "decrypt-method-owner", description = "the owner of the method which can decrypt the stings, example: java.lang.String", argName = "owner")
+ @Opt(opt = "mo", longOpt = "decrypt-method-owner", description = "the owner of the method which can decrypt the "
+ + "stings, example: java.lang.String", argName = "owner")
private String methodOwner;
- @Opt(opt = "mn", longOpt = "decrypt-method-name", description = "the owner of the method which can decrypt the stings, the method's signature must be static (parameter-type)Ljava/lang/String;. Please use -pt,--parameter-type to set the argument descrypt.", argName = "name")
+ @Opt(opt = "mn", longOpt = "decrypt-method-name", description = "the owner of the method which can decrypt the "
+ + "stings, the method's signature must be static (parameter-type)Ljava/lang/String;. Please use -pt,"
+ + "--parameter-type to set the argument decrypt.", argName = "name")
private String methodName;
@Opt(opt = "cp", longOpt = "classpath", description = "add extra lib to classpath", argName = "cp")
private String classpath;
- //extended parameter option: e.g. '-t int,byte,string' to specify a routine such as decryptionRoutine(int a, byte b, String c)
- @Opt(opt = "t", longOpt = "arg-types", description = "comma-separated list of types:boolean,byte,short,char,int,long,float,double,string. Default is string", argName = "type")
+ //extended parameter option: e.g. '-t int,byte,string' to specify a routine such as decryptionRoutine(int a, byte
+ // b, String c)
+ @Opt(opt = "t", longOpt = "arg-types", description = "comma-separated list of types:boolean,byte,short,char,int,"
+ + "long,float,double,string. Default is string", argName = "type")
private String parameterJTypes;
- @Opt(opt = "pd", longOpt = "parameters-descriptor", description = "the descriptor for the method which can decrypt the stings, example1: Ljava/lang/String; example2: III, default is Ljava/lang/String;", argName = "type")
+ @Opt(opt = "pd", longOpt = "parameters-descriptor", description = "the descriptor for the method which can "
+ + "decrypt the stings, example1: Ljava/lang/String; example2: III, default is Ljava/lang/String;",
+ argName = "type")
private String parametersDescriptor;
@Opt(opt = "d", longOpt = "delete", hasArg = false, description = "delete the method which can decrypt the stings")
private boolean deleteMethod = false;
- @Opt(opt = "da", longOpt = "deep-analyze", hasArg = false, description = "use dex2jar IR to static analyze and find more values like byte[]")
+ @Opt(opt = "da", longOpt = "deep-analyze", hasArg = false, description = "use dex2jar IR to static analyze and "
+ + "find more values like byte[]")
private boolean deepAnalyze = false;
@Opt(opt = "v", longOpt = "verbose", hasArg = false, description = "show more on output")
private boolean verbose = false;
@@ -189,26 +225,23 @@ protected void doCommandLine() throws Exception {
final Map map = loadMethods(jar, methodConfigs);
try (FileSystem outputFileSystem = createZip(output)) {
final Path outputBase = outputFileSystem.getPath("/");
- walkJarOrDir(jar, new FileVisitorX() {
- @Override
- public void visitFile(Path file, String relative) throws IOException {
- if (file.getFileName().toString().endsWith(".class")) {
- Path dist1 = outputBase.resolve(relative);
- createParentDirectories(dist1);
- byte[] data = Files.readAllBytes(file);
- ClassNode cn = readClassNode(data);
-
- if (decrypt(cn, map)) {
- byte[] data2 = toByteArray(cn);
- Files.write(dist1, data2);
- } else {
- Files.write(dist1, data);
- }
+ walkJarOrDir(jar, (file, relative) -> {
+ if (file.getFileName().toString().endsWith(".class")) {
+ Path dist1 = outputBase.resolve(relative);
+ createParentDirectories(dist1);
+ byte[] data = Files.readAllBytes(file);
+ ClassNode cn = readClassNode(data);
+
+ if (decrypt(cn, map)) {
+ byte[] data2 = toByteArray(cn);
+ Files.write(dist1, data2);
} else {
- Path dist1 = outputBase.resolve(relative);
- createParentDirectories(dist1);
- Files.copy(file, dist1);
+ Files.write(dist1, data);
}
+ } else {
+ Path dist1 = outputBase.resolve(relative);
+ createParentDirectories(dist1);
+ Files.copy(file, dist1);
}
});
}
@@ -296,13 +329,12 @@ private boolean decryptByIr(ClassNode cn, Map map) {
// copy back m3 to m
m.maxLocals = -1;
- m.maxLocals = -1;
m.instructions = m3.instructions;
m.tryCatchBlocks = m3.tryCatchBlocks;
m.localVariables = null;
changed = true;
} catch (Exception ex) {
- if(verbose) {
+ if (verbose) {
ex.printStackTrace();
}
}
@@ -350,7 +382,8 @@ private boolean decryptByStack(ClassNode cn, Map map
Method jmethod = config.jmethod;
try {
int pSize = jmethod.getParameterTypes().length;
- // arguments' list. each parameter's value is retrieved by reading bytecode backwards, starting from the INVOKESTATIC statement
+ // arguments' list. each parameter's value is retrieved by reading bytecode backwards,
+ // starting from the INVOKESTATIC statement
Object[] as = readArgumentValues(mn, jmethod, pSize);
if (verbose) {
System.out.println(" > calling " + jmethod + " with arguments " + v(as));
@@ -368,8 +401,8 @@ private boolean decryptByStack(ClassNode cn, Map map
removeInsts(m, mn, pSize);
p = nLdc;
changed = true;
- } catch (InvocationTargetException ex){
- if(verbose){
+ } catch (InvocationTargetException ex) {
+ if (verbose) {
ex.getTargetException().printStackTrace();
}
} catch (Exception ex) {
@@ -435,7 +468,7 @@ public Value travel(Value op) {
throw new RuntimeException();
}
- Object args[] = new Object[ie.getArgs().length];
+ Object[] args = new Object[ie.getArgs().length];
for (int i = 0; i < args.length; i++) {
args[i] = convertIr2Jobj(ie.getOps()[i], ie.getArgs()[i]);
}
@@ -472,9 +505,9 @@ public static String v(Object[] vs) {
} else {
sb.append(",");
}
- if(obj instanceof String) {
+ if (obj instanceof String) {
sb.append(Escape.v(obj));
- }else {
+ } else {
sb.append(obj);
}
}
@@ -488,234 +521,236 @@ private Object convertIr2Jobj(Value value, String type) {
}
}
switch (type) {
- case "Z": {
- Object obj = ((Constant) value).value;
- return obj instanceof Boolean ? obj : ((Number) obj).intValue() != 0;
- }
- case "B": {
- Object obj = ((Constant) value).value;
- return ((Number) obj).byteValue();
- }
- case "S": {
- Object obj = ((Constant) value).value;
- return ((Number) obj).shortValue();
- }
- case "C": {
- Object obj = ((Constant) value).value;
- return obj instanceof Character ? obj : (char) ((Number) obj).intValue();
- }
- case "I": {
- Object obj = ((Constant) value).value;
- return ((Number) obj).intValue();
- }
- case "J": {
- Object obj = ((Constant) value).value;
- return ((Number) obj).longValue();
- }
- case "F": {
- Object obj = ((Constant) value).value;
- return obj instanceof Float ? obj : Float.intBitsToFloat(((Number) obj).intValue());
- }
- case "D": {
+ case "Z": {
+ Object obj = ((Constant) value).value;
+ return obj instanceof Boolean ? obj : ((Number) obj).intValue() != 0;
+ }
+ case "B": {
+ Object obj = ((Constant) value).value;
+ return ((Number) obj).byteValue();
+ }
+ case "S": {
+ Object obj = ((Constant) value).value;
+ return ((Number) obj).shortValue();
+ }
+ case "C": {
+ Object obj = ((Constant) value).value;
+ return obj instanceof Character ? obj : (char) ((Number) obj).intValue();
+ }
+ case "I": {
+ Object obj = ((Constant) value).value;
+ return ((Number) obj).intValue();
+ }
+ case "J": {
+ Object obj = ((Constant) value).value;
+ return ((Number) obj).longValue();
+ }
+ case "F": {
+ Object obj = ((Constant) value).value;
+ return obj instanceof Float ? obj : Float.intBitsToFloat(((Number) obj).intValue());
+ }
+ case "D": {
+ Object obj = ((Constant) value).value;
+ return obj instanceof Double ? obj : Double.longBitsToDouble(((Number) obj).longValue());
+ }
+ case "Ljava/lang/String;":
+ return ((Constant) value).value;
+ case "[Z":
+ if (value instanceof Constant) {
Object obj = ((Constant) value).value;
- return obj instanceof Double ? obj : Double.longBitsToDouble(((Number) obj).longValue());
- }
- case "Ljava/lang/String;":
- return (String) ((Constant) value).value;
- case "[Z":
- if (value instanceof Constant) {
- Object obj = ((Constant) value).value;
- if (obj instanceof boolean[]) {
- return obj;
- } else {
+ if (obj instanceof boolean[]) {
+ return obj;
+ } else {
- boolean[] b = new boolean[Array.getLength(obj)];
- for (int i = 0; i < b.length; i++) {
- b[i] = ((Number) Array.get(obj, i)).intValue() != 0;
- }
- return b;
- }
- } else if (value instanceof FilledArrayExpr) {
- boolean b[] = new boolean[value.getOps().length];
+ boolean[] b = new boolean[Array.getLength(obj)];
for (int i = 0; i < b.length; i++) {
- Object obj = ((Constant) value.getOps()[i]).value;
- if (obj instanceof Boolean) {
- b[i] = ((Boolean) obj).booleanValue();
- } else {
- b[i] = ((Number) obj).intValue() != 0;
- }
+ b[i] = ((Number) Array.get(obj, i)).intValue() != 0;
}
return b;
}
- throw new RuntimeException();
- case "[B":
- if (value instanceof Constant) {
- Object obj = ((Constant) value).value;
- if (obj instanceof byte[]) {
- return obj;
+ } else if (value instanceof FilledArrayExpr) {
+ boolean[] b = new boolean[value.getOps().length];
+ for (int i = 0; i < b.length; i++) {
+ Object obj = ((Constant) value.getOps()[i]).value;
+ if (obj instanceof Boolean) {
+ b[i] = ((Boolean) obj).booleanValue();
} else {
- byte[] b = new byte[Array.getLength(obj)];
- for (int i = 0; i < b.length; i++) {
- b[i] = ((Number) Array.get(obj, i)).byteValue();
- }
- return b;
+ b[i] = ((Number) obj).intValue() != 0;
}
- } else if (value instanceof FilledArrayExpr) {
- byte b[] = new byte[value.getOps().length];
+ }
+ return b;
+ }
+ throw new RuntimeException();
+ case "[B":
+ if (value instanceof Constant) {
+ Object obj = ((Constant) value).value;
+ if (obj instanceof byte[]) {
+ return obj;
+ } else {
+ byte[] b = new byte[Array.getLength(obj)];
for (int i = 0; i < b.length; i++) {
- Object obj = ((Constant) value.getOps()[i]).value;
- b[i] = ((Number) obj).byteValue();
+ b[i] = ((Number) Array.get(obj, i)).byteValue();
}
return b;
}
- throw new RuntimeException();
- case "[S":
- if (value instanceof Constant) {
- Object obj = ((Constant) value).value;
- if (obj instanceof short[]) {
- return obj;
- } else {
- short[] b = new short[Array.getLength(obj)];
- for (int i = 0; i < b.length; i++) {
- b[i] = ((Number) Array.get(obj, i)).shortValue();
- }
- return b;
- }
- } else if (value instanceof FilledArrayExpr) {
- short b[] = new short[value.getOps().length];
+ } else if (value instanceof FilledArrayExpr) {
+ byte[] b = new byte[value.getOps().length];
+ for (int i = 0; i < b.length; i++) {
+ Object obj = ((Constant) value.getOps()[i]).value;
+ b[i] = ((Number) obj).byteValue();
+ }
+ return b;
+ }
+ throw new RuntimeException();
+ case "[S":
+ if (value instanceof Constant) {
+ Object obj = ((Constant) value).value;
+ if (obj instanceof short[]) {
+ return obj;
+ } else {
+ short[] b = new short[Array.getLength(obj)];
for (int i = 0; i < b.length; i++) {
- Object obj = ((Constant) value.getOps()[i]).value;
- b[i] = ((Number) obj).shortValue();
+ b[i] = ((Number) Array.get(obj, i)).shortValue();
}
return b;
}
- throw new RuntimeException();
- case "[C":
- if (value instanceof Constant) {
- Object obj = ((Constant) value).value;
- if (obj instanceof char[]) {
- return obj;
- } else {
- char[] b = new char[Array.getLength(obj)];
- for (int i = 0; i < b.length; i++) {
- b[i] = (char) ((Number) Array.get(obj, i)).intValue();
- }
- return b;
- }
- } else if (value instanceof FilledArrayExpr) {
- char b[] = new char[value.getOps().length];
+ } else if (value instanceof FilledArrayExpr) {
+ short[] b = new short[value.getOps().length];
+ for (int i = 0; i < b.length; i++) {
+ Object obj = ((Constant) value.getOps()[i]).value;
+ b[i] = ((Number) obj).shortValue();
+ }
+ return b;
+ }
+ throw new RuntimeException();
+ case "[C":
+ if (value instanceof Constant) {
+ Object obj = ((Constant) value).value;
+ if (obj instanceof char[]) {
+ return obj;
+ } else {
+ char[] b = new char[Array.getLength(obj)];
for (int i = 0; i < b.length; i++) {
- Object obj = ((Constant) value.getOps()[i]).value;
- b[i] = obj instanceof Character ? ((Character) obj).charValue() : (char) ((Number) obj).intValue();
+ b[i] = (char) ((Number) Array.get(obj, i)).intValue();
}
return b;
}
- throw new RuntimeException();
- case "[I":
- if (value instanceof Constant) {
- Object obj = ((Constant) value).value;
- if (obj instanceof int[]) {
- return obj;
- } else {
- int[] b = new int[Array.getLength(obj)];
- for (int i = 0; i < b.length; i++) {
- b[i] = ((Number) Array.get(obj, i)).intValue();
- }
- return b;
- }
- } else if (value instanceof FilledArrayExpr) {
- int b[] = new int[value.getOps().length];
+ } else if (value instanceof FilledArrayExpr) {
+ char[] b = new char[value.getOps().length];
+ for (int i = 0; i < b.length; i++) {
+ Object obj = ((Constant) value.getOps()[i]).value;
+ b[i] = obj instanceof Character ? ((Character) obj).charValue() : (char) ((Number) obj).intValue();
+ }
+ return b;
+ }
+ throw new RuntimeException();
+ case "[I":
+ if (value instanceof Constant) {
+ Object obj = ((Constant) value).value;
+ if (obj instanceof int[]) {
+ return obj;
+ } else {
+ int[] b = new int[Array.getLength(obj)];
for (int i = 0; i < b.length; i++) {
- Object obj = ((Constant) value.getOps()[i]).value;
- b[i] = ((Number) obj).intValue();
+ b[i] = ((Number) Array.get(obj, i)).intValue();
}
return b;
}
- throw new RuntimeException();
- case "[J":
- if (value instanceof Constant) {
- Object obj = ((Constant) value).value;
- if (obj instanceof long[]) {
- return obj;
- } else {
- long[] b = new long[Array.getLength(obj)];
- for (int i = 0; i < b.length; i++) {
- b[i] = ((Number) Array.get(obj, i)).longValue();
- }
- return b;
- }
- } else if (value instanceof FilledArrayExpr) {
- long b[] = new long[value.getOps().length];
+ } else if (value instanceof FilledArrayExpr) {
+ int[] b = new int[value.getOps().length];
+ for (int i = 0; i < b.length; i++) {
+ Object obj = ((Constant) value.getOps()[i]).value;
+ b[i] = ((Number) obj).intValue();
+ }
+ return b;
+ }
+ throw new RuntimeException();
+ case "[J":
+ if (value instanceof Constant) {
+ Object obj = ((Constant) value).value;
+ if (obj instanceof long[]) {
+ return obj;
+ } else {
+ long[] b = new long[Array.getLength(obj)];
for (int i = 0; i < b.length; i++) {
- Object obj = ((Constant) value.getOps()[i]).value;
- b[i] = ((Number) obj).longValue();
+ b[i] = ((Number) Array.get(obj, i)).longValue();
}
return b;
}
- throw new RuntimeException();
- case "[F":
- if (value instanceof Constant) {
- Object obj = ((Constant) value).value;
- if (obj instanceof float[]) {
- return obj;
- } else {
- float[] b = new float[Array.getLength(obj)];
- for (int i = 0; i < b.length; i++) {
- b[i] = (char) ((Number) Array.get(obj, i)).intValue();
- }
- return b;
- }
- } else if (value instanceof FilledArrayExpr) {
- float b[] = new float[value.getOps().length];
+ } else if (value instanceof FilledArrayExpr) {
+ long[] b = new long[value.getOps().length];
+ for (int i = 0; i < b.length; i++) {
+ Object obj = ((Constant) value.getOps()[i]).value;
+ b[i] = ((Number) obj).longValue();
+ }
+ return b;
+ }
+ throw new RuntimeException();
+ case "[F":
+ if (value instanceof Constant) {
+ Object obj = ((Constant) value).value;
+ if (obj instanceof float[]) {
+ return obj;
+ } else {
+ float[] b = new float[Array.getLength(obj)];
for (int i = 0; i < b.length; i++) {
- Object obj = ((Constant) value.getOps()[i]).value;
- b[i] = obj instanceof Float ? ((Float) obj).floatValue() : Float.intBitsToFloat(((Number) obj).intValue());
+ b[i] = (char) ((Number) Array.get(obj, i)).intValue();
}
return b;
}
- throw new RuntimeException();
- case "[D":
- if (value instanceof Constant) {
- Object obj = ((Constant) value).value;
- if (obj instanceof double[]) {
- return obj;
- } else {
- double[] b = new double[Array.getLength(obj)];
- for (int i = 0; i < b.length; i++) {
- b[i] = (char) ((Number) Array.get(obj, i)).intValue();
- }
- return b;
- }
- } else if (value instanceof FilledArrayExpr) {
- double b[] = new double[value.getOps().length];
+ } else if (value instanceof FilledArrayExpr) {
+ float[] b = new float[value.getOps().length];
+ for (int i = 0; i < b.length; i++) {
+ Object obj = ((Constant) value.getOps()[i]).value;
+ b[i] = obj instanceof Float ? ((Float) obj).floatValue() :
+ Float.intBitsToFloat(((Number) obj).intValue());
+ }
+ return b;
+ }
+ throw new RuntimeException();
+ case "[D":
+ if (value instanceof Constant) {
+ Object obj = ((Constant) value).value;
+ if (obj instanceof double[]) {
+ return obj;
+ } else {
+ double[] b = new double[Array.getLength(obj)];
for (int i = 0; i < b.length; i++) {
- Object obj = ((Constant) value.getOps()[i]).value;
- b[i] = obj instanceof Double ? ((Double) obj).doubleValue() : Double.longBitsToDouble(((Number) obj).longValue());
+ b[i] = (char) ((Number) Array.get(obj, i)).intValue();
}
return b;
}
- throw new RuntimeException();
- case "[Ljava/lang/String;":
- if (value instanceof Constant) {
- Object obj = ((Constant) value).value;
- if (obj instanceof String[]) {
- return obj;
- }
- } else if (value instanceof FilledArrayExpr) {
- String b[] = new String[value.getOps().length];
- for (int i = 0; i < b.length; i++) {
- Object obj = ((Constant) value.getOps()[i]).value;
- if (obj instanceof String) {
- b[i] = (String) obj;
- } else if (Constant.Null.equals(obj)) {
- b[i] = null;
- } else {
- throw new RuntimeException();
- }
+ } else if (value instanceof FilledArrayExpr) {
+ double[] b = new double[value.getOps().length];
+ for (int i = 0; i < b.length; i++) {
+ Object obj = ((Constant) value.getOps()[i]).value;
+ b[i] = obj instanceof Double ? ((Double) obj).doubleValue() :
+ Double.longBitsToDouble(((Number) obj).longValue());
+ }
+ return b;
+ }
+ throw new RuntimeException();
+ case "[Ljava/lang/String;":
+ if (value instanceof Constant) {
+ Object obj = ((Constant) value).value;
+ if (obj instanceof String[]) {
+ return obj;
+ }
+ } else if (value instanceof FilledArrayExpr) {
+ String[] b = new String[value.getOps().length];
+ for (int i = 0; i < b.length; i++) {
+ Object obj = ((Constant) value.getOps()[i]).value;
+ if (obj instanceof String) {
+ b[i] = (String) obj;
+ } else if (Constant.Null.equals(obj)) {
+ b[i] = null;
+ } else {
+ throw new RuntimeException();
}
- return b;
}
- throw new RuntimeException();
+ return b;
+ }
+ throw new RuntimeException();
}
throw new RuntimeException();
}
@@ -792,11 +827,6 @@ Object convert(Object object, Class> type) {
/**
* load java methods from jar and --classpath
- *
- * @param jar
- * @param methodConfigs
- * @return
- * @throws Exception
*/
private Map loadMethods(Path jar, List methodConfigs) throws Exception {
final Map map = new HashMap<>();
@@ -837,9 +867,6 @@ private Map loadMethods(Path jar, List
/**
* collect methods from --methods and --method-owner,--method-name
- *
- * @return
- * @throws IOException
*/
private List collectMethodConfigs() throws IOException {
List methodConfigs = new ArrayList<>();
@@ -863,42 +890,43 @@ private List collectMethodConfigs() throws IOException {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < type_list.length; i++) {
switch (type_list[i]) {
- case "boolean":
- sb.append("Z");
- break;
- case "byte":
- sb.append("B");
- break;
- case "short":
- sb.append("S");
- break;
- case "char":
- sb.append("C");
- break;
- case "int":
- sb.append("I");
- break;
- case "long":
- sb.append("J");
- break;
- case "float":
- sb.append("F");
- break;
- case "double":
- sb.append("D");
- break;
- case "string":
- sb.append("Ljava/lang/String;");
- break;
-
- default:
- throw new RuntimeException("not support type " + type_list[i] + " on -t/--arg-types");
+ case "boolean":
+ sb.append("Z");
+ break;
+ case "byte":
+ sb.append("B");
+ break;
+ case "short":
+ sb.append("S");
+ break;
+ case "char":
+ sb.append("C");
+ break;
+ case "int":
+ sb.append("I");
+ break;
+ case "long":
+ sb.append("J");
+ break;
+ case "float":
+ sb.append("F");
+ break;
+ case "double":
+ sb.append("D");
+ break;
+ case "string":
+ sb.append("Ljava/lang/String;");
+ break;
+
+ default:
+ throw new RuntimeException("not support type " + type_list[i] + " on -t/--arg-types");
}
}
methodConfigs.add(this.build("L" + methodOwner.replace('.', '/') + ";->" + methodName + "("
+ sb + ")Ljava/lang/String;"));
} else {
- methodConfigs.add(this.build("L" + methodOwner.replace('.', '/') + ";->" + methodName + "(Ljava/lang/String;)Ljava/lang/String;"));
+ methodConfigs.add(this.build("L" + methodOwner.replace('.', '/') + ";->" + methodName + "(Ljava/lang"
+ + "/String;)Ljava/lang/String;"));
}
}
return methodConfigs;
@@ -939,51 +967,51 @@ private Method findAnyMethodMatch(Class> clz, String name, Class>[] classes)
Object readCst(AbstractInsnNode q) {
switch (q.getOpcode()) {
- case Opcodes.LDC:
- // LDC: String, integer, long and double cases (Opcodes.LDC comprehends LDC_W and LDC2_W)
- // push 32bit or 64bit int/float
- // push string/type
- LdcInsnNode ldc = (LdcInsnNode) q;
- if (ldc.cst instanceof Type) {
- throw new RuntimeException("not support .class value yet!");
- }
- return ldc.cst;
-
- case Opcodes.BIPUSH:
- case Opcodes.SIPUSH:
- // INT_INSN ("instruction with a single int operand")
- // push 8bit or 16bit int
- IntInsnNode in = (IntInsnNode) q;
- return in.operand;
-
- case Opcodes.ICONST_M1:
- case Opcodes.ICONST_0:
- case Opcodes.ICONST_1:
- case Opcodes.ICONST_2:
- case Opcodes.ICONST_3:
- case Opcodes.ICONST_4:
- case Opcodes.ICONST_5:
- // ICONST_*: push a tiny int, -1 <= value <= 5
- return q.getOpcode() - Opcodes.ICONST_0;
- case Opcodes.LCONST_0:
- case Opcodes.LCONST_1:
- return (long) (q.getOpcode() - Opcodes.LCONST_0);
- case Opcodes.FCONST_0:
- case Opcodes.FCONST_1:
- case Opcodes.FCONST_2:
- return (float) (q.getOpcode() - Opcodes.FCONST_0);
- case Opcodes.DCONST_0:
- case Opcodes.DCONST_1:
- return (double) (q.getOpcode() - Opcodes.DCONST_0);
- case Opcodes.ACONST_NULL:
- return null;
+ case Opcodes.LDC:
+ // LDC: String, integer, long and double cases (Opcodes.LDC comprehends LDC_W and LDC2_W)
+ // push 32bit or 64bit int/float
+ // push string/type
+ LdcInsnNode ldc = (LdcInsnNode) q;
+ if (ldc.cst instanceof Type) {
+ throw new RuntimeException("not support .class value yet!");
+ }
+ return ldc.cst;
+
+ case Opcodes.BIPUSH:
+ case Opcodes.SIPUSH:
+ // INT_INSN ("instruction with a single int operand")
+ // push 8bit or 16bit int
+ IntInsnNode in = (IntInsnNode) q;
+ return in.operand;
+
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ // ICONST_*: push a tiny int, -1 <= value <= 5
+ return q.getOpcode() - Opcodes.ICONST_0;
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ return (long) (q.getOpcode() - Opcodes.LCONST_0);
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ return (float) (q.getOpcode() - Opcodes.FCONST_0);
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ return (double) (q.getOpcode() - Opcodes.DCONST_0);
+ case Opcodes.ACONST_NULL:
+ return null;
}
throw new RuntimeException();
}
Class>[] toJavaType(Type[] pt) throws ClassNotFoundException {
- Class> jt[] = new Class>[pt.length];
+ Class>[] jt = new Class>[pt.length];
for (int i = 0; i < pt.length; i++) {
jt[i] = toJavaType(pt[i]);
}
@@ -992,28 +1020,28 @@ Class>[] toJavaType(Type[] pt) throws ClassNotFoundException {
Class> toJavaType(Type t) throws ClassNotFoundException {
switch (t.getSort()) {
- case Type.BOOLEAN:
- return boolean.class;
- case Type.BYTE:
- return byte.class;
- case Type.SHORT:
- return short.class;
- case Type.CHAR:
- return char.class;
- case Type.INT:
- return int.class;
- case Type.FLOAT:
- return float.class;
- case Type.LONG:
- return long.class;
- case Type.DOUBLE:
- return double.class;
- case Type.OBJECT:
- return Class.forName(t.getClassName());
- case Type.ARRAY:
- return Class.forName(t.getDescriptor());
- case Type.VOID:
- return void.class;
+ case Type.BOOLEAN:
+ return boolean.class;
+ case Type.BYTE:
+ return byte.class;
+ case Type.SHORT:
+ return short.class;
+ case Type.CHAR:
+ return char.class;
+ case Type.INT:
+ return int.class;
+ case Type.FLOAT:
+ return float.class;
+ case Type.LONG:
+ return long.class;
+ case Type.DOUBLE:
+ return double.class;
+ case Type.OBJECT:
+ return Class.forName(t.getClassName());
+ case Type.ARRAY:
+ return Class.forName(t.getDescriptor());
+ case Type.VOID:
+ return void.class;
}
throw new RuntimeException();
}
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarCmd.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarCmd.java
index 928856382..0a68db570 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarCmd.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarCmd.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,7 +21,6 @@
import com.googlecode.d2j.reader.DexFileReader;
import com.googlecode.d2j.reader.MultiDexFileReader;
import com.googlecode.dex2jar.ir.ET;
-
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -33,22 +32,27 @@ public static void main(String... args) {
new Dex2jarCmd().doMain(args);
}
- @Opt(opt = "e", longOpt = "exception-file", description = "detail exception file, default is $current_dir/[file-name]-error.zip", argName = "file")
+ @Opt(opt = "e", longOpt = "exception-file", description = "detail exception file, default is "
+ + "$current_dir/[file-name]-error.zip", argName = "file")
private Path exceptionFile;
@Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite")
private boolean forceOverwrite = false;
- @Opt(opt = "n", longOpt = "not-handle-exception", hasArg = false, description = "not handle any exceptions thrown by dex2jar")
+ @Opt(opt = "n", longOpt = "not-handle-exception", hasArg = false, description = "not handle any exceptions thrown"
+ + " by dex2jar")
private boolean notHandleException = false;
- @Opt(opt = "o", longOpt = "output", description = "output .jar file, default is $current_dir/[file-name]-dex2jar.jar", argName = "out-jar-file")
+ @Opt(opt = "o", longOpt = "output", description = "output .jar file, default is $current_dir/[file-name]-dex2jar"
+ + ".jar", argName = "out-jar-file")
private Path output;
- @Opt(opt = "r", longOpt = "reuse-reg", hasArg = false, description = "reuse register while generate java .class file")
+ @Opt(opt = "r", longOpt = "reuse-reg", hasArg = false, description = "reuse register while generate java .class "
+ + "file")
private boolean reuseReg = false;
@Opt(opt = "s", hasArg = false, description = "same with --topological-sort/-ts")
private boolean topologicalSort1 = false;
- @Opt(opt = "ts", longOpt = "topological-sort", hasArg = false, description = "sort block by topological, that will generate more readable code, default enabled")
+ @Opt(opt = "ts", longOpt = "topological-sort", hasArg = false, description = "sort block by topological, that "
+ + "will generate more readable code, default enabled")
private boolean topologicalSort = false;
@Opt(opt = "d", longOpt = "debug-info", hasArg = false, description = "translate debug info")
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarMultiThreadCmd.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarMultiThreadCmd.java
index be6501f51..7f7455775 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarMultiThreadCmd.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Dex2jarMultiThreadCmd.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,27 +16,32 @@
*/
package com.googlecode.dex2jar.tools;
+import com.googlecode.d2j.dex.ClassVisitorFactory;
+import com.googlecode.d2j.dex.ExDex2Asm;
+import com.googlecode.d2j.dex.LambadaNameSafeClassAdapter;
+import com.googlecode.d2j.node.DexClassNode;
+import com.googlecode.d2j.node.DexFileNode;
+import com.googlecode.d2j.reader.BaseDexFileReader;
+import com.googlecode.d2j.reader.DexFileReader;
+import com.googlecode.d2j.reader.MultiDexFileReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.*;
-import java.util.concurrent.*;
-
-import com.googlecode.d2j.dex.LambadaNameSafeClassAdapter;
-import com.googlecode.d2j.reader.BaseDexFileReader;
-import com.googlecode.d2j.reader.MultiDexFileReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.Opcodes;
-
-import com.googlecode.d2j.dex.ClassVisitorFactory;
-import com.googlecode.d2j.dex.ExDex2Asm;
-import com.googlecode.d2j.node.DexClassNode;
-import com.googlecode.d2j.node.DexFileNode;
-import com.googlecode.d2j.reader.DexFileReader;
@BaseCmd.Syntax(cmd = "d2j-mt-dex2jar", syntax = "[options] [file1 ... fileN]", desc = "convert dex to jar")
public class Dex2jarMultiThreadCmd extends BaseCmd {
@@ -140,33 +145,26 @@ public void convertDex(final DexFileNode fileNode, final ClassVisitorFactory cvf
final Map classes = collectClzInfo(fileNode);
final List> results = new ArrayList<>(fileNode.clzs.size());
for (final DexClassNode classNode : fileNode.clzs) {
- results.add(executorService.submit(new Runnable() {
- @Override
- public void run() {
- convertClass(fileNode, classNode, cvf, classes);
- }
- }));
+ results.add(executorService.submit(() -> convertClass(fileNode, classNode, cvf, classes)));
}
- executorService.submit(new Runnable() {
- @Override
- public void run() {
- for (Future> result : results) {
- try {
- result.get();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- }
- BaksmaliBaseDexExceptionHandler exceptionHandler1 = (BaksmaliBaseDexExceptionHandler) exceptionHandler;
- if (exceptionHandler1.hasException()) {
- exceptionHandler1.dump(errorFile, new String[0]);
- }
+ executorService.submit(() -> {
+ for (Future> result : results) {
try {
- fs.close();
- } catch (IOException e) {
+ result.get();
+ } catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
+ BaksmaliBaseDexExceptionHandler exceptionHandler1 =
+ (BaksmaliBaseDexExceptionHandler) exceptionHandler;
+ if (exceptionHandler1.hasException()) {
+ exceptionHandler1.dump(errorFile, new String[0]);
+ }
+ try {
+ fs.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
});
}
}
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexRecomputeChecksum.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexRecomputeChecksum.java
index aa8b7005e..aa7505ca6 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexRecomputeChecksum.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexRecomputeChecksum.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2014 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,7 +17,6 @@
package com.googlecode.dex2jar.tools;
import com.googlecode.d2j.dex.writer.DexFileWriter;
-
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -32,7 +31,8 @@ public static void main(String... args) {
@Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite")
private boolean forceOverwrite = false;
- @Opt(opt = "o", longOpt = "output", description = "output .dex file, default is [dex-name]-rechecksum.dex", argName = "out-dex-file")
+ @Opt(opt = "o", longOpt = "output", description = "output .dex file, default is [dex-name]-rechecksum.dex",
+ argName = "out-dex-file")
private Path output;
@Override
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexWeaverCmd.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexWeaverCmd.java
index 619a01eec..9b4e359e2 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexWeaverCmd.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/DexWeaverCmd.java
@@ -1,12 +1,5 @@
package com.googlecode.dex2jar.tools;
-import java.io.File;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.HashMap;
-import java.util.Map;
-
import com.googlecode.d2j.Method;
import com.googlecode.d2j.dex.writer.DexFileWriter;
import com.googlecode.d2j.reader.DexFileReader;
@@ -17,8 +10,15 @@
import com.googlecode.d2j.visitors.DexCodeVisitor;
import com.googlecode.d2j.visitors.DexFileVisitor;
import com.googlecode.d2j.visitors.DexMethodVisitor;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.Map;
-@BaseCmd.Syntax(cmd = "d2j-dex-weaver", syntax = "[options] dex", desc = "replace invoke in dex", onlineHelp = "https://sourceforge.net/p/dex2jar/wiki/DexWeaver")
+@BaseCmd.Syntax(cmd = "d2j-dex-weaver", syntax = "[options] dex", desc = "replace invoke in dex", onlineHelp = "https"
+ + "://sourceforge.net/p/dex2jar/wiki/DexWeaver")
public class DexWeaverCmd extends BaseCmd {
@Opt(opt = "o", longOpt = "output", description = "output .dex file", argName = "out-dex-file")
private Path output;
@@ -56,7 +56,8 @@ protected void doCommandLine() throws Exception {
DexFileWriter out = new DexFileWriter();
DexFileVisitor fv = new DexFileVisitor(out) {
@Override
- public DexClassVisitor visit(int access_flags, String className, String superClass, String[] interfaceNames) {
+ public DexClassVisitor visit(int access_flags, String className, String superClass,
+ String[] interfaceNames) {
DexClassVisitor dcv = super.visit(access_flags, className, superClass, interfaceNames);
if (dcv != null) {
return new DexClassVisitor(dcv) {
@@ -87,7 +88,8 @@ public void visitMethodStmt(Op op, int[] args, Method method) {
case INVOKE_STATIC_RANGE:
case INVOKE_SUPER_RANGE:
case INVOKE_VIRTUAL_RANGE:
- super.visitMethodStmt(Op.INVOKE_STATIC_RANGE, args, replaceTo);
+ super.visitMethodStmt(Op.INVOKE_STATIC_RANGE, args,
+ replaceTo);
break;
default:
// impossible here
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ExtractOdexFromCoredumpCmd.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ExtractOdexFromCoredumpCmd.java
index 306bf3336..652e3279c 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ExtractOdexFromCoredumpCmd.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/ExtractOdexFromCoredumpCmd.java
@@ -13,7 +13,8 @@
import java.util.ArrayList;
import java.util.List;
-@BaseCmd.Syntax(cmd = "extract-odex-from-coredump", syntax = "", desc = "Extract odex from dalvik memery core dump")
+@BaseCmd.Syntax(cmd = "extract-odex-from-coredump", syntax = "", desc = "Extract odex from dalvik memory "
+ + "core dump")
public class ExtractOdexFromCoredumpCmd extends BaseCmd {
public static void main(String... args) {
new ExtractOdexFromCoredumpCmd().doMain(args);
@@ -38,7 +39,7 @@ private static void extractDex(SeekableByteChannel channel, List possibleO
final int buffSize = 0x28 + 0x70;
ByteBuffer head = ByteBuffer.allocate(buffSize).order(ByteOrder.LITTLE_ENDIAN); // odex+dex head
for (long pos : possibleOdexs) {
- System.err.println(String.format(">> Check for %08x", pos));
+ System.err.printf(">> Check for %08x%n", pos);
channel.position(pos);
head.position(0);
int c = channel.read(head);
@@ -55,25 +56,29 @@ private static void extractDex(SeekableByteChannel channel, List possibleO
int flags = head.getInt(32);
int checksum = head.getInt(36);
if (dexOffset != 0x28) {
- System.err.println(String.format(">>> dex offset is not 0x28"));
+ System.err.println(">>> dex offset is not 0x28");
} else {
- int dexMagic = head.getInt(dexOffset + 0);
+ int dexMagic = head.getInt(dexOffset);
int dexVersion = head.getInt(dexOffset + 4);
if (dexMagic != 0x0a786564 || !(dexVersion == 0x00363330 || dexVersion == 0x00353330)) {
- System.err.println(String.format(">>> dex magic is not dex.036 or dex.035: 0x%08x 0x%08x", dexMagic, dexVersion));
+ System.err.printf(">>> dex magic is not dex.036 or dex.035: 0x%08x 0x%08x%n"
+ , dexMagic, dexVersion);
} else {
int fileSize = head.getInt(dexOffset + 32);
if (fileSize != dexLength) {
- System.err.println(String.format(">>> dex file size is same with dexLength in odex %d vs %d", fileSize, dexLength));
+ System.err.printf(">>> dex file size is same with dexLength in odex %d"
+ + " vs %d%n", fileSize, dexLength);
} else {
int endian = head.getInt(dexOffset + 40);
if (endian != 0x12345678) {
- System.err.println(String.format(">>> dex endian is not 0x12345678"));
+ System.err.println(">>> dex endian is not 0x12345678");
} else {
// find new dex
- Path nFile = new File(String.format("%s-%02d.odex", namePrefix, dexIndex++)).toPath();
- System.out.println(String.format(">>>> extract 0x%08x to %s", pos, nFile));
- try (SeekableByteChannel channel2 = Files.newByteChannel(nFile, StandardOpenOption.CREATE, StandardOpenOption.WRITE);) {
+ Path nFile =
+ new File(String.format("%s-%02d.odex", namePrefix, dexIndex++)).toPath();
+ System.out.printf(">>>> extract 0x%08x to %s%n", pos, nFile);
+ try (SeekableByteChannel channel2 = Files.newByteChannel(nFile,
+ StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
odexHead.rewind();
odexHead.putInt(0x0a796564);// dey
@@ -129,7 +134,8 @@ private static void extractDex(SeekableByteChannel channel, List possibleO
}
}
- private static void copy(SeekableByteChannel channel, SeekableByteChannel channel2, ByteBuffer copyBuff, int fileSize) throws IOException {
+ private static void copy(SeekableByteChannel channel, SeekableByteChannel channel2, ByteBuffer copyBuff,
+ int fileSize) throws IOException {
int remain = fileSize;
while (remain > 0) {
@@ -162,11 +168,11 @@ private static List findPossibleOdexLocation(SeekableByteChannel channel)
int v4 = intBuffer.get(i + 1);
if (v4 == 0x00363330 || v4 == 0x00353330) {
possibleOdexs.add(position + 4 * i);
- System.err.println(String.format("> Possible %08x | %08x %08x", position + i * 4, u4, v4));
+ System.err.printf("> Possible %08x | %08x %08x%n", position + i * 4, 0x0a796564, v4);
}
} else {
possibleOdexs.add(position + 4 * i);
- System.err.println(String.format("> Possible %08x | %08x", position + i * 4, u4));
+ System.err.printf("> Possible %08x | %08x%n", position + i * 4, 0x0a796564);
}
}
}
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/GenerateCompileStubFromOdex.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/GenerateCompileStubFromOdex.java
index e9867c138..726fad35d 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/GenerateCompileStubFromOdex.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/GenerateCompileStubFromOdex.java
@@ -4,8 +4,6 @@
import com.googlecode.d2j.dex.Dex2Asm;
import com.googlecode.d2j.node.DexFileNode;
import com.googlecode.d2j.reader.DexFileReader;
-import org.objectweb.asm.*;
-
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -13,8 +11,14 @@
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
-@BaseCmd.Syntax(cmd = "d2j-generate-stub-from-odex", syntax = "[options] [odex1 ... odexN]", desc = "Genenerate no-code jar from odex")
+@BaseCmd.Syntax(cmd = "d2j-generate-stub-from-odex", syntax = "[options] [odex1 ... odexN]", desc =
+ "Genenerate no-code jar from odex")
public class GenerateCompileStubFromOdex extends BaseCmd {
private static final int MAGIC_ODEX = 0x0A796564 & 0x00FFFFFF;// hex for 'dey ', ignore the 0A
private static final int MAGIC_DEX = 0x0A786564 & 0x00FFFFFF;// hex for 'dex ', ignore the 0A
@@ -88,7 +92,8 @@ public void visitEnd() {
}
@Override
- public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
+ public FieldVisitor visitField(int access, String name, String desc, String signature,
+ Object value) {
if (noPrivate && 0 != (access & Opcodes.ACC_PRIVATE)) {
return null;
}
@@ -97,7 +102,7 @@ public FieldVisitor visitField(int access, String name, String desc, String sign
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature,
- String[] exceptions) {
+ String[] exceptions) {
if (noPrivate && 0 != (access & Opcodes.ACC_PRIVATE)) {
return null;
}
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Jar2Dex.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Jar2Dex.java
index 00270601a..a40e4159d 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Jar2Dex.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/Jar2Dex.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,7 +17,6 @@
package com.googlecode.dex2jar.tools;
import java.io.File;
-import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.file.FileSystem;
import java.nio.file.Files;
@@ -34,7 +33,8 @@ public static void main(String... args) {
@Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite")
private boolean forceOverwrite = false;
- @Opt(opt = "o", longOpt = "output", description = "output .dex file, default is $current_dir/[jar-name]-jar2dex.dex", argName = "out-dex-file")
+ @Opt(opt = "o", longOpt = "output", description = "output .dex file, default is $current_dir/[jar-name]-jar2dex"
+ + ".dex", argName = "out-dex-file")
private Path output;
@Override
@@ -74,12 +74,9 @@ protected void doCommandLine() throws Exception {
System.out.println("zipping " + jar + " -> " + realJar);
try (FileSystem fs = createZip(realJar)) {
final Path outRoot = fs.getPath("/");
- walkJarOrDir(jar, new FileVisitorX() {
- @Override
- public void visitFile(Path file, String relative) throws IOException {
- if (file.getFileName().toString().endsWith(".class")) {
- Files.copy(file, outRoot.resolve(relative));
- }
+ walkJarOrDir(jar, (file, relative) -> {
+ if (file.getFileName().toString().endsWith(".class")) {
+ Files.copy(file, outRoot.resolve(relative));
}
});
}
@@ -94,9 +91,9 @@ public void visitFile(Path file, String relative) throws IOException {
List ps = new ArrayList<>(Arrays.asList("--dex", "--no-strict",
"--output=" + output.toAbsolutePath(), realJar
- .toAbsolutePath().toString()));
+ .toAbsolutePath().toString()));
System.out.println("call com.android.dx.command.Main.main" + ps);
- m.invoke(null, new Object[] { ps.toArray(new String[0]) });
+ m.invoke(null, new Object[]{ps.toArray(new String[0])});
} finally {
if (tmp != null) {
Files.deleteIfExists(tmp);
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarAccessCmd.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarAccessCmd.java
index a5c0dbb4f..306f511cd 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarAccessCmd.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarAccessCmd.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,10 +21,15 @@
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
-
-import org.objectweb.asm.*;
-
-@BaseCmd.Syntax(cmd = "d2j-jar-access", syntax = "[options] ", desc = "add or remove class/method/field access in jar file")
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+@BaseCmd.Syntax(cmd = "d2j-jar-access", syntax = "[options] ", desc = "add or remove class/method/field access "
+ + "in jar file")
public class JarAccessCmd extends BaseCmd implements Opcodes {
public static void main(String... args) {
new JarAccessCmd().doMain(args);
@@ -32,7 +37,8 @@ public static void main(String... args) {
@Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite")
private boolean forceOverwrite = false;
- @Opt(opt = "o", longOpt = "output", description = "output dir of .j files, default is $current_dir/[jar-name]-access.jar", argName = "out-dir")
+ @Opt(opt = "o", longOpt = "output", description = "output dir of .j files, default is "
+ + "$current_dir/[jar-name]-access.jar", argName = "out-dir")
private Path output;
@Opt(opt = "rd", longOpt = "remove-debug", hasArg = false, description = "remove debug info")
@@ -169,7 +175,7 @@ public void visitFile(Path file, String relative) throws IOException {
@Override
public void visit(int version, int access, String name, String signature, String superName,
- String[] interfaces) {
+ String[] interfaces) {
int na = (access & rc) | ac;
if (access != na) {
System.out.println("c " + name);
@@ -179,7 +185,7 @@ public void visit(int version, int access, String name, String signature, String
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature,
- Object value) {
+ Object value) {
int na = (access & rf) | af;
if (na != access) {
System.out.println("f " + r.getClassName() + "." + name);
@@ -189,7 +195,7 @@ public FieldVisitor visitField(int access, String name, String desc, String sign
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature,
- String[] exceptions) {
+ String[] exceptions) {
int na = (access & rm) | am;
if (na != access) {
System.out.println("m " + r.getClassName() + "." + name + desc);
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarWeaverCmd.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarWeaverCmd.java
index 1e2278b75..7600c75bb 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarWeaverCmd.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/JarWeaverCmd.java
@@ -1,14 +1,13 @@
package com.googlecode.dex2jar.tools;
import com.googlecode.d2j.tools.jar.InvocationWeaver;
-
import java.io.File;
-import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
-@BaseCmd.Syntax(cmd = "d2j-jar-weaver", syntax = "[options] jar", desc = "replace invoke in jar", onlineHelp = "https://sourceforge.net/p/dex2jar/wiki/JarWeaver")
+@BaseCmd.Syntax(cmd = "d2j-jar-weaver", syntax = "[options] jar", desc = "replace invoke in jar", onlineHelp = "https"
+ + "://sourceforge.net/p/dex2jar/wiki/JarWeaver")
public class JarWeaverCmd extends BaseCmd {
@Opt(opt = "o", longOpt = "output", description = "output .jar file", argName = "out-jar-file", required = true)
private Path output;
@@ -40,16 +39,13 @@ protected void doCommandLine() throws Exception {
}
if (stub != null) {
System.err.println(stub + " -> " + output);
- walkJarOrDir(stub, new FileVisitorX() {
- @Override
- public void visitFile(Path file, String relative) throws IOException {
- Path out = outRoot.resolve(relative);
- if (Files.exists(out)) {
- System.err.println("skip " + relative + " in " + stub);
- } else {
- createParentDirectories(out);
- Files.copy(file, out);
- }
+ walkJarOrDir(stub, (file, relative) -> {
+ Path out = outRoot.resolve(relative);
+ if (Files.exists(out)) {
+ System.err.println("skip " + relative + " in " + stub);
+ } else {
+ createParentDirectories(out);
+ Files.copy(file, out);
}
});
}
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/StdApkCmd.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/StdApkCmd.java
index e3c15cc28..8df3e10cd 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/StdApkCmd.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/StdApkCmd.java
@@ -16,6 +16,8 @@
*/
package com.googlecode.dex2jar.tools;
+import com.googlecode.d2j.util.zip.AutoSTOREDZipOutputStream;
+import com.googlecode.dex2jar.tools.BaseCmd.Syntax;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
@@ -23,9 +25,6 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
-import com.googlecode.d2j.util.zip.AutoSTOREDZipOutputStream;
-import com.googlecode.dex2jar.tools.BaseCmd.Syntax;
-
@Syntax(cmd = "d2j-std-zip", syntax = "[options] ", desc = "clean up apk to standard zip")
public class StdApkCmd extends BaseCmd {
@@ -48,7 +47,7 @@ protected void doCommandLine() throws Exception {
byte[] buffer = new byte[1000];
try (ZipOutputStream zos = new AutoSTOREDZipOutputStream(Files.newOutputStream(output))) {
byte[] data = Files.readAllBytes(new File(remainingArgs[0]).toPath());
- try(com.googlecode.d2j.util.zip.ZipFile zipFile = new com.googlecode.d2j.util.zip.ZipFile(data)) {
+ try (com.googlecode.d2j.util.zip.ZipFile zipFile = new com.googlecode.d2j.util.zip.ZipFile(data)) {
for (com.googlecode.d2j.util.zip.ZipEntry e : zipFile.entries()) {
ZipEntry nEntry = new ZipEntry(e.getName());
diff --git a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/to/Do.java b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/to/Do.java
index 750bdeaa2..53556dca7 100644
--- a/dex-tools/src/main/java/com/googlecode/dex2jar/tools/to/Do.java
+++ b/dex-tools/src/main/java/com/googlecode/dex2jar/tools/to/Do.java
@@ -3,7 +3,7 @@
public class Do {
/**
- * @param args
+ *
*/
public static void main(String[] args) {
System.out.println("This is not support!");
diff --git a/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/MethodInvocation.java b/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/MethodInvocation.java
index c02857cbf..ae8e29092 100644
--- a/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/MethodInvocation.java
+++ b/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/MethodInvocation.java
@@ -11,6 +11,7 @@ public interface MethodInvocation {
String getMethodDesc();
Object getThis();
+
// @Nullale
Object[] getArguments();
}
diff --git a/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/DexWaveTest.java b/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/DexWaveTest.java
index 1914d99fc..137d73184 100644
--- a/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/DexWaveTest.java
+++ b/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/DexWaveTest.java
@@ -6,13 +6,12 @@
import com.googlecode.d2j.smali.BaksmaliDumper;
import com.googlecode.d2j.smali.Smali;
import com.googlecode.d2j.tools.jar.DexWeaver;
-import org.antlr.runtime.RecognitionException;
-import org.junit.Assert;
-import org.junit.Test;
-
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.StringWriter;
+import org.antlr.runtime.RecognitionException;
+import org.junit.Assert;
+import org.junit.Test;
public class DexWaveTest {
@Test
diff --git a/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/WaveTest.java b/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/WaveTest.java
index c5b6f3d7a..4cb13adf9 100644
--- a/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/WaveTest.java
+++ b/dex-tools/src/test/java/com/googlecode/d2j/tools/jar/test/WaveTest.java
@@ -5,6 +5,9 @@
import com.googlecode.d2j.jasmin.Jasmins;
import com.googlecode.d2j.tools.jar.InvocationWeaver;
import com.googlecode.dex2jar.tools.Constants;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import org.antlr.runtime.RecognitionException;
import org.junit.Assert;
import org.junit.Test;
@@ -13,10 +16,6 @@
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
public class WaveTest {
@Test
public void testA() throws IOException, RecognitionException {
@@ -33,10 +32,15 @@ public void testB() throws IOException, RecognitionException {
InvocationWeaver iw = new InvocationWeaver();
iw.setInvocationInterfaceDesc("Lp;");
- iw.withConfig("r Ljava/util/ArrayList;.size=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.size(Lp;)Ljava/lang/Object;");
- iw.withConfig("r Ljava/util/ArrayList;.add=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.add(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
- iw.withConfig("r Ljava/io/PrintStream;.append(Ljava/lang/CharSequence;)Ljava/io/PrintStream;=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.append(Lp;)Ljava/lang/Object;");
- iw.withConfig("r Ljava/io/PrintStream;.println(Ljava/lang/String;)V=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.println(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;");
+ iw.withConfig("r Ljava/util/ArrayList;.size=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.size(Lp;)"
+ + "Ljava/lang/Object;");
+ iw.withConfig("r Ljava/util/ArrayList;.add=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.add"
+ + "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+ iw.withConfig("r Ljava/io/PrintStream;.append(Ljava/lang/CharSequence;)Ljava/io/PrintStream;"
+ + "=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.append(Lp;)Ljava/lang/Object;");
+ iw.withConfig("r Ljava/io/PrintStream;.println(Ljava/lang/String;)"
+ + "V=Lcom/googlecode/d2j/tools/jar/test/WaveTest;.println(Ljava/lang/Object;Ljava/lang/String;)"
+ + "Ljava/lang/Object;");
test0(iw, "b");
}
diff --git a/dex-translator/src/main/java/com/googlecode/d2j/asm/LdcOptimizeAdapter.java b/dex-translator/src/main/java/com/googlecode/d2j/asm/LdcOptimizeAdapter.java
index ebc7ff4fd..f181f81bf 100644
--- a/dex-translator/src/main/java/com/googlecode/d2j/asm/LdcOptimizeAdapter.java
+++ b/dex-translator/src/main/java/com/googlecode/d2j/asm/LdcOptimizeAdapter.java
@@ -1,12 +1,12 @@
/*
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,7 +28,7 @@
public class LdcOptimizeAdapter extends MethodVisitor implements Opcodes {
/**
- * @param mv
+ *
*/
public LdcOptimizeAdapter(MethodVisitor mv) {
super(Constants.ASM_VERSION, mv);
@@ -36,7 +36,7 @@ public LdcOptimizeAdapter(MethodVisitor mv) {
/*
* (non-Javadoc)
- *
+ *
* @see org.objectweb.asm.MethodAdapter#visitLdcInsn(java.lang.Object)
*/
@Override
@@ -81,35 +81,35 @@ public void visitLdcInsn(Object cst) {
} else {
super.visitLdcInsn(cst);
}
- } else if(cst instanceof Type){
- Type t= (Type) cst;
+ } else if (cst instanceof Type) {
+ Type t = (Type) cst;
switch (t.getSort()) {
- case Type.BOOLEAN:
- super.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
- break;
- case Type.BYTE:
- super.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;");
- break;
- case Type.CHAR:
- super.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;");
- break;
- case Type.DOUBLE:
- super.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;");
- break;
- case Type.FLOAT:
- super.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;");
- break;
- case Type.INT:
- super.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
- break;
- case Type.LONG:
- super.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;");
- break;
- case Type.SHORT:
- super.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;");
- break;
- default:
- super.visitLdcInsn(cst);
+ case Type.BOOLEAN:
+ super.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
+ break;
+ case Type.BYTE:
+ super.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;");
+ break;
+ case Type.CHAR:
+ super.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;");
+ break;
+ case Type.DOUBLE:
+ super.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;");
+ break;
+ case Type.FLOAT:
+ super.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;");
+ break;
+ case Type.INT:
+ super.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
+ break;
+ case Type.LONG:
+ super.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;");
+ break;
+ case Type.SHORT:
+ super.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;");
+ break;
+ default:
+ super.visitLdcInsn(cst);
}
} else {
super.visitLdcInsn(cst);
@@ -123,7 +123,8 @@ public static MethodVisitor wrap(MethodVisitor mv) {
public static ClassVisitor wrap(ClassVisitor cv) {
return cv == null ? null : new ClassVisitor(Constants.ASM_VERSION, cv) {
@Override
- public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature,
+ String[] exceptions) {
return wrap(super.visitMethod(access, name, desc, signature, exceptions));
}
};
diff --git a/dex-translator/src/main/java/com/googlecode/d2j/converter/Dex2IRConverter.java b/dex-translator/src/main/java/com/googlecode/d2j/converter/Dex2IRConverter.java
index 853ec946b..154ffb30d 100644
--- a/dex-translator/src/main/java/com/googlecode/d2j/converter/Dex2IRConverter.java
+++ b/dex-translator/src/main/java/com/googlecode/d2j/converter/Dex2IRConverter.java
@@ -8,7 +8,21 @@
import com.googlecode.d2j.node.TryCatchNode;
import com.googlecode.d2j.node.analysis.DvmFrame;
import com.googlecode.d2j.node.analysis.DvmInterpreter;
-import com.googlecode.d2j.node.insn.*;
+import com.googlecode.d2j.node.insn.BaseSwitchStmtNode;
+import com.googlecode.d2j.node.insn.ConstStmtNode;
+import com.googlecode.d2j.node.insn.DexLabelStmtNode;
+import com.googlecode.d2j.node.insn.DexStmtNode;
+import com.googlecode.d2j.node.insn.FieldStmtNode;
+import com.googlecode.d2j.node.insn.FillArrayDataStmtNode;
+import com.googlecode.d2j.node.insn.FilledNewArrayStmtNode;
+import com.googlecode.d2j.node.insn.JumpStmtNode;
+import com.googlecode.d2j.node.insn.MethodCustomStmtNode;
+import com.googlecode.d2j.node.insn.MethodPolymorphicStmtNode;
+import com.googlecode.d2j.node.insn.MethodStmtNode;
+import com.googlecode.d2j.node.insn.PackedSwitchStmtNode;
+import com.googlecode.d2j.node.insn.SparseSwitchStmtNode;
+import com.googlecode.d2j.node.insn.Stmt2R1NNode;
+import com.googlecode.d2j.node.insn.TypeStmtNode;
import com.googlecode.d2j.reader.Op;
import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.Trap;
@@ -16,12 +30,75 @@
import com.googlecode.dex2jar.ir.expr.Exprs;
import com.googlecode.dex2jar.ir.expr.Local;
import com.googlecode.dex2jar.ir.expr.Value;
-import com.googlecode.dex2jar.ir.stmt.*;
-
-import java.util.*;
-
-import static com.googlecode.dex2jar.ir.expr.Exprs.*;
-import static com.googlecode.dex2jar.ir.stmt.Stmts.*;
+import com.googlecode.dex2jar.ir.stmt.AssignStmt;
+import com.googlecode.dex2jar.ir.stmt.LabelStmt;
+import com.googlecode.dex2jar.ir.stmt.Stmt;
+import com.googlecode.dex2jar.ir.stmt.StmtList;
+import com.googlecode.dex2jar.ir.stmt.Stmts;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.Stack;
+import java.util.TreeSet;
+
+import static com.googlecode.dex2jar.ir.expr.Exprs.nAdd;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nAnd;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nArray;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nArrayValue;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nCast;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nCheckCast;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nDCmpg;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nDCmpl;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nDiv;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nFCmpg;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nFCmpl;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nField;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nInstanceOf;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nInt;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeCustom;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeInterface;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeNew;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nInvokePolymorphic;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeSpecial;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeStatic;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nInvokeVirtual;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nLCmp;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nLength;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nLong;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nMul;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nNeg;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nNew;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nNewArray;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nNot;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nOr;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nRem;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nShl;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nShr;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nStaticField;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nString;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nSub;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nType;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nUshr;
+import static com.googlecode.dex2jar.ir.expr.Exprs.nXor;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nAssign;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nFillArrayData;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nGoto;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nIf;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nLock;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nLookupSwitch;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nNop;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nReturn;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nReturnVoid;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nTableSwitch;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nThrow;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nUnLock;
+import static com.googlecode.dex2jar.ir.stmt.Stmts.nVoidInvoke;
public class Dex2IRConverter {
Map labelMap = new HashMap<>();
@@ -312,7 +389,7 @@ private void addPhi(DvmValue v, Set phiVal
}
if (phiValues.size() > 0) {
phis.add(Stmts.nAssign(v.local, Exprs
- .nPhi(phiValues.toArray(new com.googlecode.dex2jar.ir.expr.Value[phiValues.size()]))));
+ .nPhi(phiValues.toArray(new Value[0]))));
phiValues.clear();
}
}
@@ -398,25 +475,25 @@ private void dfs(BitSet[] exBranch, BitSet handlers, BitSet access, DvmInterpret
try {
if (p.op != null) {
switch (p.op) {
- case RETURN_VOID:
- emit(nReturnVoid());
- break;
- case GOTO:
- case GOTO_16:
- case GOTO_32:
- emit(nGoto(getLabel(((JumpStmtNode) p).label)));
- break;
- case NOP:
- emit(nNop());
- break;
- case BAD_OP:
- emit(nThrow(nInvokeNew(new Value[]{nString("bad dex opcode")}, new String[]{
- "Ljava/lang/String;"},
- "Ljava/lang/VerifyError;")));
- break;
- default:
- tmp.execute(p, interpreter);
- break;
+ case RETURN_VOID:
+ emit(nReturnVoid());
+ break;
+ case GOTO:
+ case GOTO_16:
+ case GOTO_32:
+ emit(nGoto(getLabel(((JumpStmtNode) p).label)));
+ break;
+ case NOP:
+ emit(nNop());
+ break;
+ case BAD_OP:
+ emit(nThrow(nInvokeNew(new Value[]{nString("bad dex opcode")}, new String[]{
+ "Ljava/lang/String;"},
+ "Ljava/lang/VerifyError;")));
+ break;
+ default:
+ tmp.execute(p, interpreter);
+ break;
}
}
} catch (Exception exception) {
@@ -543,33 +620,33 @@ DvmValue b(com.googlecode.dex2jar.ir.expr.Value value) {
@Override
public DvmValue newOperation(DexStmtNode insn) {
switch (insn.op) {
- case CONST:
- case CONST_16:
- case CONST_4:
- case CONST_HIGH16:
- return b(nInt((Integer) ((ConstStmtNode) insn).value));
- case CONST_WIDE:
- case CONST_WIDE_16:
- case CONST_WIDE_32:
- case CONST_WIDE_HIGH16:
- return b(nLong((Long) ((ConstStmtNode) insn).value));
- case CONST_CLASS:
- return b(nType((DexType) ((ConstStmtNode) insn).value));
- case CONST_STRING:
- case CONST_STRING_JUMBO:
- return b(nString((String) ((ConstStmtNode) insn).value));
- case SGET:
- case SGET_BOOLEAN:
- case SGET_BYTE:
- case SGET_CHAR:
- case SGET_OBJECT:
- case SGET_SHORT:
- case SGET_WIDE:
- Field field = ((FieldStmtNode) insn).field;
- return b(nStaticField(field.getOwner(), field.getName(), field.getType()));
- case NEW_INSTANCE:
- return b(nNew(((TypeStmtNode) insn).type));
- default:
+ case CONST:
+ case CONST_16:
+ case CONST_4:
+ case CONST_HIGH16:
+ return b(nInt((Integer) ((ConstStmtNode) insn).value));
+ case CONST_WIDE:
+ case CONST_WIDE_16:
+ case CONST_WIDE_32:
+ case CONST_WIDE_HIGH16:
+ return b(nLong((Long) ((ConstStmtNode) insn).value));
+ case CONST_CLASS:
+ return b(nType((DexType) ((ConstStmtNode) insn).value));
+ case CONST_STRING:
+ case CONST_STRING_JUMBO:
+ return b(nString((String) ((ConstStmtNode) insn).value));
+ case SGET:
+ case SGET_BOOLEAN:
+ case SGET_BYTE:
+ case SGET_CHAR:
+ case SGET_OBJECT:
+ case SGET_SHORT:
+ case SGET_WIDE:
+ Field field = ((FieldStmtNode) insn).field;
+ return b(nStaticField(field.getOwner(), field.getName(), field.getType()));
+ case NEW_INSTANCE:
+ return b(nNew(((TypeStmtNode) insn).type));
+ default:
}
return null;
}
@@ -591,194 +668,200 @@ public DvmValue unaryOperation(DexStmtNode insn, DvmValue value) {
}
Local local = getLocal(value);
switch (insn.op) {
- case NOT_INT:
- return b(nNot(local, "I"));
- case NOT_LONG:
- return b(nNot(local, "J"));
+ case NOT_INT:
+ return b(nNot(local, "I"));
+ case NOT_LONG:
+ return b(nNot(local, "J"));
- case NEG_DOUBLE:
- return b(nNeg(local, "D"));
+ case NEG_DOUBLE:
+ return b(nNeg(local, "D"));
- case NEG_FLOAT:
- return b(nNeg(local, "F"));
+ case NEG_FLOAT:
+ return b(nNeg(local, "F"));
- case NEG_INT:
- return b(nNeg(local, "I"));
+ case NEG_INT:
+ return b(nNeg(local, "I"));
- case NEG_LONG:
- return b(nNeg(local, "J"));
- case INT_TO_BYTE:
- return b(nCast(local, "I", "B"));
+ case NEG_LONG:
+ return b(nNeg(local, "J"));
+ case INT_TO_BYTE:
+ return b(nCast(local, "I", "B"));
- case INT_TO_CHAR:
- return b(nCast(local, "I", "C"));
+ case INT_TO_CHAR:
+ return b(nCast(local, "I", "C"));
- case INT_TO_DOUBLE:
- return b(nCast(local, "I", "D"));
+ case INT_TO_DOUBLE:
+ return b(nCast(local, "I", "D"));
- case INT_TO_FLOAT:
- return b(nCast(local, "I", "F"));
+ case INT_TO_FLOAT:
+ return b(nCast(local, "I", "F"));
- case INT_TO_LONG:
- return b(nCast(local, "I", "J"));
+ case INT_TO_LONG:
+ return b(nCast(local, "I", "J"));
- case INT_TO_SHORT:
- return b(nCast(local, "I", "S"));
+ case INT_TO_SHORT:
+ return b(nCast(local, "I", "S"));
- case FLOAT_TO_DOUBLE:
- return b(nCast(local, "F", "D"));
+ case FLOAT_TO_DOUBLE:
+ return b(nCast(local, "F", "D"));
- case FLOAT_TO_INT:
- return b(nCast(local, "F", "I"));
+ case FLOAT_TO_INT:
+ return b(nCast(local, "F", "I"));
- case FLOAT_TO_LONG:
- return b(nCast(local, "F", "J"));
+ case FLOAT_TO_LONG:
+ return b(nCast(local, "F", "J"));
- case DOUBLE_TO_FLOAT:
- return b(nCast(local, "D", "F"));
+ case DOUBLE_TO_FLOAT:
+ return b(nCast(local, "D", "F"));
- case DOUBLE_TO_INT:
- return b(nCast(local, "D", "I"));
+ case DOUBLE_TO_INT:
+ return b(nCast(local, "D", "I"));
- case DOUBLE_TO_LONG:
- return b(nCast(local, "D", "J"));
+ case DOUBLE_TO_LONG:
+ return b(nCast(local, "D", "J"));
- case LONG_TO_DOUBLE:
- return b(nCast(local, "J", "D"));
+ case LONG_TO_DOUBLE:
+ return b(nCast(local, "J", "D"));
- case LONG_TO_FLOAT:
- return b(nCast(local, "J", "F"));
+ case LONG_TO_FLOAT:
+ return b(nCast(local, "J", "F"));
- case LONG_TO_INT:
- return b(nCast(local, "J", "I"));
+ case LONG_TO_INT:
+ return b(nCast(local, "J", "I"));
- case ARRAY_LENGTH:
- return b(nLength(local));
+ case ARRAY_LENGTH:
+ return b(nLength(local));
- case IF_EQZ:
- emit(nIf(Exprs
- .nEq(local, nInt(0), TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_EQZ:
+ emit(nIf(Exprs
+ .nEq(local, nInt(0), TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IF_GEZ:
- emit(nIf(Exprs.nGe(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_GEZ:
+ emit(nIf(Exprs.nGe(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IF_GTZ:
- emit(nIf(Exprs.nGt(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_GTZ:
+ emit(nIf(Exprs.nGt(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IF_LEZ:
- emit(nIf(Exprs.nLe(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_LEZ:
+ emit(nIf(Exprs.nLe(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IF_LTZ:
- emit(nIf(Exprs.nLt(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
- return null;
-
- case IF_NEZ:
- emit(nIf(Exprs
- .nNe(local, nInt(0), TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_LTZ:
+ emit(nIf(Exprs.nLt(local, nInt(0), "I"), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case PACKED_SWITCH:
- case SPARSE_SWITCH:
- DexLabel[] labels = ((BaseSwitchStmtNode) insn).labels;
- LabelStmt[] lss = new LabelStmt[labels.length];
- for (int i = 0; i < labels.length; i++) {
- lss[i] = getLabel(labels[i]);
- }
- LabelStmt d = new LabelStmt();
- if (insn.op == Op.PACKED_SWITCH) {
- emit(nTableSwitch(local, ((PackedSwitchStmtNode) insn).first_case, lss, d));
- } else {
- emit(nLookupSwitch(local, ((SparseSwitchStmtNode) insn).cases, lss, d));
- }
- emit(d);
- return null;
+ case IF_NEZ:
+ emit(nIf(Exprs
+ .nNe(local, nInt(0), TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case SPUT:
- case SPUT_BOOLEAN:
- case SPUT_BYTE:
- case SPUT_CHAR:
- case SPUT_OBJECT:
- case SPUT_SHORT:
- case SPUT_WIDE: {
- Field field = ((FieldStmtNode) insn).field;
- emit(nAssign(nStaticField(field.getOwner(), field.getName(), field.getType()), local));
- return null;
+ case PACKED_SWITCH:
+ case SPARSE_SWITCH:
+ DexLabel[] labels = ((BaseSwitchStmtNode) insn).labels;
+ LabelStmt[] lss = new LabelStmt[labels.length];
+ for (int i = 0; i < labels.length; i++) {
+ lss[i] = getLabel(labels[i]);
}
- case IGET:
- case IGET_BOOLEAN:
- case IGET_BYTE:
- case IGET_CHAR:
- case IGET_OBJECT:
- case IGET_SHORT:
- case IGET_WIDE: {
- Field field = ((FieldStmtNode) insn).field;
- return b(nField(local, field.getOwner(), field.getName(), field.getType()));
+ LabelStmt d = new LabelStmt();
+ if (insn.op == Op.PACKED_SWITCH) {
+ emit(nTableSwitch(local, ((PackedSwitchStmtNode) insn).first_case, lss, d));
+ } else {
+ emit(nLookupSwitch(local, ((SparseSwitchStmtNode) insn).cases, lss, d));
}
- case INSTANCE_OF:
- return b(nInstanceOf(local, ((TypeStmtNode) insn).type));
-
- case NEW_ARRAY:
- return b(nNewArray(((TypeStmtNode) insn).type.substring(1), local));
-
- case CHECK_CAST:
- return b(nCheckCast(local, ((TypeStmtNode) insn).type));
-
- case MONITOR_ENTER:
- emit(nLock(local));
- return null;
- case MONITOR_EXIT:
- emit(nUnLock(local));
- return null;
- case THROW:
- emit(nThrow(local));
- return null;
- case ADD_INT_LIT16:
- case ADD_INT_LIT8:
- return b(nAdd(local, nInt(((Stmt2R1NNode) insn).content), "I"));
-
- case RSUB_INT_LIT8:
- case RSUB_INT://
- return b(nSub(nInt(((Stmt2R1NNode) insn).content), local, "I"));
-
- case MUL_INT_LIT8:
- case MUL_INT_LIT16:
- return b(nMul(local, nInt(((Stmt2R1NNode) insn).content), "I"));
-
- case DIV_INT_LIT16:
- case DIV_INT_LIT8:
- return b(nDiv(local, nInt(((Stmt2R1NNode) insn).content), "I"));
-
- case REM_INT_LIT16:
- case REM_INT_LIT8:
- return b(nRem(local, nInt(((Stmt2R1NNode) insn).content), "I"));
-
- case AND_INT_LIT16:
- case AND_INT_LIT8:
- return b(nAnd(local, nInt(((Stmt2R1NNode) insn).content), ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? "I" : TypeClass.ZI.name));
-
- case OR_INT_LIT16:
- case OR_INT_LIT8:
- return b(nOr(local, nInt(((Stmt2R1NNode) insn).content), ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? "I" : TypeClass.ZI.name));
-
- case XOR_INT_LIT16:
- case XOR_INT_LIT8:
- return b(nXor(local, nInt(((Stmt2R1NNode) insn).content), ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? "I" : TypeClass.ZI.name));
-
- case SHL_INT_LIT8:
- return b(nShl(local, nInt(((Stmt2R1NNode) insn).content), "I"));
-
- case SHR_INT_LIT8:
- return b(nShr(local, nInt(((Stmt2R1NNode) insn).content), "I"));
-
- case USHR_INT_LIT8:
- return b(nUshr(local, nInt(((Stmt2R1NNode) insn).content), "I"));
- case FILL_ARRAY_DATA:
- emit(nFillArrayData(local, nArrayValue(((FillArrayDataStmtNode) insn).array)));
- return null;
+ emit(d);
+ return null;
+
+ case SPUT:
+ case SPUT_BOOLEAN:
+ case SPUT_BYTE:
+ case SPUT_CHAR:
+ case SPUT_OBJECT:
+ case SPUT_SHORT:
+ case SPUT_WIDE: {
+ Field field = ((FieldStmtNode) insn).field;
+ emit(nAssign(nStaticField(field.getOwner(), field.getName(), field.getType()), local));
+ return null;
+ }
+ case IGET:
+ case IGET_BOOLEAN:
+ case IGET_BYTE:
+ case IGET_CHAR:
+ case IGET_OBJECT:
+ case IGET_SHORT:
+ case IGET_WIDE: {
+ Field field = ((FieldStmtNode) insn).field;
+ return b(nField(local, field.getOwner(), field.getName(), field.getType()));
+ }
+ case INSTANCE_OF:
+ return b(nInstanceOf(local, ((TypeStmtNode) insn).type));
+
+ case NEW_ARRAY:
+ return b(nNewArray(((TypeStmtNode) insn).type.substring(1), local));
+
+ case CHECK_CAST:
+ return b(nCheckCast(local, ((TypeStmtNode) insn).type));
+
+ case MONITOR_ENTER:
+ emit(nLock(local));
+ return null;
+ case MONITOR_EXIT:
+ emit(nUnLock(local));
+ return null;
+ case THROW:
+ emit(nThrow(local));
+ return null;
+ case ADD_INT_LIT16:
+ case ADD_INT_LIT8:
+ return b(nAdd(local, nInt(((Stmt2R1NNode) insn).content), "I"));
+
+ case RSUB_INT_LIT8:
+ case RSUB_INT://
+ return b(nSub(nInt(((Stmt2R1NNode) insn).content), local, "I"));
+
+ case MUL_INT_LIT8:
+ case MUL_INT_LIT16:
+ return b(nMul(local, nInt(((Stmt2R1NNode) insn).content), "I"));
+
+ case DIV_INT_LIT16:
+ case DIV_INT_LIT8:
+ return b(nDiv(local, nInt(((Stmt2R1NNode) insn).content), "I"));
+
+ case REM_INT_LIT16:
+ case REM_INT_LIT8:
+ return b(nRem(local, nInt(((Stmt2R1NNode) insn).content), "I"));
+
+ case AND_INT_LIT16:
+ case AND_INT_LIT8:
+ return b(nAnd(local, nInt(((Stmt2R1NNode) insn).content),
+ ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? "I" :
+ TypeClass.ZI.name));
+
+ case OR_INT_LIT16:
+ case OR_INT_LIT8:
+ return b(nOr(local, nInt(((Stmt2R1NNode) insn).content),
+ ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? "I" :
+ TypeClass.ZI.name));
+
+ case XOR_INT_LIT16:
+ case XOR_INT_LIT8:
+ return b(nXor(local, nInt(((Stmt2R1NNode) insn).content),
+ ((Stmt2R1NNode) insn).content < 0 || ((Stmt2R1NNode) insn).content > 1 ? "I" :
+ TypeClass.ZI.name));
+
+ case SHL_INT_LIT8:
+ return b(nShl(local, nInt(((Stmt2R1NNode) insn).content), "I"));
+
+ case SHR_INT_LIT8:
+ return b(nShr(local, nInt(((Stmt2R1NNode) insn).content), "I"));
+
+ case USHR_INT_LIT8:
+ return b(nUshr(local, nInt(((Stmt2R1NNode) insn).content), "I"));
+ case FILL_ARRAY_DATA:
+ emit(nFillArrayData(local, nArrayValue(((FillArrayDataStmtNode) insn).array)));
+ return null;
}
throw new RuntimeException();
}
@@ -792,270 +875,270 @@ public DvmValue binaryOperation(DexStmtNode insn, DvmValue value1, DvmValue valu
Local local1 = getLocal(value1);
Local local2 = getLocal(value2);
switch (insn.op) {
- case AGET:
- return b(nArray(local1, local2, TypeClass.IF.name));
+ case AGET:
+ return b(nArray(local1, local2, TypeClass.IF.name));
- case AGET_BOOLEAN:
- return b(nArray(local1, local2, "Z"));
+ case AGET_BOOLEAN:
+ return b(nArray(local1, local2, "Z"));
- case AGET_BYTE:
- return b(nArray(local1, local2, "B"));
+ case AGET_BYTE:
+ return b(nArray(local1, local2, "B"));
- case AGET_CHAR:
- return b(nArray(local1, local2, "C"));
+ case AGET_CHAR:
+ return b(nArray(local1, local2, "C"));
- case AGET_OBJECT:
- return b(nArray(local1, local2, "L"));
+ case AGET_OBJECT:
+ return b(nArray(local1, local2, "L"));
- case AGET_SHORT:
- return b(nArray(local1, local2, "S"));
+ case AGET_SHORT:
+ return b(nArray(local1, local2, "S"));
- case AGET_WIDE:
- return b(nArray(local1, local2, TypeClass.JD.name));
+ case AGET_WIDE:
+ return b(nArray(local1, local2, TypeClass.JD.name));
- case CMP_LONG:
- return b(nLCmp(local1, local2));
+ case CMP_LONG:
+ return b(nLCmp(local1, local2));
- case CMPG_DOUBLE:
- return b(nDCmpg(local1, local2));
+ case CMPG_DOUBLE:
+ return b(nDCmpg(local1, local2));
- case CMPG_FLOAT:
- return b(nFCmpg(local1, local2));
+ case CMPG_FLOAT:
+ return b(nFCmpg(local1, local2));
- case CMPL_DOUBLE:
- return b(nDCmpl(local1, local2));
+ case CMPL_DOUBLE:
+ return b(nDCmpl(local1, local2));
- case CMPL_FLOAT:
- return b(nFCmpl(local1, local2));
+ case CMPL_FLOAT:
+ return b(nFCmpl(local1, local2));
- case ADD_DOUBLE:
- return b(nAdd(local1, local2, "D"));
+ case ADD_DOUBLE:
+ return b(nAdd(local1, local2, "D"));
- case ADD_FLOAT:
- return b(nAdd(local1, local2, "F"));
+ case ADD_FLOAT:
+ return b(nAdd(local1, local2, "F"));
- case ADD_INT:
- return b(nAdd(local1, local2, "I"));
+ case ADD_INT:
+ return b(nAdd(local1, local2, "I"));
- case ADD_LONG:
- return b(nAdd(local1, local2, "J"));
+ case ADD_LONG:
+ return b(nAdd(local1, local2, "J"));
- case SUB_DOUBLE:
- return b(nSub(local1, local2, "D"));
+ case SUB_DOUBLE:
+ return b(nSub(local1, local2, "D"));
- case SUB_FLOAT:
- return b(nSub(local1, local2, "F"));
+ case SUB_FLOAT:
+ return b(nSub(local1, local2, "F"));
- case SUB_INT:
- return b(nSub(local1, local2, "I"));
+ case SUB_INT:
+ return b(nSub(local1, local2, "I"));
- case SUB_LONG:
- return b(nSub(local1, local2, "J"));
+ case SUB_LONG:
+ return b(nSub(local1, local2, "J"));
- case MUL_DOUBLE:
- return b(nMul(local1, local2, "D"));
+ case MUL_DOUBLE:
+ return b(nMul(local1, local2, "D"));
- case MUL_FLOAT:
- return b(nMul(local1, local2, "F"));
+ case MUL_FLOAT:
+ return b(nMul(local1, local2, "F"));
- case MUL_INT:
- return b(nMul(local1, local2, "I"));
+ case MUL_INT:
+ return b(nMul(local1, local2, "I"));
- case MUL_LONG:
- return b(nMul(local1, local2, "J"));
+ case MUL_LONG:
+ return b(nMul(local1, local2, "J"));
- case DIV_DOUBLE:
- return b(nDiv(local1, local2, "D"));
+ case DIV_DOUBLE:
+ return b(nDiv(local1, local2, "D"));
- case DIV_FLOAT:
- return b(nDiv(local1, local2, "F"));
+ case DIV_FLOAT:
+ return b(nDiv(local1, local2, "F"));
- case DIV_INT:
- return b(nDiv(local1, local2, "I"));
+ case DIV_INT:
+ return b(nDiv(local1, local2, "I"));
- case DIV_LONG:
- return b(nDiv(local1, local2, "J"));
+ case DIV_LONG:
+ return b(nDiv(local1, local2, "J"));
- case REM_DOUBLE:
- return b(nRem(local1, local2, "D"));
+ case REM_DOUBLE:
+ return b(nRem(local1, local2, "D"));
- case REM_FLOAT:
- return b(nRem(local1, local2, "F"));
+ case REM_FLOAT:
+ return b(nRem(local1, local2, "F"));
- case REM_INT:
- return b(nRem(local1, local2, "I"));
+ case REM_INT:
+ return b(nRem(local1, local2, "I"));
- case REM_LONG:
- return b(nRem(local1, local2, "J"));
+ case REM_LONG:
+ return b(nRem(local1, local2, "J"));
- case AND_INT:
- return b(nAnd(local1, local2, TypeClass.ZI.name));
+ case AND_INT:
+ return b(nAnd(local1, local2, TypeClass.ZI.name));
- case AND_LONG:
- return b(nAnd(local1, local2, "J"));
+ case AND_LONG:
+ return b(nAnd(local1, local2, "J"));
- case OR_INT:
- return b(nOr(local1, local2, TypeClass.ZI.name));
+ case OR_INT:
+ return b(nOr(local1, local2, TypeClass.ZI.name));
- case OR_LONG:
- return b(nOr(local1, local2, "J"));
+ case OR_LONG:
+ return b(nOr(local1, local2, "J"));
- case XOR_INT:
- return b(nXor(local1, local2, TypeClass.ZI.name));
+ case XOR_INT:
+ return b(nXor(local1, local2, TypeClass.ZI.name));
- case XOR_LONG:
- return b(nXor(local1, local2, "J"));
+ case XOR_LONG:
+ return b(nXor(local1, local2, "J"));
- case SHL_INT:
- return b(nShl(local1, local2, "I"));
+ case SHL_INT:
+ return b(nShl(local1, local2, "I"));
- case SHL_LONG:
- return b(nShl(local1, local2, "J"));
+ case SHL_LONG:
+ return b(nShl(local1, local2, "J"));
- case SHR_INT:
- return b(nShr(local1, local2, "I"));
+ case SHR_INT:
+ return b(nShr(local1, local2, "I"));
- case SHR_LONG:
- return b(nShr(local1, local2, "J"));
+ case SHR_LONG:
+ return b(nShr(local1, local2, "J"));
- case USHR_INT:
- return b(nUshr(local1, local2, "I"));
+ case USHR_INT:
+ return b(nUshr(local1, local2, "I"));
- case USHR_LONG:
- return b(nUshr(local1, local2, "J"));
+ case USHR_LONG:
+ return b(nUshr(local1, local2, "J"));
- case IF_EQ:
- emit(nIf(Exprs
- .nEq(local1, local2, TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_EQ:
+ emit(nIf(Exprs
+ .nEq(local1, local2, TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IF_GE:
- emit(nIf(Exprs.nGe(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_GE:
+ emit(nIf(Exprs.nGe(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IF_GT:
- emit(nIf(Exprs.nGt(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_GT:
+ emit(nIf(Exprs.nGt(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IF_LE:
- emit(nIf(Exprs.nLe(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_LE:
+ emit(nIf(Exprs.nLe(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IF_LT:
- emit(nIf(Exprs.nLt(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_LT:
+ emit(nIf(Exprs.nLt(local1, local2, "I"), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IF_NE:
- emit(nIf(Exprs
- .nNe(local1, local2, TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
- return null;
+ case IF_NE:
+ emit(nIf(Exprs
+ .nNe(local1, local2, TypeClass.ZIL.name), getLabel(((JumpStmtNode) insn).label)));
+ return null;
- case IPUT:
- case IPUT_BOOLEAN:
- case IPUT_BYTE:
- case IPUT_CHAR:
- case IPUT_OBJECT:
- case IPUT_SHORT:
- case IPUT_WIDE:
- Field field = ((FieldStmtNode) insn).field;
- emit(nAssign(nField(local1, field.getOwner(), field.getName(), field.getType()), local2));
- return null;
+ case IPUT:
+ case IPUT_BOOLEAN:
+ case IPUT_BYTE:
+ case IPUT_CHAR:
+ case IPUT_OBJECT:
+ case IPUT_SHORT:
+ case IPUT_WIDE:
+ Field field = ((FieldStmtNode) insn).field;
+ emit(nAssign(nField(local1, field.getOwner(), field.getName(), field.getType()), local2));
+ return null;
- case ADD_DOUBLE_2ADDR:
- return b(nAdd(local1, local2, "D"));
+ case ADD_DOUBLE_2ADDR:
+ return b(nAdd(local1, local2, "D"));
- case ADD_FLOAT_2ADDR:
- return b(nAdd(local1, local2, "F"));
+ case ADD_FLOAT_2ADDR:
+ return b(nAdd(local1, local2, "F"));
- case ADD_INT_2ADDR:
- return b(nAdd(local1, local2, "I"));
+ case ADD_INT_2ADDR:
+ return b(nAdd(local1, local2, "I"));
- case ADD_LONG_2ADDR:
- return b(nAdd(local1, local2, "J"));
+ case ADD_LONG_2ADDR:
+ return b(nAdd(local1, local2, "J"));
- case SUB_DOUBLE_2ADDR:
- return b(nSub(local1, local2, "D"));
+ case SUB_DOUBLE_2ADDR:
+ return b(nSub(local1, local2, "D"));
- case SUB_FLOAT_2ADDR:
- return b(nSub(local1, local2, "F"));
+ case SUB_FLOAT_2ADDR:
+ return b(nSub(local1, local2, "F"));
- case SUB_INT_2ADDR:
- return b(nSub(local1, local2, "I"));
+ case SUB_INT_2ADDR:
+ return b(nSub(local1, local2, "I"));
- case SUB_LONG_2ADDR:
- return b(nSub(local1, local2, "J"));
+ case SUB_LONG_2ADDR:
+ return b(nSub(local1, local2, "J"));
- case MUL_DOUBLE_2ADDR:
- return b(nMul(local1, local2, "D"));
+ case MUL_DOUBLE_2ADDR:
+ return b(nMul(local1, local2, "D"));
- case MUL_FLOAT_2ADDR:
- return b(nMul(local1, local2, "F"));
+ case MUL_FLOAT_2ADDR:
+ return b(nMul(local1, local2, "F"));
- case MUL_INT_2ADDR:
- return b(nMul(local1, local2, "I"));
+ case MUL_INT_2ADDR:
+ return b(nMul(local1, local2, "I"));
- case MUL_LONG_2ADDR:
- return b(nMul(local1, local2, "J"));
+ case MUL_LONG_2ADDR:
+ return b(nMul(local1, local2, "J"));
- case DIV_DOUBLE_2ADDR:
- return b(nDiv(local1, local2, "D"));
+ case DIV_DOUBLE_2ADDR:
+ return b(nDiv(local1, local2, "D"));
- case DIV_FLOAT_2ADDR:
- return b(nDiv(local1, local2, "F"));
+ case DIV_FLOAT_2ADDR:
+ return b(nDiv(local1, local2, "F"));
- case DIV_INT_2ADDR:
- return b(nDiv(local1, local2, "I"));
+ case DIV_INT_2ADDR:
+ return b(nDiv(local1, local2, "I"));
- case DIV_LONG_2ADDR:
- return b(nDiv(local1, local2, "J"));
+ case DIV_LONG_2ADDR:
+ return b(nDiv(local1, local2, "J"));
- case REM_DOUBLE_2ADDR:
- return b(nRem(local1, local2, "D"));
+ case REM_DOUBLE_2ADDR:
+ return b(nRem(local1, local2, "D"));
- case REM_FLOAT_2ADDR:
- return b(nRem(local1, local2, "F"));
+ case REM_FLOAT_2ADDR:
+ return b(nRem(local1, local2, "F"));
- case REM_INT_2ADDR:
- return b(nRem(local1, local2, "I"));
+ case REM_INT_2ADDR:
+ return b(nRem(local1, local2, "I"));
- case REM_LONG_2ADDR:
- return b(nRem(local1, local2, "J"));
+ case REM_LONG_2ADDR:
+ return b(nRem(local1, local2, "J"));
- case AND_INT_2ADDR:
- return b(nAnd(local1, local2, TypeClass.ZI.name));
+ case AND_INT_2ADDR:
+ return b(nAnd(local1, local2, TypeClass.ZI.name));
- case AND_LONG_2ADDR:
- return b(nAnd(local1, local2, "J"));
+ case AND_LONG_2ADDR:
+ return b(nAnd(local1, local2, "J"));
- case OR_INT_2ADDR:
- return b(nOr(local1, local2, TypeClass.ZI.name));
+ case OR_INT_2ADDR:
+ return b(nOr(local1, local2, TypeClass.ZI.name));
- case OR_LONG_2ADDR:
- return b(nOr(local1, local2, "J"));
+ case OR_LONG_2ADDR:
+ return b(nOr(local1, local2, "J"));
- case XOR_INT_2ADDR:
- return b(nXor(local1, local2, TypeClass.ZI.name));
+ case XOR_INT_2ADDR:
+ return b(nXor(local1, local2, TypeClass.ZI.name));
- case XOR_LONG_2ADDR:
- return b(nXor(local1, local2, "J"));
+ case XOR_LONG_2ADDR:
+ return b(nXor(local1, local2, "J"));
- case SHL_INT_2ADDR:
- return b(nShl(local1, local2, "I"));
+ case SHL_INT_2ADDR:
+ return b(nShl(local1, local2, "I"));
- case SHL_LONG_2ADDR:
- return b(nShl(local1, local2, "J"));
+ case SHL_LONG_2ADDR:
+ return b(nShl(local1, local2, "J"));
- case SHR_INT_2ADDR:
- return b(nShr(local1, local2, "I"));
+ case SHR_INT_2ADDR:
+ return b(nShr(local1, local2, "I"));
- case SHR_LONG_2ADDR:
- return b(nShr(local1, local2, "J"));
+ case SHR_LONG_2ADDR:
+ return b(nShr(local1, local2, "J"));
- case USHR_INT_2ADDR:
- return b(nUshr(local1, local2, "I"));
+ case USHR_INT_2ADDR:
+ return b(nUshr(local1, local2, "I"));
- case USHR_LONG_2ADDR:
- return b(nUshr(local1, local2, "J"));
+ case USHR_LONG_2ADDR:
+ return b(nUshr(local1, local2, "J"));
}
throw new RuntimeException();
@@ -1071,27 +1154,27 @@ public DvmValue ternaryOperation(DexStmtNode insn, DvmValue value1, DvmValue val
Local localIndex = getLocal(value2);
Local localValue = getLocal(value3);
switch (insn.op) {
- case APUT:
- emit(nAssign(nArray(localArray, localIndex, TypeClass.IF.name), localValue));
- break;
- case APUT_BOOLEAN:
- emit(nAssign(nArray(localArray, localIndex, "Z"), localValue));
- break;
- case APUT_BYTE:
- emit(nAssign(nArray(localArray, localIndex, "B"), localValue));
- break;
- case APUT_CHAR:
- emit(nAssign(nArray(localArray, localIndex, "C"), localValue));
- break;
- case APUT_OBJECT:
- emit(nAssign(nArray(localArray, localIndex, "L"), localValue));
- break;
- case APUT_SHORT:
- emit(nAssign(nArray(localArray, localIndex, "S"), localValue));
- break;
- case APUT_WIDE:
- emit(nAssign(nArray(localArray, localIndex, TypeClass.JD.name), localValue));
- break;
+ case APUT:
+ emit(nAssign(nArray(localArray, localIndex, TypeClass.IF.name), localValue));
+ break;
+ case APUT_BOOLEAN:
+ emit(nAssign(nArray(localArray, localIndex, "Z"), localValue));
+ break;
+ case APUT_BYTE:
+ emit(nAssign(nArray(localArray, localIndex, "B"), localValue));
+ break;
+ case APUT_CHAR:
+ emit(nAssign(nArray(localArray, localIndex, "C"), localValue));
+ break;
+ case APUT_OBJECT:
+ emit(nAssign(nArray(localArray, localIndex, "L"), localValue));
+ break;
+ case APUT_SHORT:
+ emit(nAssign(nArray(localArray, localIndex, "S"), localValue));
+ break;
+ case APUT_WIDE:
+ emit(nAssign(nArray(localArray, localIndex, TypeClass.JD.name), localValue));
+ break;
}
return null;
}
@@ -1107,94 +1190,94 @@ public DvmValue naryOperation(DexStmtNode insn, List extends DvmValue> values)
switch (insn.op) {
- case FILLED_NEW_ARRAY:
- case FILLED_NEW_ARRAY_RANGE:
- DvmValue value = new DvmValue();
- FilledNewArrayStmtNode filledNewArrayStmtNode = (FilledNewArrayStmtNode) insn;
- String type = filledNewArrayStmtNode.type;
-
- String elem = type.substring(1);
- emit(nAssign(getLocal(value), nNewArray(elem, nInt(values.size()))));
- for (int i = 0; i < values.size(); i++) {
- emit(nAssign(nArray(getLocal(value), nInt(i), elem), getLocal(values.get(i))));
- }
+ case FILLED_NEW_ARRAY:
+ case FILLED_NEW_ARRAY_RANGE:
+ DvmValue value = new DvmValue();
+ FilledNewArrayStmtNode filledNewArrayStmtNode = (FilledNewArrayStmtNode) insn;
+ String type = filledNewArrayStmtNode.type;
+
+ String elem = type.substring(1);
+ emit(nAssign(getLocal(value), nNewArray(elem, nInt(values.size()))));
+ for (int i = 0; i < values.size(); i++) {
+ emit(nAssign(nArray(getLocal(value), nInt(i), elem), getLocal(values.get(i))));
+ }
- return value;
- case INVOKE_CUSTOM:
- case INVOKE_CUSTOM_RANGE: {
- Value[] vs = new Value[values.size()];
- for (int i = 0; i < vs.length; i++) {
- vs[i] = getLocal(values.get(i));
- }
- MethodCustomStmtNode n = (MethodCustomStmtNode) insn;
- Value invoke = nInvokeCustom(vs, n.name, n.proto, n.bsm, n.bsmArgs);
- if ("V".equals(n.getProto().getReturnType())) {
- emit(nVoidInvoke(invoke));
- return null;
- } else {
- return b(invoke);
- }
+ return value;
+ case INVOKE_CUSTOM:
+ case INVOKE_CUSTOM_RANGE: {
+ Value[] vs = new Value[values.size()];
+ for (int i = 0; i < vs.length; i++) {
+ vs[i] = getLocal(values.get(i));
}
- case INVOKE_POLYMORPHIC:
- case INVOKE_POLYMORPHIC_RANGE: {
- Value[] vs = new Value[values.size()];
- for (int i = 0; i < vs.length; i++) {
- vs[i] = getLocal(values.get(i));
- }
- MethodPolymorphicStmtNode n = (MethodPolymorphicStmtNode) insn;
- Value invoke = nInvokePolymorphic(vs, n.proto, n.method);
- if ("V".equals(n.getProto().getReturnType())) {
- emit(nVoidInvoke(invoke));
- return null;
- } else {
- return b(invoke);
- }
+ MethodCustomStmtNode n = (MethodCustomStmtNode) insn;
+ Value invoke = nInvokeCustom(vs, n.name, n.proto, n.bsm, n.bsmArgs);
+ if ("V".equals(n.getProto().getReturnType())) {
+ emit(nVoidInvoke(invoke));
+ return null;
+ } else {
+ return b(invoke);
+ }
+ }
+ case INVOKE_POLYMORPHIC:
+ case INVOKE_POLYMORPHIC_RANGE: {
+ Value[] vs = new Value[values.size()];
+ for (int i = 0; i < vs.length; i++) {
+ vs[i] = getLocal(values.get(i));
+ }
+ MethodPolymorphicStmtNode n = (MethodPolymorphicStmtNode) insn;
+ Value invoke = nInvokePolymorphic(vs, n.proto, n.method);
+ if ("V".equals(n.getProto().getReturnType())) {
+ emit(nVoidInvoke(invoke));
+ return null;
+ } else {
+ return b(invoke);
+ }
+ }
+ default:
+ Op op = insn.op;
+ Value[] vs = new Value[values.size()];
+ for (int i = 0; i < vs.length; i++) {
+ vs[i] = getLocal(values.get(i));
}
- default:
- Op op = insn.op;
- Value[] vs = new Value[values.size()];
- for (int i = 0; i < vs.length; i++) {
- vs[i] = getLocal(values.get(i));
- }
- Method method = ((MethodStmtNode) insn).method;
- Value invoke = null;
- switch (op) {
- case INVOKE_VIRTUAL_RANGE:
- case INVOKE_VIRTUAL:
- invoke = nInvokeVirtual(vs, method.getOwner(), method.getName(), method
- .getParameterTypes(),
- method.getReturnType());
- break;
- case INVOKE_SUPER_RANGE:
- case INVOKE_DIRECT_RANGE:
- case INVOKE_SUPER:
- case INVOKE_DIRECT:
- invoke = nInvokeSpecial(vs, method.getOwner(), method.getName(), method
- .getParameterTypes(),
- method.getReturnType());
- break;
- case INVOKE_STATIC_RANGE:
- case INVOKE_STATIC:
- invoke = nInvokeStatic(vs, method.getOwner(), method.getName(), method
- .getParameterTypes(),
- method.getReturnType());
- break;
- case INVOKE_INTERFACE_RANGE:
- case INVOKE_INTERFACE:
- invoke = nInvokeInterface(vs, method.getOwner(), method.getName(), method
- .getParameterTypes(),
- method.getReturnType());
- break;
- default:
- throw new RuntimeException();
- }
- if ("V".equals(method.getReturnType())) {
- emit(nVoidInvoke(invoke));
- return null;
- } else {
- return b(invoke);
- }
+ Method method = ((MethodStmtNode) insn).method;
+ Value invoke;
+ switch (op) {
+ case INVOKE_VIRTUAL_RANGE:
+ case INVOKE_VIRTUAL:
+ invoke = nInvokeVirtual(vs, method.getOwner(), method.getName(), method
+ .getParameterTypes(),
+ method.getReturnType());
+ break;
+ case INVOKE_SUPER_RANGE:
+ case INVOKE_DIRECT_RANGE:
+ case INVOKE_SUPER:
+ case INVOKE_DIRECT:
+ invoke = nInvokeSpecial(vs, method.getOwner(), method.getName(), method
+ .getParameterTypes(),
+ method.getReturnType());
+ break;
+ case INVOKE_STATIC_RANGE:
+ case INVOKE_STATIC:
+ invoke = nInvokeStatic(vs, method.getOwner(), method.getName(), method
+ .getParameterTypes(),
+ method.getReturnType());
+ break;
+ case INVOKE_INTERFACE_RANGE:
+ case INVOKE_INTERFACE:
+ invoke = nInvokeInterface(vs, method.getOwner(), method.getName(), method
+ .getParameterTypes(),
+ method.getReturnType());
+ break;
+ default:
+ throw new RuntimeException();
+ }
+ if ("V".equals(method.getReturnType())) {
+ emit(nVoidInvoke(invoke));
+ return null;
+ } else {
+ return b(invoke);
+ }
}
@@ -1204,14 +1287,14 @@ public DvmValue naryOperation(DexStmtNode insn, List extends DvmValue> values)
void emitNotFindOperand(DexStmtNode insn) {
String msg;
switch (insn.op) {
- case MOVE_RESULT:
- case MOVE_RESULT_OBJECT:
- case MOVE_RESULT_WIDE:
- msg = "can't get operand(s) for " + insn.op + ", wrong position ?";
- break;
- default:
- msg = "can't get operand(s) for " + insn.op + ", out-of-range or not initialized ?";
- break;
+ case MOVE_RESULT:
+ case MOVE_RESULT_OBJECT:
+ case MOVE_RESULT_WIDE:
+ msg = "can't get operand(s) for " + insn.op + ", wrong position ?";
+ break;
+ default:
+ msg = "can't get operand(s) for " + insn.op + ", out-of-range or not initialized ?";
+ break;
}
System.err.println("WARN: " + msg);
diff --git a/dex-translator/src/main/java/com/googlecode/d2j/converter/IR2JConverter.java b/dex-translator/src/main/java/com/googlecode/d2j/converter/IR2JConverter.java
index 5633c81f7..1c777d137 100755
--- a/dex-translator/src/main/java/com/googlecode/d2j/converter/IR2JConverter.java
+++ b/dex-translator/src/main/java/com/googlecode/d2j/converter/IR2JConverter.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2013 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,19 +23,42 @@
import com.googlecode.d2j.dex.Dex2Asm;
import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.Trap;
-import com.googlecode.dex2jar.ir.expr.*;
+import com.googlecode.dex2jar.ir.expr.ArrayExpr;
+import com.googlecode.dex2jar.ir.expr.CastExpr;
+import com.googlecode.dex2jar.ir.expr.Constant;
+import com.googlecode.dex2jar.ir.expr.Exprs;
+import com.googlecode.dex2jar.ir.expr.FieldExpr;
+import com.googlecode.dex2jar.ir.expr.FilledArrayExpr;
+import com.googlecode.dex2jar.ir.expr.InvokeCustomExpr;
+import com.googlecode.dex2jar.ir.expr.InvokeExpr;
+import com.googlecode.dex2jar.ir.expr.InvokePolymorphicExpr;
+import com.googlecode.dex2jar.ir.expr.Local;
+import com.googlecode.dex2jar.ir.expr.NewExpr;
+import com.googlecode.dex2jar.ir.expr.NewMutiArrayExpr;
+import com.googlecode.dex2jar.ir.expr.StaticFieldExpr;
+import com.googlecode.dex2jar.ir.expr.TypeExpr;
+import com.googlecode.dex2jar.ir.expr.Value;
import com.googlecode.dex2jar.ir.expr.Value.E1Expr;
import com.googlecode.dex2jar.ir.expr.Value.E2Expr;
import com.googlecode.dex2jar.ir.expr.Value.EnExpr;
import com.googlecode.dex2jar.ir.expr.Value.VT;
-import com.googlecode.dex2jar.ir.stmt.*;
+import com.googlecode.dex2jar.ir.stmt.GotoStmt;
+import com.googlecode.dex2jar.ir.stmt.IfStmt;
+import com.googlecode.dex2jar.ir.stmt.LabelStmt;
+import com.googlecode.dex2jar.ir.stmt.LookupSwitchStmt;
+import com.googlecode.dex2jar.ir.stmt.Stmt;
import com.googlecode.dex2jar.ir.stmt.Stmt.E2Stmt;
import com.googlecode.dex2jar.ir.stmt.Stmt.ST;
-import org.objectweb.asm.*;
-
+import com.googlecode.dex2jar.ir.stmt.TableSwitchStmt;
+import com.googlecode.dex2jar.ir.stmt.UnopStmt;
import java.lang.reflect.Array;
import java.util.HashMap;
import java.util.Map;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
@SuppressWarnings("incomplete-switch")
public class IR2JConverter implements Opcodes {
@@ -69,9 +92,6 @@ private void mapLabelStmt(IrMethod ir) {
/**
* an empty try-catch block will cause other crash, we check this by finding non-label stmts between
* {@link Trap#start} and {@link Trap#end}. if find we add the try-catch or we drop the try-catch.
- *
- * @param ir
- * @param asm
*/
private void reBuildTryCatchBlocks(IrMethod ir, MethodVisitor asm) {
for (Trap trap : ir.traps) {
@@ -98,14 +118,13 @@ static String toInternal(String n) {
}
-
private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
asm = new LdcOptimizeAdapter(asm);
int maxLocalIndex = 0;
for (Local local : ir.locals) {
maxLocalIndex = Math.max(maxLocalIndex, local._ls_index);
}
- Map lockMap = new HashMap();
+ Map lockMap = new HashMap<>();
for (Stmt st : ir.stmts) {
switch (st.st) {
case LABEL:
@@ -203,7 +222,7 @@ private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
break;
}
}
- break;
+ break;
case IDENTITY: {
E2Stmt e2 = (E2Stmt) st;
if (e2.op2.vt == VT.EXCEPTION_REF) {
@@ -215,9 +234,9 @@ private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
}
}
}
- break;
+ break;
- case FILL_ARRAY_DATA:{
+ case FILL_ARRAY_DATA: {
E2Stmt e2 = (E2Stmt) st;
if (e2.getOp2().vt == VT.CONSTANT) {
Object arrayData = ((Constant) e2.getOp2()).value;
@@ -287,14 +306,14 @@ private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
asm.visitVarInsn(getOpcode(v, ISTORE), nIndex);
lockMap.put(key, nIndex);
}
- break;
+ break;
default:
throw new RuntimeException();
}
}
asm.visitInsn(MONITORENTER);
}
- break;
+ break;
case UNLOCK: {
Value v = ((UnopStmt) st).op;
if (optimizeSynchronized) {
@@ -314,7 +333,7 @@ private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
accept(v, asm);
}
}
- break;
+ break;
// TODO other
default: {
accept(v, asm);
@@ -326,7 +345,7 @@ private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
}
asm.visitInsn(MONITOREXIT);
}
- break;
+ break;
case NOP:
break;
case RETURN: {
@@ -335,31 +354,31 @@ private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
insertI2x(v.valueType, ir.ret, asm);
asm.visitInsn(getOpcode(v, IRETURN));
}
- break;
+ break;
case RETURN_VOID:
asm.visitInsn(RETURN);
break;
case LOOKUP_SWITCH: {
LookupSwitchStmt lss = (LookupSwitchStmt) st;
accept(lss.op, asm);
- Label targets[] = new Label[lss.targets.length];
+ Label[] targets = new Label[lss.targets.length];
for (int i = 0; i < targets.length; i++) {
targets[i] = (Label) lss.targets[i].tag;
}
asm.visitLookupSwitchInsn((Label) lss.defaultTarget.tag, lss.lookupValues, targets);
}
- break;
+ break;
case TABLE_SWITCH: {
TableSwitchStmt tss = (TableSwitchStmt) st;
accept(tss.op, asm);
- Label targets[] = new Label[tss.targets.length];
+ Label[] targets = new Label[tss.targets.length];
for (int i = 0; i < targets.length; i++) {
targets[i] = (Label) tss.targets[i].tag;
}
asm.visitTableSwitchInsn(tss.lowIndex, tss.lowIndex + targets.length - 1,
(Label) tss.defaultTarget.tag, targets);
}
- break;
+ break;
case THROW:
accept(((UnopStmt) st).op, asm);
asm.visitInsn(ATHROW);
@@ -373,13 +392,13 @@ private void reBuildInstructions(IrMethod ir, MethodVisitor asm) {
asm.visitInsn(POP);
} else if (!"V".equals(ret)) {
switch (ret.charAt(0)) {
- case 'J':
- case 'D':
- asm.visitInsn(POP2);
- break;
- default:
- asm.visitInsn(POP);
- break;
+ case 'J':
+ case 'D':
+ asm.visitInsn(POP2);
+ break;
+ default:
+ asm.visitInsn(POP);
+ break;
}
}
break;
@@ -396,10 +415,6 @@ private static boolean isLocalWithIndex(Value v, int i) {
/**
* insert I2x instruction
- *
- * @param tos
- * @param expect
- * @param mv
*/
private static void insertI2x(String tos, String expect, MethodVisitor mv) {
switch (expect.charAt(0)) {
@@ -519,11 +534,7 @@ private void reBuildJumpInstructions(IfStmt st, MethodVisitor asm) {
}
/**
- *
- * @param v
- * @param op
- * DUP
- * @return
+ * @param op DUP
*/
static int getOpcode(Value v, int op) {
return getOpcode(v.valueType, op);
@@ -531,28 +542,28 @@ static int getOpcode(Value v, int op) {
static int getOpcode(String v, int op) {
switch (v.charAt(0)) {
- case 'L':
- case '[':
- return Type.getType("La;").getOpcode(op);
- case 'Z':
- return Type.BOOLEAN_TYPE.getOpcode(op);
- case 'B':
- return Type.BYTE_TYPE.getOpcode(op);
- case 'S':
- return Type.SHORT_TYPE.getOpcode(op);
- case 'C':
- return Type.CHAR_TYPE.getOpcode(op);
- case 'I':
- return Type.INT_TYPE.getOpcode(op);
- case 'F':
- return Type.FLOAT_TYPE.getOpcode(op);
- case 'J':
- return Type.LONG_TYPE.getOpcode(op);
- case 'D':
- return Type.DOUBLE_TYPE.getOpcode(op);
- default:
- // FIXME handle undetected types
- return Type.INT_TYPE.getOpcode(op); // treat other as int
+ case 'L':
+ case '[':
+ return Type.getType("La;").getOpcode(op);
+ case 'Z':
+ return Type.BOOLEAN_TYPE.getOpcode(op);
+ case 'B':
+ return Type.BYTE_TYPE.getOpcode(op);
+ case 'S':
+ return Type.SHORT_TYPE.getOpcode(op);
+ case 'C':
+ return Type.CHAR_TYPE.getOpcode(op);
+ case 'I':
+ return Type.INT_TYPE.getOpcode(op);
+ case 'F':
+ return Type.FLOAT_TYPE.getOpcode(op);
+ case 'J':
+ return Type.LONG_TYPE.getOpcode(op);
+ case 'D':
+ return Type.DOUBLE_TYPE.getOpcode(op);
+ default:
+ // FIXME handle undetected types
+ return Type.INT_TYPE.getOpcode(op); // treat other as int
}
}
@@ -578,8 +589,8 @@ private static void accept(Value value, MethodVisitor asm) {
asm.visitTypeInsn(NEW, toInternal(((NewExpr) value).type));
break;
case STATIC_FIELD:
- StaticFieldExpr sfe= (StaticFieldExpr) value;
- asm.visitFieldInsn(GETSTATIC,toInternal(sfe.owner),sfe.name,sfe.type);
+ StaticFieldExpr sfe = (StaticFieldExpr) value;
+ asm.visitFieldInsn(GETSTATIC, toInternal(sfe.owner), sfe.name, sfe.type);
break;
}
break;
@@ -678,7 +689,8 @@ private static void reBuildEnExpression(EnExpr value, MethodVisitor asm) {
if (ie.vt == VT.INVOKE_NEW) {
p = new Proto(p.getParameterTypes(), "V");
}
- asm.visitMethodInsn(opcode, toInternal(ie.getOwner()), ie.getName(), p.getDesc(), opcode == INVOKEINTERFACE);
+ asm.visitMethodInsn(opcode, toInternal(ie.getOwner()), ie.getName(), p.getDesc(),
+ opcode == INVOKEINTERFACE);
}
break;
case INVOKE_CUSTOM: {
@@ -701,13 +713,14 @@ private static void reBuildEnExpression(EnExpr value, MethodVisitor asm) {
} else {
throw new RuntimeException();
}
- asm.visitInvokeDynamicInsn(ice.name, ice.proto.getDesc(), (Handle) Dex2Asm.convertConstantValue(ice.handle), Dex2Asm.convertConstantValues(ice.bsmArgs));
+ asm.visitInvokeDynamicInsn(ice.name, ice.proto.getDesc(),
+ (Handle) Dex2Asm.convertConstantValue(ice.handle), Dex2Asm.convertConstantValues(ice.bsmArgs));
}
break;
case INVOKE_POLYMORPHIC: {
InvokePolymorphicExpr ipe = (InvokePolymorphicExpr) value;
Method m = ipe.method;
- String argTypes[] = ipe.getProto().getParameterTypes();
+ String[] argTypes = ipe.getProto().getParameterTypes();
Value[] vbs = ipe.getOps();
accept(vbs[0], asm);
for (int i = 1; i < vbs.length; i++) {
@@ -721,10 +734,10 @@ private static void reBuildEnExpression(EnExpr value, MethodVisitor asm) {
}
private static void box(String provideType, String expectedType, MethodVisitor asm) {
- if(provideType.equals(expectedType)){
+ if (provideType.equals(expectedType)) {
return;
}
- if(expectedType.equals("V")){
+ if (expectedType.equals("V")) {
switch (provideType.charAt(0)) {
case 'J':
case 'D':
@@ -894,18 +907,18 @@ private static void reBuildE1Expression(E1Expr e1, MethodVisitor asm) {
break;
}
}
- break;
+ break;
case CHECK_CAST:
case INSTANCE_OF: {
TypeExpr te = (TypeExpr) e1;
asm.visitTypeInsn(e1.vt == VT.CHECK_CAST ? CHECKCAST : INSTANCEOF, toInternal(te.type));
}
- break;
+ break;
case CAST: {
CastExpr te = (CastExpr) e1;
cast2(e1.op.valueType, te.to, asm);
}
- break;
+ break;
case LENGTH:
asm.visitInsn(ARRAYLENGTH);
break;
@@ -943,7 +956,7 @@ private static void reBuildE2Expression(E2Expr e2, MethodVisitor asm) {
return;
}
}
- break;
+ break;
case 'F': {
float s = (Float) constant.value;
if (s < 0) {
@@ -952,7 +965,7 @@ private static void reBuildE2Expression(E2Expr e2, MethodVisitor asm) {
return;
}
}
- break;
+ break;
case 'J': {
long s = (Long) constant.value;
if (s < 0) {
@@ -961,7 +974,7 @@ private static void reBuildE2Expression(E2Expr e2, MethodVisitor asm) {
return;
}
}
- break;
+ break;
case 'D': {
double s = (Double) constant.value;
if (s < 0) {
@@ -970,7 +983,7 @@ private static void reBuildE2Expression(E2Expr e2, MethodVisitor asm) {
return;
}
}
- break;
+ break;
}
}
@@ -1072,7 +1085,7 @@ private static void cast2(String t1, String t2, MethodVisitor asm) {
break;
}
}
- break;
+ break;
case 'J': {
switch (t2.charAt(0)) {
case 'I':
@@ -1086,7 +1099,7 @@ private static void cast2(String t1, String t2, MethodVisitor asm) {
break;
}
}
- break;
+ break;
case 'D': {
switch (t2.charAt(0)) {
case 'I':
@@ -1100,7 +1113,7 @@ private static void cast2(String t1, String t2, MethodVisitor asm) {
break;
}
}
- break;
+ break;
case 'F': {
switch (t2.charAt(0)) {
case 'I':
diff --git a/dex-translator/src/main/java/com/googlecode/d2j/converter/J2IRConverter.java b/dex-translator/src/main/java/com/googlecode/d2j/converter/J2IRConverter.java
index 0e7b3cf7d..25a4f37fe 100644
--- a/dex-translator/src/main/java/com/googlecode/d2j/converter/J2IRConverter.java
+++ b/dex-translator/src/main/java/com/googlecode/d2j/converter/J2IRConverter.java
@@ -4,20 +4,45 @@
import com.googlecode.dex2jar.ir.Trap;
import com.googlecode.dex2jar.ir.expr.Exprs;
import com.googlecode.dex2jar.ir.expr.Local;
-import com.googlecode.dex2jar.ir.stmt.*;
+import com.googlecode.dex2jar.ir.stmt.AssignStmt;
+import com.googlecode.dex2jar.ir.stmt.LabelStmt;
+import com.googlecode.dex2jar.ir.stmt.Stmt;
+import com.googlecode.dex2jar.ir.stmt.StmtList;
+import com.googlecode.dex2jar.ir.stmt.Stmts;
import com.googlecode.dex2jar.tools.Constants;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+import java.util.Stack;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
-import org.objectweb.asm.tree.*;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.IincInsnNode;
+import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.IntInsnNode;
+import org.objectweb.asm.tree.JumpInsnNode;
+import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.LookupSwitchInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TableSwitchInsnNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.Frame;
import org.objectweb.asm.tree.analysis.Interpreter;
import org.objectweb.asm.tree.analysis.Value;
-import java.util.*;
-
import static org.objectweb.asm.Opcodes.*;
public class J2IRConverter {
@@ -27,7 +52,7 @@ public class J2IRConverter {
JvmFrame[] frames;
MethodNode methodNode;
IrMethod target;
- List emitStmts[];
+ List[] emitStmts;
List preEmit = new ArrayList<>();
List currentEmit;
@@ -58,7 +83,7 @@ IrMethod populate(String owner, MethodNode source) {
target.owner = "L" + owner + ";";
target.ret = Type.getReturnType(source.desc).getDescriptor();
Type[] args = Type.getArgumentTypes(source.desc);
- String sArgs[] = new String[args.length];
+ String[] sArgs = new String[args.length];
target.args = sArgs;
for (int i = 0; i < args.length; i++) {
sArgs[i] = args[i].getDescriptor();
@@ -85,7 +110,8 @@ IrMethod convert0(String owner, MethodNode methodNode) throws AnalyzerException
BitSet handlers = new BitSet(insnList.size());
if (methodNode.tryCatchBlocks != null) {
for (TryCatchBlockNode tcb : methodNode.tryCatchBlocks) {
- target.traps.add(new Trap(getLabel(tcb.start), getLabel(tcb.end), new LabelStmt[]{getLabel(tcb.handler)},
+ target.traps.add(new Trap(getLabel(tcb.start), getLabel(tcb.end),
+ new LabelStmt[]{getLabel(tcb.handler)},
new String[]{tcb.type == null ? null : Type.getObjectType(tcb.type).getDescriptor()}));
int handlerIdx = insnList.indexOf(tcb.handler);
handlers.set(handlerIdx);
@@ -199,7 +225,8 @@ private void addPhi(JvmValue v, Set phiVal
}
}
if (phiValues.size() > 0) {
- phis.add(Stmts.nAssign(v.local, Exprs.nPhi(phiValues.toArray(new com.googlecode.dex2jar.ir.expr.Value[phiValues.size()]))));
+ phis.add(Stmts.nAssign(v.local,
+ Exprs.nPhi(phiValues.toArray(new com.googlecode.dex2jar.ir.expr.Value[0]))));
phiValues.clear();
}
}
@@ -326,73 +353,73 @@ public JvmValue newValue(Type type) {
}
@Override
- public JvmValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
+ public JvmValue newOperation(AbstractInsnNode insn) {
switch (insn.getOpcode()) {
- case ACONST_NULL:
- return b(1, Exprs.nNull());
- case ICONST_M1:
- case ICONST_0:
- case ICONST_1:
- case ICONST_2:
- case ICONST_3:
- case ICONST_4:
- case ICONST_5:
- return b(1, Exprs.nInt(insn.getOpcode() - ICONST_0));
- case LCONST_0:
- case LCONST_1:
- return b(2, Exprs.nLong(insn.getOpcode() - LCONST_0));
- case FCONST_0:
- case FCONST_1:
- case FCONST_2:
- return b(1, Exprs.nFloat(insn.getOpcode() - FCONST_0));
- case DCONST_0:
- case DCONST_1:
- return b(2, Exprs.nDouble(insn.getOpcode() - DCONST_0));
- case BIPUSH:
- case SIPUSH:
- return b(1, Exprs.nInt(((IntInsnNode) insn).operand));
- case LDC:
- Object cst = ((LdcInsnNode) insn).cst;
- if (cst instanceof Integer) {
- return b(1, Exprs.nInt((Integer) cst));
- } else if (cst instanceof Float) {
- return b(1, Exprs.nFloat((Float) cst));
- } else if (cst instanceof Long) {
- return b(2, Exprs.nLong((Long) cst));
- } else if (cst instanceof Double) {
- return b(2, Exprs.nDouble((Double) cst));
- } else if (cst instanceof String) {
- return b(1, Exprs.nString((String) cst));
- } else if (cst instanceof Type) {
- Type type = (Type) cst;
- int sort = type.getSort();
- if (sort == Type.OBJECT || sort == Type.ARRAY) {
- return b(1, Exprs.nType(type.getDescriptor()));
- } else if (sort == Type.METHOD) {
- throw new UnsupportedOperationException("Not supported yet.");
- } else {
- throw new IllegalArgumentException("Illegal LDC constant " + cst);
- }
- } else if (cst instanceof Handle) {
+ case ACONST_NULL:
+ return b(1, Exprs.nNull());
+ case ICONST_M1:
+ case ICONST_0:
+ case ICONST_1:
+ case ICONST_2:
+ case ICONST_3:
+ case ICONST_4:
+ case ICONST_5:
+ return b(1, Exprs.nInt(insn.getOpcode() - ICONST_0));
+ case LCONST_0:
+ case LCONST_1:
+ return b(2, Exprs.nLong(insn.getOpcode() - LCONST_0));
+ case FCONST_0:
+ case FCONST_1:
+ case FCONST_2:
+ return b(1, Exprs.nFloat(insn.getOpcode() - FCONST_0));
+ case DCONST_0:
+ case DCONST_1:
+ return b(2, Exprs.nDouble(insn.getOpcode() - DCONST_0));
+ case BIPUSH:
+ case SIPUSH:
+ return b(1, Exprs.nInt(((IntInsnNode) insn).operand));
+ case LDC:
+ Object cst = ((LdcInsnNode) insn).cst;
+ if (cst instanceof Integer) {
+ return b(1, Exprs.nInt((Integer) cst));
+ } else if (cst instanceof Float) {
+ return b(1, Exprs.nFloat((Float) cst));
+ } else if (cst instanceof Long) {
+ return b(2, Exprs.nLong((Long) cst));
+ } else if (cst instanceof Double) {
+ return b(2, Exprs.nDouble((Double) cst));
+ } else if (cst instanceof String) {
+ return b(1, Exprs.nString((String) cst));
+ } else if (cst instanceof Type) {
+ Type type = (Type) cst;
+ int sort = type.getSort();
+ if (sort == Type.OBJECT || sort == Type.ARRAY) {
+ return b(1, Exprs.nType(type.getDescriptor()));
+ } else if (sort == Type.METHOD) {
throw new UnsupportedOperationException("Not supported yet.");
} else {
throw new IllegalArgumentException("Illegal LDC constant " + cst);
}
- case JSR:
+ } else if (cst instanceof Handle) {
throw new UnsupportedOperationException("Not supported yet.");
- case GETSTATIC:
- FieldInsnNode fin = (FieldInsnNode) insn;
- return b(Type.getType(fin.desc).getSize(), Exprs.nStaticField("L" + fin.owner + ";", fin.name,
- fin.desc));
- case NEW:
- return b(1, Exprs.nNew("L" + ((TypeInsnNode) insn).desc + ";"));
- default:
- throw new Error("Internal error.");
+ } else {
+ throw new IllegalArgumentException("Illegal LDC constant " + cst);
+ }
+ case JSR:
+ throw new UnsupportedOperationException("Not supported yet.");
+ case GETSTATIC:
+ FieldInsnNode fin = (FieldInsnNode) insn;
+ return b(Type.getType(fin.desc).getSize(), Exprs.nStaticField("L" + fin.owner + ";", fin.name,
+ fin.desc));
+ case NEW:
+ return b(1, Exprs.nNew("L" + ((TypeInsnNode) insn).desc + ";"));
+ default:
+ throw new Error("Internal error.");
}
}
@Override
- public JvmValue copyOperation(AbstractInsnNode insn, JvmValue value) throws AnalyzerException {
+ public JvmValue copyOperation(AbstractInsnNode insn, JvmValue value) {
return b(value.getSize(), getLocal(value));
}
@@ -400,161 +427,161 @@ public JvmValue copyOperation(AbstractInsnNode insn, JvmValue value) throws Anal
public JvmValue unaryOperation(AbstractInsnNode insn, JvmValue value0) throws AnalyzerException {
Local local = value0 == null ? null : getLocal(value0);
switch (insn.getOpcode()) {
- case INEG:
- return b(1, Exprs.nNeg(local, "I"));
- case IINC:
- return b(1, Exprs.nAdd(local, Exprs.nInt(((IincInsnNode) insn).incr), "I"));
- case L2I:
- return b(1, Exprs.nCast(local, "J", "I"));
- case F2I:
- return b(1, Exprs.nCast(local, "F", "I"));
- case D2I:
- return b(1, Exprs.nCast(local, "D", "I"));
- case I2B:
- return b(1, Exprs.nCast(local, "I", "B"));
- case I2C:
- return b(1, Exprs.nCast(local, "I", "C"));
- case I2S:
- return b(1, Exprs.nCast(local, "I", "S"));
- case FNEG:
- return b(1, Exprs.nNeg(local, "F"));
- case I2F:
- return b(1, Exprs.nCast(local, "I", "F"));
- case L2F:
- return b(1, Exprs.nCast(local, "J", "F"));
- case D2F:
- return b(1, Exprs.nCast(local, "D", "F"));
- case LNEG:
- return b(2, Exprs.nNeg(local, "J"));
- case I2L:
- return b(2, Exprs.nCast(local, "I", "J"));
- case F2L:
- return b(2, Exprs.nCast(local, "F", "J"));
- case D2L:
- return b(2, Exprs.nCast(local, "D", "J"));
- case DNEG:
- return b(2, Exprs.nNeg(local, "D"));
- case I2D:
- return b(2, Exprs.nCast(local, "I", "D"));
- case L2D:
- return b(2, Exprs.nCast(local, "J", "D"));
- case F2D:
- return b(2, Exprs.nCast(local, "F", "D"));
- case IFEQ:
- emit(Stmts.nIf(Exprs.nEq(local, Exprs.nInt(0), "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IFNE:
- emit(Stmts.nIf(Exprs.nNe(local, Exprs.nInt(0), "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IFLT:
- emit(Stmts.nIf(Exprs.nLt(local, Exprs.nInt(0), "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IFGE:
- emit(Stmts.nIf(Exprs.nGe(local, Exprs.nInt(0), "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IFGT:
- emit(Stmts.nIf(Exprs.nGt(local, Exprs.nInt(0), "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IFLE:
- emit(Stmts.nIf(Exprs.nLe(local, Exprs.nInt(0), "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case TABLESWITCH: {
- TableSwitchInsnNode ts = (TableSwitchInsnNode) insn;
- LabelStmt targets[] = new LabelStmt[ts.labels.size()];
- for (int i = 0; i < ts.labels.size(); i++) {
- targets[i] = getLabel((LabelNode) ts.labels.get(i));
- }
- emit(Stmts.nTableSwitch(local, ts.min, targets, getLabel(ts.dflt)));
- return null;
+ case INEG:
+ return b(1, Exprs.nNeg(local, "I"));
+ case IINC:
+ return b(1, Exprs.nAdd(local, Exprs.nInt(((IincInsnNode) insn).incr), "I"));
+ case L2I:
+ return b(1, Exprs.nCast(local, "J", "I"));
+ case F2I:
+ return b(1, Exprs.nCast(local, "F", "I"));
+ case D2I:
+ return b(1, Exprs.nCast(local, "D", "I"));
+ case I2B:
+ return b(1, Exprs.nCast(local, "I", "B"));
+ case I2C:
+ return b(1, Exprs.nCast(local, "I", "C"));
+ case I2S:
+ return b(1, Exprs.nCast(local, "I", "S"));
+ case FNEG:
+ return b(1, Exprs.nNeg(local, "F"));
+ case I2F:
+ return b(1, Exprs.nCast(local, "I", "F"));
+ case L2F:
+ return b(1, Exprs.nCast(local, "J", "F"));
+ case D2F:
+ return b(1, Exprs.nCast(local, "D", "F"));
+ case LNEG:
+ return b(2, Exprs.nNeg(local, "J"));
+ case I2L:
+ return b(2, Exprs.nCast(local, "I", "J"));
+ case F2L:
+ return b(2, Exprs.nCast(local, "F", "J"));
+ case D2L:
+ return b(2, Exprs.nCast(local, "D", "J"));
+ case DNEG:
+ return b(2, Exprs.nNeg(local, "D"));
+ case I2D:
+ return b(2, Exprs.nCast(local, "I", "D"));
+ case L2D:
+ return b(2, Exprs.nCast(local, "J", "D"));
+ case F2D:
+ return b(2, Exprs.nCast(local, "F", "D"));
+ case IFEQ:
+ emit(Stmts.nIf(Exprs.nEq(local, Exprs.nInt(0), "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IFNE:
+ emit(Stmts.nIf(Exprs.nNe(local, Exprs.nInt(0), "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IFLT:
+ emit(Stmts.nIf(Exprs.nLt(local, Exprs.nInt(0), "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IFGE:
+ emit(Stmts.nIf(Exprs.nGe(local, Exprs.nInt(0), "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IFGT:
+ emit(Stmts.nIf(Exprs.nGt(local, Exprs.nInt(0), "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IFLE:
+ emit(Stmts.nIf(Exprs.nLe(local, Exprs.nInt(0), "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case TABLESWITCH: {
+ TableSwitchInsnNode ts = (TableSwitchInsnNode) insn;
+ LabelStmt[] targets = new LabelStmt[ts.labels.size()];
+ for (int i = 0; i < ts.labels.size(); i++) {
+ targets[i] = getLabel(ts.labels.get(i));
}
- case LOOKUPSWITCH: {
- LookupSwitchInsnNode ls = (LookupSwitchInsnNode) insn;
- LabelStmt targets[] = new LabelStmt[ls.labels.size()];
- int[] lookupValues = new int[ls.labels.size()];
- for (int i = 0; i < ls.labels.size(); i++) {
- targets[i] = getLabel((LabelNode) ls.labels.get(i));
- lookupValues[i] = (Integer) ls.keys.get(i);
- }
- emit(Stmts.nLookupSwitch(local, lookupValues, targets, getLabel(ls.dflt)));
- return null;
- }
- case IRETURN:
- case LRETURN:
- case FRETURN:
- case DRETURN:
- case ARETURN:
- // skip, move to returnOperation
- return null;
- case PUTSTATIC: {
- FieldInsnNode fin = (FieldInsnNode) insn;
- emit(Stmts.nAssign(Exprs.nStaticField("L" + fin.owner + ";", fin.name, fin.desc), local));
- return null;
- }
- case GETFIELD: {
- FieldInsnNode fin = (FieldInsnNode) insn;
- Type fieldType = Type.getType(fin.desc);
- return b(fieldType.getSize(), Exprs.nField(local, "L" + fin.owner + ";", fin.name, fin.desc));
+ emit(Stmts.nTableSwitch(local, ts.min, targets, getLabel(ts.dflt)));
+ return null;
+ }
+ case LOOKUPSWITCH: {
+ LookupSwitchInsnNode ls = (LookupSwitchInsnNode) insn;
+ LabelStmt[] targets = new LabelStmt[ls.labels.size()];
+ int[] lookupValues = new int[ls.labels.size()];
+ for (int i = 0; i < ls.labels.size(); i++) {
+ targets[i] = getLabel(ls.labels.get(i));
+ lookupValues[i] = ls.keys.get(i);
}
- case NEWARRAY:
- switch (((IntInsnNode) insn).operand) {
- case T_BOOLEAN:
- return b(1, Exprs.nNewArray("Z", local));
- case T_CHAR:
- return b(1, Exprs.nNewArray("C", local));
- case T_BYTE:
- return b(1, Exprs.nNewArray("B", local));
- case T_SHORT:
- return b(1, Exprs.nNewArray("S", local));
- case T_INT:
- return b(1, Exprs.nNewArray("I", local));
- case T_FLOAT:
- return b(1, Exprs.nNewArray("F", local));
- case T_DOUBLE:
- return b(1, Exprs.nNewArray("D", local));
- case T_LONG:
- return b(1, Exprs.nNewArray("D", local));
- default:
- throw new AnalyzerException(insn, "Invalid array type");
- }
- case ANEWARRAY:
- String desc = "L" + ((TypeInsnNode) insn).desc + ";";
- return b(1, Exprs.nNewArray(desc, local));
- case ARRAYLENGTH:
- return b(1, Exprs.nLength(local));
- case ATHROW:
- emit(Stmts.nThrow(local));
- return null;
- case CHECKCAST:
- String orgDesc = ((TypeInsnNode) insn).desc;
- desc = orgDesc.startsWith("[") ? orgDesc : ("L" + orgDesc + ";");
- return b(1, Exprs.nCheckCast(local, desc));
- case INSTANCEOF:
- return b(1, Exprs.nInstanceOf(local, "L" + ((TypeInsnNode) insn).desc + ";"));
- case MONITORENTER:
- emit(Stmts.nLock(local));
- return null;
- case MONITOREXIT:
- emit(Stmts.nUnLock(local));
- return null;
- case IFNULL:
- emit(Stmts.nIf(Exprs.nEq(local, Exprs.nNull(), "L"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IFNONNULL:
- emit(Stmts.nIf(Exprs.nNe(local, Exprs.nNull(), "L"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case GOTO: // special case
- emit(Stmts.nGoto(getLabel(((JumpInsnNode) insn).label)));
- return null;
+ emit(Stmts.nLookupSwitch(local, lookupValues, targets, getLabel(ls.dflt)));
+ return null;
+ }
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case ARETURN:
+ // skip, move to returnOperation
+ return null;
+ case PUTSTATIC: {
+ FieldInsnNode fin = (FieldInsnNode) insn;
+ emit(Stmts.nAssign(Exprs.nStaticField("L" + fin.owner + ";", fin.name, fin.desc), local));
+ return null;
+ }
+ case GETFIELD: {
+ FieldInsnNode fin = (FieldInsnNode) insn;
+ Type fieldType = Type.getType(fin.desc);
+ return b(fieldType.getSize(), Exprs.nField(local, "L" + fin.owner + ";", fin.name, fin.desc));
+ }
+ case NEWARRAY:
+ switch (((IntInsnNode) insn).operand) {
+ case T_BOOLEAN:
+ return b(1, Exprs.nNewArray("Z", local));
+ case T_CHAR:
+ return b(1, Exprs.nNewArray("C", local));
+ case T_BYTE:
+ return b(1, Exprs.nNewArray("B", local));
+ case T_SHORT:
+ return b(1, Exprs.nNewArray("S", local));
+ case T_INT:
+ return b(1, Exprs.nNewArray("I", local));
+ case T_FLOAT:
+ return b(1, Exprs.nNewArray("F", local));
+ case T_DOUBLE:
+ return b(1, Exprs.nNewArray("D", local));
+ case T_LONG:
+ return b(1, Exprs.nNewArray("D", local));
default:
- throw new Error("Internal error.");
+ throw new AnalyzerException(insn, "Invalid array type");
+ }
+ case ANEWARRAY:
+ String desc = "L" + ((TypeInsnNode) insn).desc + ";";
+ return b(1, Exprs.nNewArray(desc, local));
+ case ARRAYLENGTH:
+ return b(1, Exprs.nLength(local));
+ case ATHROW:
+ emit(Stmts.nThrow(local));
+ return null;
+ case CHECKCAST:
+ String orgDesc = ((TypeInsnNode) insn).desc;
+ desc = orgDesc.startsWith("[") ? orgDesc : ("L" + orgDesc + ";");
+ return b(1, Exprs.nCheckCast(local, desc));
+ case INSTANCEOF:
+ return b(1, Exprs.nInstanceOf(local, "L" + ((TypeInsnNode) insn).desc + ";"));
+ case MONITORENTER:
+ emit(Stmts.nLock(local));
+ return null;
+ case MONITOREXIT:
+ emit(Stmts.nUnLock(local));
+ return null;
+ case IFNULL:
+ emit(Stmts.nIf(Exprs.nEq(local, Exprs.nNull(), "L"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IFNONNULL:
+ emit(Stmts.nIf(Exprs.nNe(local, Exprs.nNull(), "L"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case GOTO: // special case
+ emit(Stmts.nGoto(getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ default:
+ throw new Error("Internal error.");
}
}
@@ -565,185 +592,183 @@ JvmValue b(int size, com.googlecode.dex2jar.ir.expr.Value value) {
}
@Override
- public JvmValue binaryOperation(AbstractInsnNode insn, JvmValue value10, JvmValue value20)
- throws AnalyzerException {
+ public JvmValue binaryOperation(AbstractInsnNode insn, JvmValue value10, JvmValue value20) {
Local local1 = getLocal(value10);
Local local2 = getLocal(value20);
switch (insn.getOpcode()) {
- case IALOAD:
- return b(1, Exprs.nArray(local1, local2, "I"));
- case BALOAD:
- return b(1, Exprs.nArray(local1, local2, "B"));
- case CALOAD:
- return b(1, Exprs.nArray(local1, local2, "C"));
- case SALOAD:
- return b(1, Exprs.nArray(local1, local2, "S"));
- case FALOAD:
- return b(1, Exprs.nArray(local1, local2, "F"));
- case AALOAD:
- return b(1, Exprs.nArray(local1, local2, "L"));
- case DALOAD:
- return b(1, Exprs.nArray(local1, local2, "D"));
- case LALOAD:
- return b(1, Exprs.nArray(local1, local2, "J"));
- case IADD:
- return b(1, Exprs.nAdd(local1, local2, "I"));
- case ISUB:
- return b(1, Exprs.nSub(local1, local2, "I"));
- case IMUL:
- return b(1, Exprs.nMul(local1, local2, "I"));
- case IDIV:
- return b(1, Exprs.nDiv(local1, local2, "I"));
- case IREM:
- return b(1, Exprs.nRem(local1, local2, "I"));
- case ISHL:
- return b(1, Exprs.nShl(local1, local2, "I"));
- case ISHR:
- return b(1, Exprs.nShr(local1, local2, "I"));
- case IUSHR:
- return b(1, Exprs.nUshr(local1, local2, "I"));
- case IAND:
- return b(1, Exprs.nAnd(local1, local2, "I"));
- case IOR:
- return b(1, Exprs.nOr(local1, local2, "I"));
- case IXOR:
- return b(1, Exprs.nXor(local1, local2, "I"));
- case FADD:
- return b(1, Exprs.nAdd(local1, local2, "F"));
- case FSUB:
- return b(1, Exprs.nSub(local1, local2, "F"));
- case FMUL:
- return b(1, Exprs.nMul(local1, local2, "F"));
- case FDIV:
- return b(1, Exprs.nDiv(local1, local2, "F"));
- case FREM:
- return b(1, Exprs.nRem(local1, local2, "F"));
- case LADD:
- return b(2, Exprs.nAdd(local1, local2, "J"));
- case LSUB:
- return b(2, Exprs.nSub(local1, local2, "J"));
- case LMUL:
- return b(2, Exprs.nMul(local1, local2, "J"));
- case LDIV:
- return b(2, Exprs.nDiv(local1, local2, "J"));
- case LREM:
- return b(2, Exprs.nRem(local1, local2, "J"));
- case LSHL:
- return b(2, Exprs.nShl(local1, local2, "J"));
- case LSHR:
- return b(2, Exprs.nShr(local1, local2, "J"));
- case LUSHR:
- return b(2, Exprs.nUshr(local1, local2, "J"));
- case LAND:
- return b(2, Exprs.nAnd(local1, local2, "J"));
- case LOR:
- return b(2, Exprs.nOr(local1, local2, "J"));
- case LXOR:
- return b(2, Exprs.nXor(local1, local2, "J"));
-
- case DADD:
- return b(2, Exprs.nAdd(local1, local2, "D"));
- case DSUB:
- return b(2, Exprs.nSub(local1, local2, "D"));
- case DMUL:
- return b(2, Exprs.nMul(local1, local2, "D"));
- case DDIV:
- return b(2, Exprs.nDiv(local1, local2, "D"));
- case DREM:
- return b(2, Exprs.nRem(local1, local2, "D"));
-
- case LCMP:
- return b(2, Exprs.nLCmp(local1, local2));
- case FCMPL:
- return b(1, Exprs.nFCmpl(local1, local2));
- case FCMPG:
- return b(1, Exprs.nFCmpg(local1, local2));
- case DCMPL:
- return b(2, Exprs.nDCmpl(local1, local2));
- case DCMPG:
- return b(2, Exprs.nDCmpg(local1, local2));
-
- case IF_ICMPEQ:
- emit(Stmts.nIf(Exprs.nEq(local1, local2, "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IF_ICMPNE:
- emit(Stmts.nIf(Exprs.nNe(local1, local2, "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IF_ICMPLT:
- emit(Stmts.nIf(Exprs.nLt(local1, local2, "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IF_ICMPGE:
- emit(Stmts.nIf(Exprs.nGe(local1, local2, "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IF_ICMPGT:
- emit(Stmts.nIf(Exprs.nGt(local1, local2, "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IF_ICMPLE:
- emit(Stmts.nIf(Exprs.nLe(local1, local2, "I"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IF_ACMPEQ:
- emit(Stmts.nIf(Exprs.nEq(local1, local2, "L"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case IF_ACMPNE:
- emit(Stmts.nIf(Exprs.nNe(local1, local2, "L"),
- getLabel(((JumpInsnNode) insn).label)));
- return null;
- case PUTFIELD:
- FieldInsnNode fin = (FieldInsnNode) insn;
- emit(Stmts.nAssign(Exprs.nField(local1, "L" + fin.owner + ";", fin.name, fin.desc), local2));
- return null;
- default:
- throw new Error("Internal error.");
+ case IALOAD:
+ return b(1, Exprs.nArray(local1, local2, "I"));
+ case BALOAD:
+ return b(1, Exprs.nArray(local1, local2, "B"));
+ case CALOAD:
+ return b(1, Exprs.nArray(local1, local2, "C"));
+ case SALOAD:
+ return b(1, Exprs.nArray(local1, local2, "S"));
+ case FALOAD:
+ return b(1, Exprs.nArray(local1, local2, "F"));
+ case AALOAD:
+ return b(1, Exprs.nArray(local1, local2, "L"));
+ case DALOAD:
+ return b(1, Exprs.nArray(local1, local2, "D"));
+ case LALOAD:
+ return b(1, Exprs.nArray(local1, local2, "J"));
+ case IADD:
+ return b(1, Exprs.nAdd(local1, local2, "I"));
+ case ISUB:
+ return b(1, Exprs.nSub(local1, local2, "I"));
+ case IMUL:
+ return b(1, Exprs.nMul(local1, local2, "I"));
+ case IDIV:
+ return b(1, Exprs.nDiv(local1, local2, "I"));
+ case IREM:
+ return b(1, Exprs.nRem(local1, local2, "I"));
+ case ISHL:
+ return b(1, Exprs.nShl(local1, local2, "I"));
+ case ISHR:
+ return b(1, Exprs.nShr(local1, local2, "I"));
+ case IUSHR:
+ return b(1, Exprs.nUshr(local1, local2, "I"));
+ case IAND:
+ return b(1, Exprs.nAnd(local1, local2, "I"));
+ case IOR:
+ return b(1, Exprs.nOr(local1, local2, "I"));
+ case IXOR:
+ return b(1, Exprs.nXor(local1, local2, "I"));
+ case FADD:
+ return b(1, Exprs.nAdd(local1, local2, "F"));
+ case FSUB:
+ return b(1, Exprs.nSub(local1, local2, "F"));
+ case FMUL:
+ return b(1, Exprs.nMul(local1, local2, "F"));
+ case FDIV:
+ return b(1, Exprs.nDiv(local1, local2, "F"));
+ case FREM:
+ return b(1, Exprs.nRem(local1, local2, "F"));
+ case LADD:
+ return b(2, Exprs.nAdd(local1, local2, "J"));
+ case LSUB:
+ return b(2, Exprs.nSub(local1, local2, "J"));
+ case LMUL:
+ return b(2, Exprs.nMul(local1, local2, "J"));
+ case LDIV:
+ return b(2, Exprs.nDiv(local1, local2, "J"));
+ case LREM:
+ return b(2, Exprs.nRem(local1, local2, "J"));
+ case LSHL:
+ return b(2, Exprs.nShl(local1, local2, "J"));
+ case LSHR:
+ return b(2, Exprs.nShr(local1, local2, "J"));
+ case LUSHR:
+ return b(2, Exprs.nUshr(local1, local2, "J"));
+ case LAND:
+ return b(2, Exprs.nAnd(local1, local2, "J"));
+ case LOR:
+ return b(2, Exprs.nOr(local1, local2, "J"));
+ case LXOR:
+ return b(2, Exprs.nXor(local1, local2, "J"));
+
+ case DADD:
+ return b(2, Exprs.nAdd(local1, local2, "D"));
+ case DSUB:
+ return b(2, Exprs.nSub(local1, local2, "D"));
+ case DMUL:
+ return b(2, Exprs.nMul(local1, local2, "D"));
+ case DDIV:
+ return b(2, Exprs.nDiv(local1, local2, "D"));
+ case DREM:
+ return b(2, Exprs.nRem(local1, local2, "D"));
+
+ case LCMP:
+ return b(2, Exprs.nLCmp(local1, local2));
+ case FCMPL:
+ return b(1, Exprs.nFCmpl(local1, local2));
+ case FCMPG:
+ return b(1, Exprs.nFCmpg(local1, local2));
+ case DCMPL:
+ return b(2, Exprs.nDCmpl(local1, local2));
+ case DCMPG:
+ return b(2, Exprs.nDCmpg(local1, local2));
+
+ case IF_ICMPEQ:
+ emit(Stmts.nIf(Exprs.nEq(local1, local2, "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IF_ICMPNE:
+ emit(Stmts.nIf(Exprs.nNe(local1, local2, "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IF_ICMPLT:
+ emit(Stmts.nIf(Exprs.nLt(local1, local2, "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IF_ICMPGE:
+ emit(Stmts.nIf(Exprs.nGe(local1, local2, "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IF_ICMPGT:
+ emit(Stmts.nIf(Exprs.nGt(local1, local2, "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IF_ICMPLE:
+ emit(Stmts.nIf(Exprs.nLe(local1, local2, "I"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IF_ACMPEQ:
+ emit(Stmts.nIf(Exprs.nEq(local1, local2, "L"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case IF_ACMPNE:
+ emit(Stmts.nIf(Exprs.nNe(local1, local2, "L"),
+ getLabel(((JumpInsnNode) insn).label)));
+ return null;
+ case PUTFIELD:
+ FieldInsnNode fin = (FieldInsnNode) insn;
+ emit(Stmts.nAssign(Exprs.nField(local1, "L" + fin.owner + ";", fin.name, fin.desc), local2));
+ return null;
+ default:
+ throw new Error("Internal error.");
}
}
@Override
- public JvmValue ternaryOperation(AbstractInsnNode insn, JvmValue value1, JvmValue value2, JvmValue value3)
- throws AnalyzerException {
+ public JvmValue ternaryOperation(AbstractInsnNode insn, JvmValue value1, JvmValue value2, JvmValue value3) {
Local local1 = getLocal(value1);
Local local2 = getLocal(value2);
Local local3 = getLocal(value3);
switch (insn.getOpcode()) {
- case IASTORE:
- emit(Stmts.nAssign(Exprs.nArray(local1, local2, "I"),
- local3));
- break;
- case LASTORE:
- emit(Stmts.nAssign(Exprs.nArray(local1, local2, "J"),
- local3));
- break;
- case FASTORE:
- emit(Stmts.nAssign(Exprs.nArray(local1, local2, "F"),
- local3));
- break;
- case DASTORE:
- emit(Stmts.nAssign(Exprs.nArray(local1, local2, "D"),
- local3));
- break;
- case AASTORE:
- emit(Stmts.nAssign(Exprs.nArray(local1, local2, "L"),
- local3));
- break;
- case BASTORE:
- emit(Stmts.nAssign(Exprs.nArray(local1, local2, "B"),
- local3));
- break;
- case CASTORE:
- emit(Stmts.nAssign(Exprs.nArray(local1, local2, "C"),
- local3));
- break;
- case SASTORE:
- emit(Stmts.nAssign(Exprs.nArray(local1, local2, "S"),
- local3));
- break;
+ case IASTORE:
+ emit(Stmts.nAssign(Exprs.nArray(local1, local2, "I"),
+ local3));
+ break;
+ case LASTORE:
+ emit(Stmts.nAssign(Exprs.nArray(local1, local2, "J"),
+ local3));
+ break;
+ case FASTORE:
+ emit(Stmts.nAssign(Exprs.nArray(local1, local2, "F"),
+ local3));
+ break;
+ case DASTORE:
+ emit(Stmts.nAssign(Exprs.nArray(local1, local2, "D"),
+ local3));
+ break;
+ case AASTORE:
+ emit(Stmts.nAssign(Exprs.nArray(local1, local2, "L"),
+ local3));
+ break;
+ case BASTORE:
+ emit(Stmts.nAssign(Exprs.nArray(local1, local2, "B"),
+ local3));
+ break;
+ case CASTORE:
+ emit(Stmts.nAssign(Exprs.nArray(local1, local2, "C"),
+ local3));
+ break;
+ case SASTORE:
+ emit(Stmts.nAssign(Exprs.nArray(local1, local2, "S"),
+ local3));
+ break;
}
return null;
@@ -758,9 +783,10 @@ public String[] toDescArray(Type[] ts) {
}
@Override
- public JvmValue naryOperation(AbstractInsnNode insn, List extends JvmValue> xvalues) throws AnalyzerException {
+ public JvmValue naryOperation(AbstractInsnNode insn, List extends JvmValue> xvalues) {
- com.googlecode.dex2jar.ir.expr.Value values[] = new com.googlecode.dex2jar.ir.expr.Value[xvalues.size()];
+ com.googlecode.dex2jar.ir.expr.Value[] values =
+ new com.googlecode.dex2jar.ir.expr.Value[xvalues.size()];
for (int i = 0; i < xvalues.size(); i++) {
values[i] = getLocal(xvalues.get(i));
}
@@ -771,22 +797,22 @@ public JvmValue naryOperation(AbstractInsnNode insn, List extends JvmValue> xv
com.googlecode.dex2jar.ir.expr.Value v = null;
String ret = Type.getReturnType(mi.desc).getDescriptor();
String owner = "L" + mi.owner + ";";
- String ps[] = toDescArray(Type.getArgumentTypes(mi.desc));
+ String[] ps = toDescArray(Type.getArgumentTypes(mi.desc));
switch (insn.getOpcode()) {
- case INVOKEVIRTUAL:
- v = Exprs.nInvokeVirtual(values, owner, mi.name, ps, ret);
- break;
- case INVOKESPECIAL:
- v = Exprs.nInvokeSpecial(values, owner, mi.name, ps, ret);
- break;
- case INVOKESTATIC:
- v = Exprs.nInvokeStatic(values, owner, mi.name, ps, ret);
- break;
- case INVOKEINTERFACE:
- v = Exprs.nInvokeInterface(values, owner, mi.name, ps, ret);
- break;
- case INVOKEDYNAMIC:
- throw new UnsupportedOperationException("Not supported yet.");
+ case INVOKEVIRTUAL:
+ v = Exprs.nInvokeVirtual(values, owner, mi.name, ps, ret);
+ break;
+ case INVOKESPECIAL:
+ v = Exprs.nInvokeSpecial(values, owner, mi.name, ps, ret);
+ break;
+ case INVOKESTATIC:
+ v = Exprs.nInvokeStatic(values, owner, mi.name, ps, ret);
+ break;
+ case INVOKEINTERFACE:
+ v = Exprs.nInvokeInterface(values, owner, mi.name, ps, ret);
+ break;
+ case INVOKEDYNAMIC:
+ throw new UnsupportedOperationException("Not supported yet.");
}
if ("V".equals(ret)) {
emit(Stmts.nVoidInvoke(v));
@@ -803,18 +829,18 @@ public JvmValue merge(JvmValue v, JvmValue w) {
}
@Override
- public void returnOperation(AbstractInsnNode insn, JvmValue value, JvmValue expected) throws AnalyzerException {
+ public void returnOperation(AbstractInsnNode insn, JvmValue value, JvmValue expected) {
switch (insn.getOpcode()) {
- case IRETURN:
- case LRETURN:
- case FRETURN:
- case DRETURN:
- case ARETURN:
- emit(Stmts.nReturn(getLocal(value)));
- break;
- case RETURN:
- emit(Stmts.nReturnVoid());
- break;
+ case IRETURN:
+ case LRETURN:
+ case FRETURN:
+ case DRETURN:
+ case ARETURN:
+ emit(Stmts.nReturn(getLocal(value)));
+ break;
+ case RETURN:
+ emit(Stmts.nReturnVoid());
+ break;
}
}
@@ -856,7 +882,7 @@ private void initParentCount(int[] parentCount) {
// can't continue
} else {
AbstractInsnNode next = p.getNext();
- if(next!=null) {
+ if (next != null) {
parentCount[insnList.indexOf(p.getNext())]++;
}
}
@@ -950,11 +976,11 @@ private JvmFrame initFirstFrame(MethodNode methodNode, IrMethod target) {
private int sizeOfType(String arg) {
switch (arg.charAt(0)) {
- case 'J':
- case 'D':
- return 2;
- default:
- return 1;
+ case 'J':
+ case 'D':
+ return 2;
+ default:
+ return 1;
}
}
diff --git a/dex-translator/src/main/java/com/googlecode/d2j/dex/BaseDexExceptionHandler.java b/dex-translator/src/main/java/com/googlecode/d2j/dex/BaseDexExceptionHandler.java
index 5c750f023..2e1189046 100644
--- a/dex-translator/src/main/java/com/googlecode/d2j/dex/BaseDexExceptionHandler.java
+++ b/dex-translator/src/main/java/com/googlecode/d2j/dex/BaseDexExceptionHandler.java
@@ -1,13 +1,13 @@
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2012 Panxiaobo
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,11 +18,10 @@
import com.googlecode.d2j.Method;
import com.googlecode.d2j.node.DexMethodNode;
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
import java.io.PrintWriter;
import java.io.StringWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
public class BaseDexExceptionHandler implements DexExceptionHandler {
@Override
@@ -41,7 +40,8 @@ public void handleMethodTranslateException(Method method, DexMethodNode methodNo
mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
mv.visitInsn(Opcodes.DUP);
mv.visitLdcInsn(msg);
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "", "(Ljava/lang/String;)V", false);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "", "(Ljava/lang/String;)V",
+ false);
mv.visitInsn(Opcodes.ATHROW);
}
}
diff --git a/dex-translator/src/main/java/com/googlecode/d2j/dex/ClassVisitorFactory.java b/dex-translator/src/main/java/com/googlecode/d2j/dex/ClassVisitorFactory.java
index 3a0f9b51a..47940e51c 100644
--- a/dex-translator/src/main/java/com/googlecode/d2j/dex/ClassVisitorFactory.java
+++ b/dex-translator/src/main/java/com/googlecode/d2j/dex/ClassVisitorFactory.java
@@ -5,9 +5,7 @@
public interface ClassVisitorFactory {
/**
- *
- * @param classInternalName
- * class name
+ * @param classInternalName class name
* @return a ClassVisitor, to generate validate .class file, ClassWriter.COMPUTE_MAXS is required for ClassWriter
*/
ClassVisitor create(String classInternalName);
diff --git a/dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java b/dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java
index d9f09d53a..1e83c2bb1 100644
--- a/dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java
+++ b/dex-translator/src/main/java/com/googlecode/d2j/dex/Dex2Asm.java
@@ -1,17 +1,53 @@
package com.googlecode.d2j.dex;
-import java.util.*;
-
+import com.googlecode.d2j.DexConstants;
+import com.googlecode.d2j.DexType;
+import com.googlecode.d2j.Field;
+import com.googlecode.d2j.Method;
+import com.googlecode.d2j.MethodHandle;
+import com.googlecode.d2j.Proto;
+import com.googlecode.d2j.Visibility;
import com.googlecode.d2j.converter.Dex2IRConverter;
-import org.objectweb.asm.*;
-import org.objectweb.asm.tree.InnerClassNode;
-
-import com.googlecode.d2j.*;
import com.googlecode.d2j.converter.IR2JConverter;
-import com.googlecode.d2j.node.*;
+import com.googlecode.d2j.node.DexAnnotationNode;
+import com.googlecode.d2j.node.DexClassNode;
+import com.googlecode.d2j.node.DexFieldNode;
+import com.googlecode.d2j.node.DexFileNode;
+import com.googlecode.d2j.node.DexMethodNode;
import com.googlecode.dex2jar.ir.IrMethod;
-import com.googlecode.dex2jar.ir.ts.*;
+import com.googlecode.dex2jar.ir.ts.AggTransformer;
+import com.googlecode.dex2jar.ir.ts.CleanLabel;
+import com.googlecode.dex2jar.ir.ts.DeadCodeTransformer;
+import com.googlecode.dex2jar.ir.ts.EndRemover;
+import com.googlecode.dex2jar.ir.ts.ExceptionHandlerTrim;
+import com.googlecode.dex2jar.ir.ts.Ir2JRegAssignTransformer;
+import com.googlecode.dex2jar.ir.ts.MultiArrayTransformer;
+import com.googlecode.dex2jar.ir.ts.NewTransformer;
+import com.googlecode.dex2jar.ir.ts.NpeTransformer;
+import com.googlecode.dex2jar.ir.ts.RemoveConstantFromSSA;
+import com.googlecode.dex2jar.ir.ts.RemoveLocalFromSSA;
+import com.googlecode.dex2jar.ir.ts.TypeTransformer;
+import com.googlecode.dex2jar.ir.ts.UnSSATransformer;
+import com.googlecode.dex2jar.ir.ts.VoidInvokeTransformer;
+import com.googlecode.dex2jar.ir.ts.ZeroTransformer;
import com.googlecode.dex2jar.ir.ts.array.FillArrayTransformer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.tree.InnerClassNode;
public class Dex2Asm {
@@ -238,7 +274,7 @@ private static MethodVisitor collectBasicMethodInfo(DexMethodNode methodNode, Cl
}
}
}
- break;
+ break;
case DexConstants.ANNOTATION_SIGNATURE_TYPE: {
Object[] strs = (Object[]) findAnnotationAttribute(ann, "value");
if (strs != null) {
@@ -249,7 +285,7 @@ private static MethodVisitor collectBasicMethodInfo(DexMethodNode methodNode, Cl
signature = sb.toString();
}
}
- break;
+ break;
}
}
}
@@ -284,7 +320,7 @@ protected static Map collectClzInfo(DexFileNode fileNode) {
enclosingClass.addInner(clz);
}
- break;
+ break;
case DexConstants.ANNOTATION_ENCLOSING_METHOD_TYPE: {
Method m = (Method) findAnnotationAttribute(ann, "value");
Clz enclosingClass = get(classes, m.getOwner());
@@ -292,7 +328,7 @@ protected static Map collectClzInfo(DexFileNode fileNode) {
clz.enclosingMethod = m;
enclosingClass.addInner(clz);
}
- break;
+ break;
case DexConstants.ANNOTATION_INNER_CLASS_TYPE: {
for (DexAnnotationNode.Item it : ann.items) {
if ("accessFlags".equals(it.name)) {
@@ -302,7 +338,7 @@ protected static Map collectClzInfo(DexFileNode fileNode) {
}
}
}
- break;
+ break;
case DexConstants.ANNOTATION_MEMBER_CLASSES_TYPE: {
Object[] ts = (Object[]) findAnnotationAttribute(ann, "value");
for (Object v : ts) {
@@ -312,7 +348,7 @@ protected static Map collectClzInfo(DexFileNode fileNode) {
inner.enclosingClass = clz;
}
}
- break;
+ break;
}
}
}
@@ -328,8 +364,9 @@ public void convertClass(DexClassNode classNode, ClassVisitorFactory cvf, DexFil
public void convertClass(DexClassNode classNode, ClassVisitorFactory cvf) {
convertClass(DexConstants.DEX_035, classNode, cvf);
}
+
public void convertClass(int dexVersion, DexClassNode classNode, ClassVisitorFactory cvf) {
- convertClass(dexVersion, classNode, cvf, new HashMap());
+ convertClass(dexVersion, classNode, cvf, new HashMap<>());
}
private static boolean isJavaIdentifier(String str) {
@@ -350,10 +387,14 @@ private static boolean isJavaIdentifier(String str) {
public void convertClass(DexClassNode classNode, ClassVisitorFactory cvf, Map classes) {
convertClass(DexConstants.DEX_035, classNode, cvf, classes);
}
- public void convertClass(DexFileNode dfn, DexClassNode classNode, ClassVisitorFactory cvf, Map classes) {
+
+ public void convertClass(DexFileNode dfn, DexClassNode classNode, ClassVisitorFactory cvf,
+ Map classes) {
convertClass(dfn.dexVersion, classNode, cvf, classes);
}
- public void convertClass(int dexVersion, DexClassNode classNode, ClassVisitorFactory cvf, Map classes) {
+
+ public void convertClass(int dexVersion, DexClassNode classNode, ClassVisitorFactory cvf,
+ Map classes) {
ClassVisitor cv = cvf.create(toInternalName(classNode.className));
if (cv == null) {
return;
@@ -376,7 +417,7 @@ public void convertClass(int dexVersion, DexClassNode classNode, ClassVisitorFac
signature = sb.toString();
}
}
- break;
+ break;
}
}
}
@@ -419,7 +460,7 @@ public void convertClass(int dexVersion, DexClassNode classNode, ClassVisitorFac
}
searchEnclosing(clzInfo, innerClassNodes);
}
- Collections.sort(innerClassNodes, INNER_CLASS_NODE_COMPARATOR);
+ innerClassNodes.sort(INNER_CLASS_NODE_COMPARATOR);
for (InnerClassNode icn : innerClassNodes) {
if (icn.innerName != null && !isJavaIdentifier(icn.innerName)) {
System.err.println("WARN: ignored invalid inner class name " + ", treat as anonymous inner class.");
@@ -509,27 +550,34 @@ public static Object convertConstantValue(Object ele) {
switch (mh.getType()) {
case MethodHandle.INSTANCE_GET:
case MethodHandle.STATIC_GET:
- h = new Handle(Opcodes.H_GETFIELD, toInternalName(mh.getField().getOwner()), mh.getField().getName(), mh.getField().getType(), false);
- break;
+ h = new Handle(Opcodes.H_GETFIELD, toInternalName(mh.getField().getOwner()), mh.getField().getName(),
+ mh.getField().getType(), false);
+ break;
case MethodHandle.INSTANCE_PUT:
case MethodHandle.STATIC_PUT:
- h = new Handle(Opcodes.H_PUTFIELD, toInternalName(mh.getField().getOwner()), mh.getField().getName(), mh.getField().getType(), false);
- break;
+ h = new Handle(Opcodes.H_PUTFIELD, toInternalName(mh.getField().getOwner()), mh.getField().getName(),
+ mh.getField().getType(), false);
+ break;
case MethodHandle.INVOKE_INSTANCE:
- h = new Handle(Opcodes.H_INVOKEVIRTUAL, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc(), false);
- break;
- case MethodHandle.INVOKE_STATIC:
- h = new Handle(Opcodes.H_INVOKESTATIC, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc(), false);
- break;
- case MethodHandle.INVOKE_CONSTRUCTOR:
- h = new Handle(Opcodes.H_NEWINVOKESPECIAL, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc(), false);
- break;
- case MethodHandle.INVOKE_DIRECT:
- h = new Handle(Opcodes.H_INVOKESPECIAL, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc(), false);
- break;
- case MethodHandle.INVOKE_INTERFACE:
- h = new Handle(Opcodes.H_INVOKEINTERFACE, toInternalName(mh.getMethod().getOwner()), mh.getMethod().getName(), mh.getMethod().getDesc(), true);
- break;
+ h = new Handle(Opcodes.H_INVOKEVIRTUAL, toInternalName(mh.getMethod().getOwner()),
+ mh.getMethod().getName(), mh.getMethod().getDesc(), false);
+ break;
+ case MethodHandle.INVOKE_STATIC:
+ h = new Handle(Opcodes.H_INVOKESTATIC, toInternalName(mh.getMethod().getOwner()),
+ mh.getMethod().getName(), mh.getMethod().getDesc(), false);
+ break;
+ case MethodHandle.INVOKE_CONSTRUCTOR:
+ h = new Handle(Opcodes.H_NEWINVOKESPECIAL, toInternalName(mh.getMethod().getOwner()),
+ mh.getMethod().getName(), mh.getMethod().getDesc(), false);
+ break;
+ case MethodHandle.INVOKE_DIRECT:
+ h = new Handle(Opcodes.H_INVOKESPECIAL, toInternalName(mh.getMethod().getOwner()),
+ mh.getMethod().getName(), mh.getMethod().getDesc(), false);
+ break;
+ case MethodHandle.INVOKE_INTERFACE:
+ h = new Handle(Opcodes.H_INVOKEINTERFACE, toInternalName(mh.getMethod().getOwner()),
+ mh.getMethod().getName(), mh.getMethod().getDesc(), true);
+ break;
}
ele = h;
} else if (ele instanceof Proto) {
@@ -645,7 +693,7 @@ public void optimize(IrMethod irMethod) {
/**
* For structure
- *
+ *
*
* class A {
* class B {
@@ -654,17 +702,16 @@ public void optimize(IrMethod irMethod) {
* }
* }
*
- *
+ *
* this method will add
- *
+ *
*
* InnerClass Outter
* A$B$WeAreHere A$B
* A$B A
*
- *
+ *
* to WeAreHere.class
- *
*/
private static void searchEnclosing(Clz clz, List innerClassNodes) {
Set visitedClz = new HashSet<>();
@@ -692,28 +739,26 @@ private static void searchEnclosing(Clz clz, List innerClassNode
/**
* For structure
- *
+ *
*
* class WeAreHere {
* class A {
* class B {
- *
+ *
* }
* }
* }
*
- *
+ *
* this method will add
- *
+ *
*
* InnerClass Outter
* WeAreHere$A$B WeAreHere$A
* WeAreHere$A WeAreHere
*
- *
+ *
* to WeAreHere.class
- *
- * @param clz
*/
private static void searchInnerClass(Clz clz, List innerClassNodes, String className) {
Set visited = new HashSet<>();
@@ -741,11 +786,7 @@ private static void searchInnerClass(Clz clz, List innerClassNod
}
}
- private static final Comparator INNER_CLASS_NODE_COMPARATOR = new Comparator