From a26d7b5a8b45ebe5f0062440e1a8c17e609e29aa Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Fri, 19 Dec 2014 23:40:35 +0100 Subject: [PATCH 01/17] Removed some warnings about collections without type specifiers. --- jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java | 2 +- jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java | 2 +- jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java | 10 +++++----- jadx-gui/src/main/java/jadx/gui/utils/Link.java | 1 + 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java index daedd1ca3..50220a83e 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java @@ -10,7 +10,7 @@ import javax.swing.Icon; import javax.swing.tree.DefaultMutableTreeNode; public abstract class JNode extends DefaultMutableTreeNode { - + private static final long serialVersionUID = 1337L; // TODO: Create your own serialvers with serialver/eclipse public static JNode makeFrom(JavaNode node) { if (node instanceof JavaClass) { JClass p = (JClass) makeFrom(node.getDeclaringClass()); diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java index a20631a32..2df2355db 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java @@ -124,7 +124,7 @@ public class JRoot extends JNode { } public JClass searchClassInTree(JClass node) { - Enumeration en = this.breadthFirstEnumeration(); + Enumeration en = this.breadthFirstEnumeration(); while (en.hasMoreElements()) { Object obj = en.nextElement(); if (node.equals(obj)) { diff --git a/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java index 96a01eee2..8bd8874fb 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java @@ -71,7 +71,7 @@ public class SearchDialog extends JDialog { private JTextField searchField; private ResultsModel resultsModel; - private JList resultsList; + private JList resultsList; private JProgressBar busyBar; public SearchDialog(Frame owner, TabbedPane tabbedPane, JadxWrapper wrapper) { @@ -171,7 +171,7 @@ public class SearchDialog extends JDialog { } } - private static class ResultsModel extends DefaultListModel { + private static class ResultsModel extends DefaultListModel { private static final long serialVersionUID = -7821286846923903208L; private void setResults(List results) { @@ -186,7 +186,7 @@ public class SearchDialog extends JDialog { } } - private static class ResultsCellRenderer implements ListCellRenderer { + private static class ResultsCellRenderer implements ListCellRenderer { private final Color selectedBackground; private final Color selectedForeground; @@ -197,7 +197,7 @@ public class SearchDialog extends JDialog { } @Override - public Component getListCellRendererComponent(JList list, + public Component getListCellRendererComponent(JList list, Object obj, int index, boolean isSelected, boolean cellHasFocus) { if (!(obj instanceof JNode)) { return null; @@ -244,7 +244,7 @@ public class SearchDialog extends JDialog { codeChBox.setEnabled(false); resultsModel = new ResultsModel(); - resultsList = new JList(resultsModel); + resultsList = new JList(resultsModel); resultsList.setCellRenderer(new ResultsCellRenderer()); resultsList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { diff --git a/jadx-gui/src/main/java/jadx/gui/utils/Link.java b/jadx-gui/src/main/java/jadx/gui/utils/Link.java index 033b59e93..cc29cc60f 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/Link.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/Link.java @@ -18,6 +18,7 @@ import org.slf4j.LoggerFactory; import static java.awt.Desktop.Action; public class Link extends JLabel implements MouseListener { + private static final long serialVersionUID = 0L; // TODO: Generate random serialvers with serialver/eclipse private static final Logger LOG = LoggerFactory.getLogger(JLabel.class); private String url; From e01789bb0d6577fee836f937b979d2cb01a9b3ad Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Sun, 21 Dec 2014 22:05:44 +0100 Subject: [PATCH 02/17] Added first implementation of the AndroidManifest XML Parser --- jadx-cli/src/main/java/jadx/cli/JadxCLI.java | 5 + .../jadx/core/xmlgen/BinaryXMLParser.java | 187 ++++++++++++++++++ 2 files changed, 192 insertions(+) create mode 100644 jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java index f9ddd2561..5eaa24ca2 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java @@ -8,10 +8,15 @@ import java.io.File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import jadx.core.xmlgen.BinaryXMLParser; + public class JadxCLI { private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class); public static void main(String[] args) throws JadxException { + BinaryXMLParser bxp = new BinaryXMLParser(args[0]); + bxp.parse(); + System.exit(4); try { JadxCLIArgs jadxArgs = new JadxCLIArgs(); if (processArgs(jadxArgs, args)) { diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java new file mode 100644 index 000000000..a975667a1 --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -0,0 +1,187 @@ +package jadx.core.xmlgen; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +public class BinaryXMLParser { + private byte[] bytes; + private String[] strings; + private int count; + private String nsPrefix="ERROR"; + public BinaryXMLParser(String xmlfilepath) { + System.out.println(xmlfilepath); + File manifest = new File(xmlfilepath); + if(null==manifest) die("null==manifest"); + bytes = new byte[(int) manifest.length()]; + try { + InputStream is = null; + try { + is = new BufferedInputStream(new FileInputStream(manifest)); + int total = 0; + while(total < bytes.length) { + int remain = bytes.length - total; + int read = is.read(bytes, total, remain); + if(read > 0) total += read; + } + } finally { + is.close(); + } + } catch(FileNotFoundException fnfe) { die("FILE NOT FOUND"); } + catch(IOException ioe) { die("IOE"); } + count=0; + } + + public void parse() { + if(cInt16(bytes, count) != 0x0003) die("Version is not 3"); + if(cInt16(bytes, count) != 0x0008) die("Size of header is not 8"); + if(cInt32(bytes, count) != bytes.length) die("Size of manifest doesn't match"); + while(true) { + int type = cInt16(bytes, count); + if(type==0x0001) parseStringPool(); + else if(type==0x0180) parseResourceMap(); + else if(type==0x0100) parseNameSpace(); + else if(type==0x0102) parseElement(); + else die("Type: " + Integer.toHexString(type) + " not yet implemented"); + System.out.println("COUNT: "+Integer.toHexString(count)); + } + //die("Done"); + } + + private void parseStringPool() { + if(cInt16(bytes, count) != 0x001c) die("Header header size not 28"); + int hsize = cInt32(bytes, count); + int stringCount = cInt32(bytes, count); + int styleCount = cInt32(bytes, count); + int flags = cInt32(bytes, count); + int stringsStart = cInt32(bytes, count); + int stylesStart = cInt32(bytes, count); +/* + System.out.println(hsize); + System.out.println(stringCount); + System.out.println(styleCount); + System.out.println(flags); + System.out.println(stringsStart); + System.out.println(stylesStart); +*/ + int[] stringsOffsets = new int[stringCount]; + for(int i=0; i Date: Sun, 21 Dec 2014 22:30:21 +0100 Subject: [PATCH 03/17] Boundaries check. Testing with other given xml binaries. --- .../jadx/core/xmlgen/BinaryXMLParser.java | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index a975667a1..691e2a381 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -42,12 +42,15 @@ public class BinaryXMLParser { if(cInt16(bytes, count) != 0x0003) die("Version is not 3"); if(cInt16(bytes, count) != 0x0008) die("Size of header is not 8"); if(cInt32(bytes, count) != bytes.length) die("Size of manifest doesn't match"); - while(true) { + while((count+2)<=bytes.length) { int type = cInt16(bytes, count); if(type==0x0001) parseStringPool(); else if(type==0x0180) parseResourceMap(); else if(type==0x0100) parseNameSpace(); + else if(type==0x0101) parseNameSpaceEnd(); else if(type==0x0102) parseElement(); + else if(type==0x0103) parseElementEnd(); + else if(type==0x0000) continue; // NullType is just doing nothing else die("Type: " + Integer.toHexString(type) + " not yet implemented"); System.out.println("COUNT: "+Integer.toHexString(count)); } @@ -105,7 +108,8 @@ public class BinaryXMLParser { if(cInt16(bytes, count) != 0x0010) die("NAMESPACE header is not 0x0010"); if(cInt32(bytes, count) != 0x18) die("NAMESPACE header chunk is not 0x18 big"); int beginLineNumber = cInt32(bytes, count); - if(beginLineNumber!=2) die("NAMESPACE beginning line number != 2 not supported yet"); + //if(beginLineNumber!=2) die("NAMESPACE beginning line number != 2 not supported yet"); + System.out.println("NAMESPACE BEGIN Line: " + beginLineNumber); System.out.println("Comment: 0x" + Integer.toHexString(cInt32(bytes, count))); int beginPrefix = cInt32(bytes, count); System.out.println("Prefix: " + strings[beginPrefix]); @@ -115,9 +119,24 @@ public class BinaryXMLParser { System.out.println("COUNT: "+Integer.toHexString(count)); } + private void parseNameSpaceEnd() { + if(cInt16(bytes, count) != 0x0010) die("NAMESPACE header is not 0x0010"); + if(cInt32(bytes, count) != 0x18) die("NAMESPACE header chunk is not 0x18 big"); + int endLineNumber = cInt32(bytes, count); + //if(endLineNumber!=2) die("NAMESPACE begining line number != 2 not supported yet"); + System.out.println("NAMESPACE END Line: " + endLineNumber); + System.out.println("Comment: 0x" + Integer.toHexString(cInt32(bytes, count))); + int endPrefix = cInt32(bytes, count); + System.out.println("Prefix: " + strings[endPrefix]); + nsPrefix = strings[endPrefix]; + int endURI = cInt32(bytes, count); + System.out.println("URI: " + strings[endURI]); + } + private void parseElement() { if(cInt16(bytes, count) != 0x0010) die("ELEMENT HEADER SIZE is not 0x10"); - if(cInt32(bytes, count) != 0x0060) die("ELEMENT CHUNK SIZE is not 0x60"); + //if(cInt32(bytes, count) != 0x0060) die("ELEMENT CHUNK SIZE is not 0x60"); + count+=4; int elementLineNumber = cInt32(bytes, count); System.out.println("elementLineNumber: " + elementLineNumber); System.out.println("Comment: 0x" + Integer.toHexString(cInt32(bytes, count))); @@ -126,6 +145,7 @@ public class BinaryXMLParser { System.out.println("Namespace: 0x" + Integer.toHexString(startNS)); int startNSName = cInt32(bytes, count); // what to do with this id? System.out.println("Namespace name: " + strings[startNSName]); + System.out.println("<" + strings[startNSName] + ""); int attributeStart = cInt16(bytes, count); if(attributeStart != 0x14) die("startNS's attributeStart is not 0x14"); int attributeSize = cInt16(bytes, count); @@ -156,8 +176,23 @@ public class BinaryXMLParser { if(attributeNS != -1) System.out.print(nsPrefix+":"); if(attrValDataType==0x3) System.out.println(strings[attributeName] + "=" + strings[attrValData]); else if(attrValDataType==0x10) System.out.println(strings[attributeName] + "=" + attrValData); - else System.out.println("UNKNOWN DATA TYPE: " + attrValDataType); + else System.out.println(strings[attributeName] + " = UNKNOWN DATA TYPE: " + attrValDataType); } + System.out.println(">"); + } + + private void parseElementEnd() { + if(cInt16(bytes, count) != 0x0010) die("ELEMENT END header is not 0x0010"); + if(cInt32(bytes, count) != 0x18) die("ELEMENT END header chunk is not 0x18 big"); + int endLineNumber = cInt32(bytes, count); + //if(endLineNumber!=2) die("NAMESPACE beginning line number != 2 not supported yet"); + System.out.println("ELEMENT END Line:" + endLineNumber); + System.out.println("Comment: 0x" + Integer.toHexString(cInt32(bytes, count))); + int elementNS = cInt32(bytes, count); + int elementName = cInt32(bytes, count); + System.out.print(""); } private int cInt8(byte[] bytes, int offset) { From 3c425990f6b627e68f91036b14b2914cb045373e Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Sun, 21 Dec 2014 22:30:32 +0100 Subject: [PATCH 04/17] Boundaries check. Testing with other given xml binaries. --- jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index 691e2a381..978e3c7f2 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -168,11 +168,13 @@ public class BinaryXMLParser { if(cInt8(bytes, count) != 0) die("res0 is not 0"); int attrValDataType = cInt8(bytes, count); int attrValData = cInt32(bytes, count); +/* System.out.println("ai["+i+"] ns: " + attributeNS); System.out.println("ai["+i+"] name: " + attributeName); System.out.println("ai["+i+"] rawval: " + attributeRawValue); System.out.println("ai["+i+"] dt: " + attrValDataType); System.out.println("ai["+i+"] d: " + attrValData); +*/ if(attributeNS != -1) System.out.print(nsPrefix+":"); if(attrValDataType==0x3) System.out.println(strings[attributeName] + "=" + strings[attrValData]); else if(attrValDataType==0x10) System.out.println(strings[attributeName] + "=" + attrValData); From 7fd46633a3c8d37530fb5cc9347885038d4858fd Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Sun, 21 Dec 2014 22:37:50 +0100 Subject: [PATCH 05/17] First near working example for first sample. --- .../jadx/core/xmlgen/BinaryXMLParser.java | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index 978e3c7f2..65065f1fd 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -52,7 +52,7 @@ public class BinaryXMLParser { else if(type==0x0103) parseElementEnd(); else if(type==0x0000) continue; // NullType is just doing nothing else die("Type: " + Integer.toHexString(type) + " not yet implemented"); - System.out.println("COUNT: "+Integer.toHexString(count)); + //System.out.println("COUNT: "+Integer.toHexString(count)); } //die("Done"); } @@ -109,14 +109,15 @@ public class BinaryXMLParser { if(cInt32(bytes, count) != 0x18) die("NAMESPACE header chunk is not 0x18 big"); int beginLineNumber = cInt32(bytes, count); //if(beginLineNumber!=2) die("NAMESPACE beginning line number != 2 not supported yet"); - System.out.println("NAMESPACE BEGIN Line: " + beginLineNumber); - System.out.println("Comment: 0x" + Integer.toHexString(cInt32(bytes, count))); + //System.out.println("NAMESPACE BEGIN Line: " + beginLineNumber); + int comment = cInt32(bytes, count); + //System.out.println("Comment: 0x" + Integer.toHexString(comment)); int beginPrefix = cInt32(bytes, count); System.out.println("Prefix: " + strings[beginPrefix]); nsPrefix = strings[beginPrefix]; int beginURI = cInt32(bytes, count); System.out.println("URI: " + strings[beginURI]); - System.out.println("COUNT: "+Integer.toHexString(count)); + //System.out.println("COUNT: "+Integer.toHexString(count)); } private void parseNameSpaceEnd() { @@ -124,8 +125,9 @@ public class BinaryXMLParser { if(cInt32(bytes, count) != 0x18) die("NAMESPACE header chunk is not 0x18 big"); int endLineNumber = cInt32(bytes, count); //if(endLineNumber!=2) die("NAMESPACE begining line number != 2 not supported yet"); - System.out.println("NAMESPACE END Line: " + endLineNumber); - System.out.println("Comment: 0x" + Integer.toHexString(cInt32(bytes, count))); + //System.out.println("NAMESPACE END Line: " + endLineNumber); + int comment = cInt32(bytes, count); + //System.out.println("Comment: 0x" + Integer.toHexString(comment)); int endPrefix = cInt32(bytes, count); System.out.println("Prefix: " + strings[endPrefix]); nsPrefix = strings[endPrefix]; @@ -138,26 +140,27 @@ public class BinaryXMLParser { //if(cInt32(bytes, count) != 0x0060) die("ELEMENT CHUNK SIZE is not 0x60"); count+=4; int elementLineNumber = cInt32(bytes, count); - System.out.println("elementLineNumber: " + elementLineNumber); - System.out.println("Comment: 0x" + Integer.toHexString(cInt32(bytes, count))); - System.out.println("COUNT: "+Integer.toHexString(count)); + //System.out.println("elementLineNumber: " + elementLineNumber); + int comment = cInt32(bytes, count); + //System.out.println("Comment: 0x" + Integer.toHexString(comment)); + //System.out.println("COUNT: "+Integer.toHexString(count)); int startNS = cInt32(bytes, count); - System.out.println("Namespace: 0x" + Integer.toHexString(startNS)); + //System.out.println("Namespace: 0x" + Integer.toHexString(startNS)); int startNSName = cInt32(bytes, count); // what to do with this id? - System.out.println("Namespace name: " + strings[startNSName]); + //System.out.println("Namespace name: " + strings[startNSName]); System.out.println("<" + strings[startNSName] + ""); int attributeStart = cInt16(bytes, count); if(attributeStart != 0x14) die("startNS's attributeStart is not 0x14"); int attributeSize = cInt16(bytes, count); if(attributeSize != 0x14) die("startNS's attributeSize is not 0x14"); int attributeCount = cInt16(bytes, count); - System.out.println("startNS: attributeCount: " + attributeCount); + //System.out.println("startNS: attributeCount: " + attributeCount); int idIndex = cInt16(bytes, count); - System.out.println("startNS: idIndex: " + idIndex); + //System.out.println("startNS: idIndex: " + idIndex); int classIndex = cInt16(bytes, count); - System.out.println("startNS: classIndex: " + classIndex); + //System.out.println("startNS: classIndex: " + classIndex); int styleIndex = cInt16(bytes, count); - System.out.println("startNS: styleIndex: " + styleIndex); + //System.out.println("startNS: styleIndex: " + styleIndex); for(int i=0; i Date: Sun, 21 Dec 2014 23:03:15 +0100 Subject: [PATCH 06/17] Correct tab numbers. Some little things still missing. --- .../jadx/core/xmlgen/BinaryXMLParser.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index 65065f1fd..2437117a8 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -15,6 +15,7 @@ public class BinaryXMLParser { private String[] strings; private int count; private String nsPrefix="ERROR"; + private int numtabs=-1; public BinaryXMLParser(String xmlfilepath) { System.out.println(xmlfilepath); File manifest = new File(xmlfilepath); @@ -136,6 +137,7 @@ public class BinaryXMLParser { } private void parseElement() { + numtabs+=1; if(cInt16(bytes, count) != 0x0010) die("ELEMENT HEADER SIZE is not 0x10"); //if(cInt32(bytes, count) != 0x0060) die("ELEMENT CHUNK SIZE is not 0x60"); count+=4; @@ -148,7 +150,8 @@ public class BinaryXMLParser { //System.out.println("Namespace: 0x" + Integer.toHexString(startNS)); int startNSName = cInt32(bytes, count); // what to do with this id? //System.out.println("Namespace name: " + strings[startNSName]); - System.out.println("<" + strings[startNSName] + ""); + for(int i=0; i0) System.out.print(" "); for(int i=0; i"); } @@ -196,9 +209,11 @@ public class BinaryXMLParser { //System.out.println("Comment: 0x" + Integer.toHexString(comment)); int elementNS = cInt32(bytes, count); int elementName = cInt32(bytes, count); + for(int i=0; i"); + numtabs-=1; } private int cInt8(byte[] bytes, int offset) { From c242a62bcc6c482710f45c9c639fc3b36e5a3f82 Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Sun, 21 Dec 2014 23:26:02 +0100 Subject: [PATCH 07/17] Write xml to a given output file instead of stdout. --- jadx-cli/src/main/java/jadx/cli/JadxCLI.java | 2 +- .../jadx/core/xmlgen/BinaryXMLParser.java | 60 +++++++++++-------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java index 5eaa24ca2..7aeddc841 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java @@ -14,7 +14,7 @@ public class JadxCLI { private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class); public static void main(String[] args) throws JadxException { - BinaryXMLParser bxp = new BinaryXMLParser(args[0]); + BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); bxp.parse(); System.exit(4); try { diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index 2437117a8..f3da438c9 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -9,6 +9,7 @@ import java.io.FileNotFoundException; import java.io.InputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.io.PrintWriter; public class BinaryXMLParser { private byte[] bytes; @@ -16,8 +17,14 @@ public class BinaryXMLParser { private int count; private String nsPrefix="ERROR"; private int numtabs=-1; - public BinaryXMLParser(String xmlfilepath) { - System.out.println(xmlfilepath); + PrintWriter writer; + public BinaryXMLParser(String xmlfilepath, String xmloutfilepath) { + //System.out.println(xmlfilepath); + try { + writer = new PrintWriter(xmloutfilepath,"UTF-8"); + } catch(FileNotFoundException fnfe) { die("FNFE"); } + catch(UnsupportedEncodingException uee) { die("UEE"); } + if(null==writer) die("null==writer"); File manifest = new File(xmlfilepath); if(null==manifest) die("null==manifest"); bytes = new byte[(int) manifest.length()]; @@ -55,6 +62,7 @@ public class BinaryXMLParser { else die("Type: " + Integer.toHexString(type) + " not yet implemented"); //System.out.println("COUNT: "+Integer.toHexString(count)); } + writer.close(); //die("Done"); } @@ -88,7 +96,7 @@ public class BinaryXMLParser { System.arraycopy(bytes, count, str, 0, strlen*2); count+=strlen*2; strings[i] = new String(str, Charset.forName("UTF-16LE")); - System.out.println("index i["+i+"] string: " + strings[i]); + //System.out.println("index i["+i+"] string: " + strings[i]); count+=2; } } @@ -96,12 +104,12 @@ public class BinaryXMLParser { private void parseResourceMap() { if(cInt16(bytes, count) != 0x8) die("Header size of resmap is not 8!"); int rhsize = cInt32(bytes, count); - System.out.println("RHeader Size: " + rhsize); + //System.out.println("RHeader Size: " + rhsize); int[] ids = new int[(rhsize-8)/4]; for(int i=0; i0) System.out.print(" "); + if(attributeCount>0) writer.print(" "); for(int i=0; i"); + writer.println(">"); } private void parseElementEnd() { @@ -209,10 +217,10 @@ public class BinaryXMLParser { //System.out.println("Comment: 0x" + Integer.toHexString(comment)); int elementNS = cInt32(bytes, count); int elementName = cInt32(bytes, count); - for(int i=0; i"); + for(int i=0; i"); numtabs-=1; } From b87d1a7fe1d0172d4ad728453b391491ddbee8b2 Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Mon, 22 Dec 2014 00:11:37 +0100 Subject: [PATCH 08/17] Fixed XML oneLiners. Added another attribute value data type --- .../jadx/core/xmlgen/BinaryXMLParser.java | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index f3da438c9..51cea2be0 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -16,7 +16,10 @@ public class BinaryXMLParser { private String[] strings; private int count; private String nsPrefix="ERROR"; + private String nsURI="ERROR"; + private String currentTag="ERROR"; private int numtabs=-1; + private boolean wasOneLiner=false; PrintWriter writer; public BinaryXMLParser(String xmlfilepath, String xmloutfilepath) { //System.out.println(xmlfilepath); @@ -126,6 +129,7 @@ public class BinaryXMLParser { nsPrefix = strings[beginPrefix]; int beginURI = cInt32(bytes, count); //System.out.println("URI: " + strings[beginURI]); + nsURI=strings[beginURI]; //System.out.println("COUNT: "+Integer.toHexString(count)); } @@ -141,6 +145,7 @@ public class BinaryXMLParser { //System.out.println("Prefix: " + strings[endPrefix]); nsPrefix = strings[endPrefix]; int endURI = cInt32(bytes, count); + nsURI=strings[endURI]; //System.out.println("URI: " + strings[endURI]); } @@ -149,15 +154,20 @@ public class BinaryXMLParser { if(cInt16(bytes, count) != 0x0010) die("ELEMENT HEADER SIZE is not 0x10"); //if(cInt32(bytes, count) != 0x0060) die("ELEMENT CHUNK SIZE is not 0x60"); count+=4; - int elementLineNumber = cInt32(bytes, count); - //System.out.println("elementLineNumber: " + elementLineNumber); + int elementBegLineNumber = cInt32(bytes, count); + //System.out.println("ELEMENT BEG Line: " + elementBegLineNumber + " of " + strings[startNSName]); int comment = cInt32(bytes, count); //System.out.println("Comment: 0x" + Integer.toHexString(comment)); //System.out.println("COUNT: "+Integer.toHexString(count)); int startNS = cInt32(bytes, count); //System.out.println("Namespace: 0x" + Integer.toHexString(startNS)); - int startNSName = cInt32(bytes, count); // what to do with this id? + int startNSName = cInt32(bytes, count); // actually is elementName... //System.out.println("Namespace name: " + strings[startNSName]); + if(!wasOneLiner && !"ERROR".equals(currentTag) && !currentTag.equals(strings[startNSName])) { + writer.println(">"); + } + wasOneLiner=false; + currentTag=strings[startNSName]; for(int i=0; i0) writer.print(" "); for(int i=0; i"); + //writer.println(">"); + //System.out.println("ELEMENT BEG Line: " + elementBegLineNumber + " of " + strings[startNSName]); } private void parseElementEnd() { @@ -212,16 +225,22 @@ public class BinaryXMLParser { if(cInt32(bytes, count) != 0x18) die("ELEMENT END header chunk is not 0x18 big"); int endLineNumber = cInt32(bytes, count); //if(endLineNumber!=2) die("NAMESPACE beginning line number != 2 not supported yet"); - //System.out.println("ELEMENT END Line:" + endLineNumber); int comment = cInt32(bytes, count); //System.out.println("Comment: 0x" + Integer.toHexString(comment)); int elementNS = cInt32(bytes, count); int elementName = cInt32(bytes, count); - for(int i=0; i"); + if(currentTag==strings[elementName]) { + writer.println("/>"); + wasOneLiner=true; + } else { + for(int i=0; i"); + } numtabs-=1; + //System.out.println("ELEMENT END Line: " + endLineNumber + " of " + strings[elementName]); + // TODO: Mind linenumbers for real original file ;) } private int cInt8(byte[] bytes, int offset) { From 2fdb26146b09352405cbc01a2ae8a0e8d45981da Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Mon, 22 Dec 2014 00:14:46 +0100 Subject: [PATCH 09/17] Refactored attribute value printing. --- .../java/jadx/core/xmlgen/BinaryXMLParser.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index 51cea2be0..c41890a2a 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -204,16 +204,17 @@ public class BinaryXMLParser { System.out.println("ai["+i+"] d: " + attrValData); */ if(attributeNS != -1) writer.print(nsPrefix+":"); - //writer.print(strings[attributeName] + "=\""); - if(attrValDataType==0x3) writer.print(strings[attributeName] + "=\"" + strings[attrValData]+"\""); - else if(attrValDataType==0x10) writer.print(strings[attributeName] + "=\"" + attrValData+"\""); + writer.print(strings[attributeName] + "=\""); + if(attrValDataType==0x3) writer.print(strings[attrValData]); + else if(attrValDataType==0x10) writer.print(attrValData); else if(attrValDataType==0x12) { // TODO: data is always -1, FIXME - if(attrValData==0) writer.print(strings[attributeName] + "=\"false\""); - else if(attrValData==1 || attrValData==-1) writer.print(strings[attributeName] + "=\"true\""); - else writer.print(strings[attributeName] + "=\"UNKNOWN\""); - } else if(attrValDataType==0x1) writer.print(strings[attributeName] + "=\"0x" + Integer.toHexString(attrValData) + "\""); - else writer.print(strings[attributeName] + " = UNKNOWN DATA TYPE: " + attrValDataType); + if(attrValData==0) writer.print("false"); + else if(attrValData==1 || attrValData==-1) writer.print("true"); + else writer.print("UNKNOWN_BOOLEAN_TYPE"); + } else if(attrValDataType==0x1) writer.print("0x" + Integer.toHexString(attrValData)); + else writer.print("UNKNOWN_DATA_TYPE_" + attrValDataType); + writer.print("\""); if((i+1)"); From 824db6be2bbe5a9acafbc0171fe36fdf34b8663d Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Mon, 22 Dec 2014 00:15:30 +0100 Subject: [PATCH 10/17] Removed BinaryXMLParser Call in main method. --- jadx-cli/src/main/java/jadx/cli/JadxCLI.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java index 7aeddc841..12686c3dd 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java @@ -8,15 +8,15 @@ import java.io.File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jadx.core.xmlgen.BinaryXMLParser; +//import jadx.core.xmlgen.BinaryXMLParser; public class JadxCLI { private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class); public static void main(String[] args) throws JadxException { - BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); - bxp.parse(); - System.exit(4); + //BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); + //bxp.parse(); + //System.exit(4); try { JadxCLIArgs jadxArgs = new JadxCLIArgs(); if (processArgs(jadxArgs, args)) { From 2bacab7dc0f8537d64b497ab43f19f11cb136a59 Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Mon, 22 Dec 2014 00:40:09 +0100 Subject: [PATCH 11/17] Removed old less-warnings branch commit changes. --- jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java | 1 - jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java | 2 +- jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java | 10 +++++----- jadx-gui/src/main/java/jadx/gui/utils/Link.java | 1 - 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java index 50220a83e..fcd5957a1 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java @@ -10,7 +10,6 @@ import javax.swing.Icon; import javax.swing.tree.DefaultMutableTreeNode; public abstract class JNode extends DefaultMutableTreeNode { - private static final long serialVersionUID = 1337L; // TODO: Create your own serialvers with serialver/eclipse public static JNode makeFrom(JavaNode node) { if (node instanceof JavaClass) { JClass p = (JClass) makeFrom(node.getDeclaringClass()); diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java index 2df2355db..a20631a32 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java @@ -124,7 +124,7 @@ public class JRoot extends JNode { } public JClass searchClassInTree(JClass node) { - Enumeration en = this.breadthFirstEnumeration(); + Enumeration en = this.breadthFirstEnumeration(); while (en.hasMoreElements()) { Object obj = en.nextElement(); if (node.equals(obj)) { diff --git a/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java index 8bd8874fb..96a01eee2 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java @@ -71,7 +71,7 @@ public class SearchDialog extends JDialog { private JTextField searchField; private ResultsModel resultsModel; - private JList resultsList; + private JList resultsList; private JProgressBar busyBar; public SearchDialog(Frame owner, TabbedPane tabbedPane, JadxWrapper wrapper) { @@ -171,7 +171,7 @@ public class SearchDialog extends JDialog { } } - private static class ResultsModel extends DefaultListModel { + private static class ResultsModel extends DefaultListModel { private static final long serialVersionUID = -7821286846923903208L; private void setResults(List results) { @@ -186,7 +186,7 @@ public class SearchDialog extends JDialog { } } - private static class ResultsCellRenderer implements ListCellRenderer { + private static class ResultsCellRenderer implements ListCellRenderer { private final Color selectedBackground; private final Color selectedForeground; @@ -197,7 +197,7 @@ public class SearchDialog extends JDialog { } @Override - public Component getListCellRendererComponent(JList list, + public Component getListCellRendererComponent(JList list, Object obj, int index, boolean isSelected, boolean cellHasFocus) { if (!(obj instanceof JNode)) { return null; @@ -244,7 +244,7 @@ public class SearchDialog extends JDialog { codeChBox.setEnabled(false); resultsModel = new ResultsModel(); - resultsList = new JList(resultsModel); + resultsList = new JList(resultsModel); resultsList.setCellRenderer(new ResultsCellRenderer()); resultsList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { diff --git a/jadx-gui/src/main/java/jadx/gui/utils/Link.java b/jadx-gui/src/main/java/jadx/gui/utils/Link.java index cc29cc60f..033b59e93 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/Link.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/Link.java @@ -18,7 +18,6 @@ import org.slf4j.LoggerFactory; import static java.awt.Desktop.Action; public class Link extends JLabel implements MouseListener { - private static final long serialVersionUID = 0L; // TODO: Generate random serialvers with serialver/eclipse private static final Logger LOG = LoggerFactory.getLogger(JLabel.class); private String url; From e081aadd2712195bc45edeed6eaa74b75b35886d Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Mon, 22 Dec 2014 00:44:02 +0100 Subject: [PATCH 12/17] Added xml header --- jadx-cli/src/main/java/jadx/cli/JadxCLI.java | 8 ++++---- .../src/main/java/jadx/core/xmlgen/BinaryXMLParser.java | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java index 12686c3dd..7aeddc841 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java @@ -8,15 +8,15 @@ import java.io.File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -//import jadx.core.xmlgen.BinaryXMLParser; +import jadx.core.xmlgen.BinaryXMLParser; public class JadxCLI { private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class); public static void main(String[] args) throws JadxException { - //BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); - //bxp.parse(); - //System.exit(4); + BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); + bxp.parse(); + System.exit(4); try { JadxCLIArgs jadxArgs = new JadxCLIArgs(); if (processArgs(jadxArgs, args)) { diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index c41890a2a..44c826084 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -28,6 +28,7 @@ public class BinaryXMLParser { } catch(FileNotFoundException fnfe) { die("FNFE"); } catch(UnsupportedEncodingException uee) { die("UEE"); } if(null==writer) die("null==writer"); + writer.println(""); File manifest = new File(xmlfilepath); if(null==manifest) die("null==manifest"); bytes = new byte[(int) manifest.length()]; From c4367e25a91b27edfcc05fdb8e9e8c268830589d Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Mon, 22 Dec 2014 00:44:29 +0100 Subject: [PATCH 13/17] Removed call in main method. --- jadx-cli/src/main/java/jadx/cli/JadxCLI.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java index 7aeddc841..7039e7c88 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java @@ -8,15 +8,15 @@ import java.io.File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jadx.core.xmlgen.BinaryXMLParser; +//import jadx.core.xmlgen.BinaryXMLParser; public class JadxCLI { private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class); public static void main(String[] args) throws JadxException { - BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); - bxp.parse(); - System.exit(4); +// BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); +// bxp.parse(); +// System.exit(4); try { JadxCLIArgs jadxArgs = new JadxCLIArgs(); if (processArgs(jadxArgs, args)) { From 0f7ca8cea4aafef28697242dd8a238b302e08749 Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Mon, 22 Dec 2014 11:56:06 +0100 Subject: [PATCH 14/17] Added a whitespace before oneLiner ends. --- jadx-cli/src/main/java/jadx/cli/JadxCLI.java | 8 ++++---- .../src/main/java/jadx/core/xmlgen/BinaryXMLParser.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java index 7039e7c88..7aeddc841 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java @@ -8,15 +8,15 @@ import java.io.File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -//import jadx.core.xmlgen.BinaryXMLParser; +import jadx.core.xmlgen.BinaryXMLParser; public class JadxCLI { private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class); public static void main(String[] args) throws JadxException { -// BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); -// bxp.parse(); -// System.exit(4); + BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); + bxp.parse(); + System.exit(4); try { JadxCLIArgs jadxArgs = new JadxCLIArgs(); if (processArgs(jadxArgs, args)) { diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index 44c826084..8256985f1 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -232,7 +232,7 @@ public class BinaryXMLParser { int elementNS = cInt32(bytes, count); int elementName = cInt32(bytes, count); if(currentTag==strings[elementName]) { - writer.println("/>"); + writer.println(" />"); wasOneLiner=true; } else { for(int i=0; i Date: Mon, 22 Dec 2014 13:36:10 +0100 Subject: [PATCH 15/17] Added style decoding and a first decoding for data type 17. --- build.gradle | 1 + jadx-cli/src/main/java/jadx/cli/JadxCLI.java | 4 +- .../jadx/core/xmlgen/BinaryXMLParser.java | 56 ++++++++++++++++++- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 157d0ccc0..5310dc19e 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,7 @@ subprojects { } dependencies { + compile 'com.google.android:android:4.1.1.4' compile 'org.slf4j:slf4j-api:1.7.7' testCompile 'ch.qos.logback:logback-classic:1.1.2' diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java index 7aeddc841..f8f934869 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java @@ -8,15 +8,17 @@ import java.io.File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import jadx.core.xmlgen.BinaryXMLParser; +//import jadx.core.xmlgen.BinaryXMLParser; public class JadxCLI { private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class); public static void main(String[] args) throws JadxException { +/* BinaryXMLParser bxp = new BinaryXMLParser(args[0],args[1]); bxp.parse(); System.exit(4); +*/ try { JadxCLIArgs jadxArgs = new JadxCLIArgs(); if (processArgs(jadxArgs, args)) { diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index 8256985f1..c39dc4cbb 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -11,6 +11,14 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.io.PrintWriter; +import java.lang.reflect.Field; + +import java.util.HashMap; +import java.util.Map; + +import android.R.style; +//import android.content.res.Resources; + public class BinaryXMLParser { private byte[] bytes; private String[] strings; @@ -21,6 +29,7 @@ public class BinaryXMLParser { private int numtabs=-1; private boolean wasOneLiner=false; PrintWriter writer; + Map styleMap = null; public BinaryXMLParser(String xmlfilepath, String xmloutfilepath) { //System.out.println(xmlfilepath); try { @@ -48,6 +57,16 @@ public class BinaryXMLParser { } catch(FileNotFoundException fnfe) { die("FILE NOT FOUND"); } catch(IOException ioe) { die("IOE"); } count=0; + styleMap = new HashMap(); + if(null==styleMap) die("null==styleMap"); + for(Field f : android.R.style.class.getFields()) { + try { + styleMap.put(f.getInt(f.getType()),f.getName()); + } catch(IllegalAccessException iae) { + die("IAE"); + } + } + } public void parse() { @@ -182,7 +201,7 @@ public class BinaryXMLParser { int classIndex = cInt16(bytes, count); //System.out.println("startNS: classIndex: " + classIndex); int styleIndex = cInt16(bytes, count); - //System.out.println("startNS: styleIndex: " + styleIndex); + if(styleIndex!=0) System.out.println("startNS: styleIndex: " + styleIndex); if("manifest".equals(strings[startNSName])) writer.print(" xmlns:\""+nsURI+"\""); if(attributeCount>0) writer.print(" "); for(int i=0; i Date: Mon, 22 Dec 2014 14:04:28 +0100 Subject: [PATCH 16/17] Removed debug output. --- .../jadx/core/xmlgen/BinaryXMLParser.java | 88 ++++--------------- 1 file changed, 16 insertions(+), 72 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index c39dc4cbb..b043469e3 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -17,7 +17,17 @@ import java.util.HashMap; import java.util.Map; import android.R.style; -//import android.content.res.Resources; + +/* TODO: + Don't die when error occurs + Check error cases, maybe checked const values are not always the same + Better error messages + What to do, when Binary XML Manifest is > size(int)? + Check for missung chunk size types + Implement missing data types + Use linenumbers to recreate EXACT AndroidManifest + Check Element chunk size +*/ public class BinaryXMLParser { private byte[] bytes; @@ -28,10 +38,10 @@ public class BinaryXMLParser { private String currentTag="ERROR"; private int numtabs=-1; private boolean wasOneLiner=false; - PrintWriter writer; - Map styleMap = null; + private PrintWriter writer; + private Map styleMap = null; + public BinaryXMLParser(String xmlfilepath, String xmloutfilepath) { - //System.out.println(xmlfilepath); try { writer = new PrintWriter(xmloutfilepath,"UTF-8"); } catch(FileNotFoundException fnfe) { die("FNFE"); } @@ -83,10 +93,8 @@ public class BinaryXMLParser { else if(type==0x0103) parseElementEnd(); else if(type==0x0000) continue; // NullType is just doing nothing else die("Type: " + Integer.toHexString(type) + " not yet implemented"); - //System.out.println("COUNT: "+Integer.toHexString(count)); } writer.close(); - //die("Done"); } private void parseStringPool() { @@ -97,29 +105,18 @@ public class BinaryXMLParser { int flags = cInt32(bytes, count); int stringsStart = cInt32(bytes, count); int stylesStart = cInt32(bytes, count); -/* - System.out.println(hsize); - System.out.println(stringCount); - System.out.println(styleCount); - System.out.println(flags); - System.out.println(stringsStart); - System.out.println(stylesStart); -*/ int[] stringsOffsets = new int[stringCount]; for(int i=0; i"); } @@ -195,13 +172,9 @@ public class BinaryXMLParser { int attributeSize = cInt16(bytes, count); if(attributeSize != 0x14) die("startNS's attributeSize is not 0x14"); int attributeCount = cInt16(bytes, count); - //System.out.println("startNS: attributeCount: " + attributeCount); int idIndex = cInt16(bytes, count); - //System.out.println("startNS: idIndex: " + idIndex); int classIndex = cInt16(bytes, count); - //System.out.println("startNS: classIndex: " + classIndex); int styleIndex = cInt16(bytes, count); - if(styleIndex!=0) System.out.println("startNS: styleIndex: " + styleIndex); if("manifest".equals(strings[startNSName])) writer.print(" xmlns:\""+nsURI+"\""); if(attributeCount>0) writer.print(" "); for(int i=0; i"); - //System.out.println("ELEMENT BEG Line: " + elementBegLineNumber + " of " + strings[startNSName]); } private void parseElementEnd() { if(cInt16(bytes, count) != 0x0010) die("ELEMENT END header is not 0x0010"); if(cInt32(bytes, count) != 0x18) die("ELEMENT END header chunk is not 0x18 big"); int endLineNumber = cInt32(bytes, count); - //if(endLineNumber!=2) die("NAMESPACE beginning line number != 2 not supported yet"); int comment = cInt32(bytes, count); - //System.out.println("Comment: 0x" + Integer.toHexString(comment)); int elementNS = cInt32(bytes, count); int elementName = cInt32(bytes, count); if(currentTag==strings[elementName]) { @@ -291,8 +237,6 @@ public class BinaryXMLParser { writer.println(strings[elementName]+">"); } numtabs-=1; - //System.out.println("ELEMENT END Line: " + endLineNumber + " of " + strings[elementName]); - // TODO: Mind linenumbers for real original file ;) } private int cInt8(byte[] bytes, int offset) { From aacb83290edd796b016ba62413dddd30912b520d Mon Sep 17 00:00:00 2001 From: YASME-Tim Date: Mon, 22 Dec 2014 22:11:04 +0100 Subject: [PATCH 17/17] Added option flag to make androidmanifest.xml decompiling optional. --- .../src/main/java/jadx/cli/JadxCLIArgs.java | 8 +++++++ .../main/java/jadx/api/DefaultJadxArgs.java | 5 ++++ .../src/main/java/jadx/api/IJadxArgs.java | 2 ++ .../main/java/jadx/api/JadxDecompiler.java | 11 +++++++++ .../java/jadx/core/utils/files/InputFile.java | 23 +++++++++++++++++++ .../jadx/core/xmlgen/BinaryXMLParser.java | 22 +++++++++++++++++- 6 files changed, 70 insertions(+), 1 deletion(-) diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java index bc960c8a4..662454ccc 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java @@ -47,6 +47,9 @@ public final class JadxCLIArgs implements IJadxArgs { @Parameter(names = {"-h", "--help"}, description = "print this help", help = true) protected boolean printHelp = false; + @Parameter(names = {"-x", "--xml"}, description = "try to decode the AndroidManifest.xml, save at current dir") + protected boolean xmlTest = false; + private final List input = new ArrayList(1); private File outputDir; @@ -164,6 +167,11 @@ public final class JadxCLIArgs implements IJadxArgs { return printHelp; } + @Override + public boolean isXMLTest() { + return xmlTest; + } + @Override public int getThreadsCount() { return threadsCount; diff --git a/jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java b/jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java index 302c59f54..66bcdfd0e 100644 --- a/jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java +++ b/jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java @@ -38,4 +38,9 @@ public class DefaultJadxArgs implements IJadxArgs { public boolean isVerbose() { return false; } + + @Override + public boolean isXMLTest() { + return false; + } } diff --git a/jadx-core/src/main/java/jadx/api/IJadxArgs.java b/jadx-core/src/main/java/jadx/api/IJadxArgs.java index 4aa8aeca7..32ea4fd6e 100644 --- a/jadx-core/src/main/java/jadx/api/IJadxArgs.java +++ b/jadx-core/src/main/java/jadx/api/IJadxArgs.java @@ -16,4 +16,6 @@ public interface IJadxArgs { boolean isShowInconsistentCode(); boolean isVerbose(); + + boolean isXMLTest(); } diff --git a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java index ea8cd446d..539c5d942 100644 --- a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java +++ b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java @@ -11,6 +11,7 @@ import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.exceptions.JadxException; import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.core.utils.files.InputFile; +import jadx.core.xmlgen.BinaryXMLParser; import java.io.File; import java.io.IOException; @@ -202,6 +203,16 @@ public final class JadxDecompiler { reset(); root = new RootNode(); LOG.info("loading ..."); + if(this.args.isXMLTest()) { + InputFile inf = inputFiles.get(0); + try { + BinaryXMLParser bxp = new BinaryXMLParser(InputFile.loadXMLBuffer(inf.getFile()), "./AndroidManifest.xml"); + //BinaryXMLParser bxp = new BinaryXMLParser(InputFile.loadXMLBuffer(inf.getFile()), "AndroidManifest.xml"); + bxp.parse(); + } catch(IOException ioe) { + LOG.info("Decompiling AndroidManifest.xml failed!"); + } + } root.load(inputFiles); } diff --git a/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java b/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java index 2bf548abe..7b62a1883 100644 --- a/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java +++ b/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java @@ -74,6 +74,29 @@ public class InputFile { } } + public static byte[] loadXMLBuffer(File file) throws IOException { // FIXME: Public.. Please fix + ZipFile zf = new ZipFile(file); + ZipEntry xml = zf.getEntry("AndroidManifest.xml"); + if(null == xml) { + zf.close(); + return null; + } + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + InputStream in = null; + try { + in = zf.getInputStream(xml); + byte[] buffer = new byte[(int) xml.getSize()]; // FIXME: long->int conversion loss + int count; + while ((count = in.read(buffer)) != -1) { + bytesOut.write(buffer, 0, count); + } + } finally { + if(null != in) in.close(); + zf.close(); + } + return bytesOut.toByteArray(); + } + private static Dex loadFromZip(File file) throws IOException { ZipFile zf = new ZipFile(file); ZipEntry dex = zf.getEntry("classes.dex"); diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index b043469e3..4c43406ee 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -76,7 +76,27 @@ public class BinaryXMLParser { die("IAE"); } } - + } + + public BinaryXMLParser(byte[] xmlfilebytes, String xmloutfilepath) { + System.out.println("XMLOUTFILEPATH: " + xmloutfilepath); + try { + writer = new PrintWriter(xmloutfilepath,"UTF-8"); + } catch(FileNotFoundException fnfe) { die("FNFE"); } + catch(UnsupportedEncodingException uee) { die("UEE"); } + if(null==writer) die("null==writer"); + writer.println(""); + bytes = xmlfilebytes; + count=0; + styleMap = new HashMap(); + if(null==styleMap) die("null==styleMap"); + for(Field f : android.R.style.class.getFields()) { + try { + styleMap.put(f.getInt(f.getType()),f.getName()); + } catch(IllegalAccessException iae) { + die("IAE"); + } + } } public void parse() {