From e2684fa2191e04f27faba763f2bcc19593513b25 Mon Sep 17 00:00:00 2001 From: "JesusFreke@JesusFreke.com" Date: Tue, 1 Dec 2009 08:14:21 +0000 Subject: [PATCH] - refactored/simplified the label code - changed the handler_ label prefix to catch_ and catchall_ - added support for the new -i/--indexed-labels option, which numbers the labels incrementally for each method by type, rather than using the bytecode offset git-svn-id: https://smali.googlecode.com/svn/trunk@493 55b6fa8a-2a1e-11de-a435-ffa8d773f76a --- .../jf/baksmali/Adaptors/CatchMethodItem.java | 46 +++-- .../Adaptors/EndTryLabelMethodItem.java | 2 +- .../Format/Instruction10tMethodItem.java | 14 +- .../Format/Instruction20tMethodItem.java | 14 +- .../Format/Instruction21tMethodItem.java | 15 +- .../Format/Instruction22tMethodItem.java | 15 +- .../Format/Instruction30tMethodItem.java | 14 +- .../Format/Instruction31tMethodItem.java | 22 ++- .../OffsetInstructionFormatMethodItem.java | 60 ++++++ .../Format/PackedSwitchMethodItem.java | 35 ++-- .../Format/SparseSwitchMethodItem.java | 60 ++++-- .../jf/baksmali/Adaptors/LabelMethodItem.java | 30 ++- .../baksmali/Adaptors/MethodDefinition.java | 181 ++++++++++-------- .../main/java/org/jf/baksmali/baksmali.java | 6 +- .../src/main/java/org/jf/baksmali/main.java | 17 +- .../templates/templates/baksmali.stg | 51 ++--- 16 files changed, 369 insertions(+), 213 deletions(-) create mode 100644 baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/OffsetInstructionFormatMethodItem.java diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/CatchMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/CatchMethodItem.java index d36d51a2..4d8d4cc9 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/CatchMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/CatchMethodItem.java @@ -36,18 +36,42 @@ import org.antlr.stringtemplate.StringTemplate; public class CatchMethodItem extends MethodItem { private final StringTemplateGroup stg; private final TypeIdItem exceptionType; - private final int startAddress; - private final int endAddress; - private final int handlerAddress; - public CatchMethodItem(int offset, StringTemplateGroup stg, TypeIdItem exceptionType, int startAddress, - int endAddress, int handlerAddress) { + private final LabelMethodItem tryStartLabel; + private final LabelMethodItem tryEndLabel; + private final LabelMethodItem handlerLabel; + + public CatchMethodItem(MethodDefinition.LabelCache labelCache, int offset, StringTemplateGroup stg, + TypeIdItem exceptionType, int startAddress, int endAddress, int handlerAddress) { super(offset); this.stg = stg; this.exceptionType = exceptionType; - this.startAddress = startAddress; - this.endAddress = endAddress; - this.handlerAddress = handlerAddress; + + tryStartLabel = labelCache.internLabel(new LabelMethodItem(startAddress, stg, "try_start_")); + tryStartLabel.setUncommented(); + //use the offset from the last covered instruction, but make the label + //name refer to the address of the next instruction + tryEndLabel = labelCache.internLabel(new EndTryLabelMethodItem(offset, stg, endAddress)); + tryEndLabel.setUncommented(); + + if (exceptionType == null) { + handlerLabel = labelCache.internLabel(new LabelMethodItem(handlerAddress, stg, "catchall_")); + } else { + handlerLabel = labelCache.internLabel(new LabelMethodItem(handlerAddress, stg, "catch_")); + } + handlerLabel.setUncommented(); + } + + public LabelMethodItem getTryStartLabel() { + return tryStartLabel; + } + + public LabelMethodItem getTryEndLabel() { + return tryEndLabel; + } + + public LabelMethodItem getHandlerLabel() { + return handlerLabel; } public int getSortOrder() { @@ -65,9 +89,9 @@ public class CatchMethodItem extends MethodItem { if (exceptionType != null) { template.setAttribute("ExceptionType", TypeReference.makeTemplate(stg, exceptionType)); } - template.setAttribute("StartAddress", Integer.toHexString(startAddress)); - template.setAttribute("EndAddress", Integer.toHexString(endAddress)); - template.setAttribute("HandlerAddress", Integer.toHexString(handlerAddress)); + template.setAttribute("StartLabel", tryStartLabel); + template.setAttribute("EndLabel", tryEndLabel); + template.setAttribute("HandlerLabel", handlerLabel); return template.toString(); } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/EndTryLabelMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/EndTryLabelMethodItem.java index 403c4832..2298fdde 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/EndTryLabelMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/EndTryLabelMethodItem.java @@ -34,7 +34,7 @@ public class EndTryLabelMethodItem extends LabelMethodItem { private int labelOffset; public EndTryLabelMethodItem(int offset, StringTemplateGroup stg, int labelOffset) { - super(offset, stg, "try_end_", false); + super(offset, stg, "try_end_"); this.labelOffset = labelOffset; } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction10tMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction10tMethodItem.java index fd22ca29..4467f639 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction10tMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction10tMethodItem.java @@ -28,18 +28,18 @@ package org.jf.baksmali.Adaptors.Format; -import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.jf.dexlib.Code.Format.Instruction10t; import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.MethodDefinition; -public class Instruction10tMethodItem extends InstructionFormatMethodItem { - public Instruction10tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, - Instruction10t instruction) { - super(codeItem, offset, stg, instruction); +public class Instruction10tMethodItem extends OffsetInstructionFormatMethodItem { + public Instruction10tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset, + StringTemplateGroup stg, Instruction10t instruction) { + super(labelCache, codeItem, offset, stg, instruction); } - protected void setAttributes(StringTemplate template) { - template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset())); + protected String getLabelPrefix() { + return "goto_"; } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction20tMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction20tMethodItem.java index fe337ae6..fde767ae 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction20tMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction20tMethodItem.java @@ -28,18 +28,18 @@ package org.jf.baksmali.Adaptors.Format; -import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.jf.dexlib.Code.Format.Instruction20t; import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.MethodDefinition; -public class Instruction20tMethodItem extends InstructionFormatMethodItem { - public Instruction20tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, - Instruction20t instruction) { - super(codeItem, offset, stg, instruction); +public class Instruction20tMethodItem extends OffsetInstructionFormatMethodItem { + public Instruction20tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset, + StringTemplateGroup stg, Instruction20t instruction) { + super(labelCache, codeItem, offset, stg, instruction); } - protected void setAttributes(StringTemplate template) { - template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset())); + protected String getLabelPrefix() { + return "goto_"; } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction21tMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction21tMethodItem.java index 8185564a..e5666ca1 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction21tMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction21tMethodItem.java @@ -32,15 +32,20 @@ import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.jf.dexlib.Code.Format.Instruction21t; import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.MethodDefinition; -public class Instruction21tMethodItem extends InstructionFormatMethodItem { - public Instruction21tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, - Instruction21t instruction) { - super(codeItem, offset, stg, instruction); +public class Instruction21tMethodItem extends OffsetInstructionFormatMethodItem { + public Instruction21tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset, + StringTemplateGroup stg, Instruction21t instruction) { + super(labelCache, codeItem, offset, stg, instruction); } protected void setAttributes(StringTemplate template) { + super.setAttributes(template); template.setAttribute("Register", formatRegister(instruction.getRegister())); - template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset())); + } + + protected String getLabelPrefix() { + return "cond_"; } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction22tMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction22tMethodItem.java index 4f0e958c..5d1908d3 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction22tMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction22tMethodItem.java @@ -32,16 +32,21 @@ import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.jf.dexlib.Code.Format.Instruction22t; import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.MethodDefinition; -public class Instruction22tMethodItem extends InstructionFormatMethodItem { - public Instruction22tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, - Instruction22t instruction) { - super(codeItem, offset, stg, instruction); +public class Instruction22tMethodItem extends OffsetInstructionFormatMethodItem { + public Instruction22tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset, + StringTemplateGroup stg, Instruction22t instruction) { + super(labelCache, codeItem, offset, stg, instruction); } protected void setAttributes(StringTemplate template) { + super.setAttributes(template); template.setAttribute("RegisterA", formatRegister(instruction.getRegisterA())); template.setAttribute("RegisterB", formatRegister(instruction.getRegisterB())); - template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset())); + } + + protected String getLabelPrefix() { + return "cond_"; } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction30tMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction30tMethodItem.java index dfc0d636..d8616fe5 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction30tMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction30tMethodItem.java @@ -28,18 +28,18 @@ package org.jf.baksmali.Adaptors.Format; -import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.jf.dexlib.Code.Format.Instruction30t; import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.MethodDefinition; -public class Instruction30tMethodItem extends InstructionFormatMethodItem { - public Instruction30tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, - Instruction30t instruction) { - super(codeItem, offset, stg, instruction); +public class Instruction30tMethodItem extends OffsetInstructionFormatMethodItem { + public Instruction30tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset, + StringTemplateGroup stg, Instruction30t instruction) { + super(labelCache, codeItem, offset, stg, instruction); } - protected void setAttributes(StringTemplate template) { - template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset())); + protected String getLabelPrefix() { + return "goto_"; } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction31tMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction31tMethodItem.java index 928b656b..06662e3b 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction31tMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/Instruction31tMethodItem.java @@ -31,16 +31,28 @@ package org.jf.baksmali.Adaptors.Format; import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.jf.dexlib.Code.Format.Instruction31t; +import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.MethodDefinition; -public class Instruction31tMethodItem extends InstructionFormatMethodItem { - public Instruction31tMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, - Instruction31t instruction) { - super(codeItem, offset, stg, instruction); +public class Instruction31tMethodItem extends OffsetInstructionFormatMethodItem { + public Instruction31tMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset, + StringTemplateGroup stg, Instruction31t instruction) { + super(labelCache, codeItem, offset, stg, instruction); } protected void setAttributes(StringTemplate template) { + super.setAttributes(template); template.setAttribute("Register", formatRegister(instruction.getRegister())); - template.setAttribute("Target", Integer.toHexString(getOffset() + instruction.getOffset())); + } + + protected String getLabelPrefix() { + if (instruction.opcode == Opcode.FILL_ARRAY_DATA) { + return "array_"; + } + if (instruction.opcode == Opcode.PACKED_SWITCH) { + return "pswitch_data_"; + } + return "sswitch_data_"; } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/OffsetInstructionFormatMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/OffsetInstructionFormatMethodItem.java new file mode 100644 index 00000000..2031d02e --- /dev/null +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/OffsetInstructionFormatMethodItem.java @@ -0,0 +1,60 @@ +/* + * [The "BSD licence"] + * Copyright (c) 2009 Ben Gruver + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.baksmali.Adaptors.Format; + +import org.jf.dexlib.CodeItem; +import org.jf.dexlib.Code.Instruction; +import org.jf.dexlib.Code.OffsetInstruction; +import org.jf.baksmali.Adaptors.LabelMethodItem; +import org.jf.baksmali.Adaptors.MethodDefinition; +import org.antlr.stringtemplate.StringTemplateGroup; +import org.antlr.stringtemplate.StringTemplate; + +public abstract class OffsetInstructionFormatMethodItem + extends InstructionFormatMethodItem { + protected LabelMethodItem label; + + public OffsetInstructionFormatMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset, + StringTemplateGroup stg, T instruction) { + super(codeItem, offset, stg, instruction); + + label = new LabelMethodItem(offset + instruction.getOffset(), stg, getLabelPrefix()); + label = labelCache.internLabel(label); + } + + protected abstract String getLabelPrefix(); + + protected void setAttributes(StringTemplate template) { + template.setAttribute("TargetLabel", label); + } + + public LabelMethodItem getLabel() { + return label; + } +} diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/PackedSwitchMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/PackedSwitchMethodItem.java index 90eb8892..464ed4da 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/PackedSwitchMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/PackedSwitchMethodItem.java @@ -32,34 +32,37 @@ import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.jf.dexlib.Code.Format.PackedSwitchDataPseudoInstruction; import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.LabelMethodItem; +import org.jf.baksmali.Adaptors.MethodDefinition; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -public class PackedSwitchMethodItem extends InstructionFormatMethodItem { - private int baseAddress; +public class PackedSwitchMethodItem extends InstructionFormatMethodItem + implements Iterable { + private List labels = new ArrayList(); - public PackedSwitchMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, - PackedSwitchDataPseudoInstruction instruction, int baseAddress) { + public PackedSwitchMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset, + StringTemplateGroup stg, PackedSwitchDataPseudoInstruction instruction, + int baseAddress) { super(codeItem, offset, stg, instruction); - this.baseAddress = baseAddress; - } - - protected void setAttributes(StringTemplate template) { - template.setAttribute("FirstKey", instruction.getFirstKey()); - template.setAttribute("Targets", getTargets()); - } - - private List getTargets() { - List targets = new ArrayList(); Iterator iterator = instruction.getTargets(); while (iterator.hasNext()) { PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next(); - targets.add(Integer.toHexString(target.target + baseAddress)); + LabelMethodItem label = new LabelMethodItem(baseAddress + target.target, stg, "pswitch_"); + label = labelCache.internLabel(label); + labels.add(label); } + } - return targets; + protected void setAttributes(StringTemplate template) { + template.setAttribute("FirstKey", instruction.getFirstKey()); + template.setAttribute("Targets", labels); + } + + public Iterator iterator() { + return labels.iterator(); } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/SparseSwitchMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/SparseSwitchMethodItem.java index 43ed6c3c..f57e4b17 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/SparseSwitchMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/Format/SparseSwitchMethodItem.java @@ -32,42 +32,60 @@ import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplateGroup; import org.jf.dexlib.Code.Format.SparseSwitchDataPseudoInstruction; import org.jf.dexlib.CodeItem; +import org.jf.baksmali.Adaptors.LabelMethodItem; +import org.jf.baksmali.Adaptors.MethodDefinition; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -public class SparseSwitchMethodItem extends InstructionFormatMethodItem { - private int baseAddress; +public class SparseSwitchMethodItem extends InstructionFormatMethodItem + implements Iterable { + private List targets = new ArrayList(); - public SparseSwitchMethodItem(CodeItem codeItem, int offset, StringTemplateGroup stg, - SparseSwitchDataPseudoInstruction instruction, int baseAddress) { + public SparseSwitchMethodItem(MethodDefinition.LabelCache labelCache, CodeItem codeItem, int offset, + StringTemplateGroup stg, SparseSwitchDataPseudoInstruction instruction, + int baseAddress) { super(codeItem, offset, stg, instruction); - this.baseAddress = baseAddress; - } - - protected void setAttributes(StringTemplate template) { - template.setAttribute("Targets", getTargets()); - } - - private static class SparseSwitchTarget { - public int Value; - public String Target; - } - - private List getTargets() { - List targets = new ArrayList(); Iterator iterator = instruction.getTargets(); - while (iterator.hasNext()) { SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next(); SparseSwitchTarget sparseSwitchTarget = new SparseSwitchTarget(); sparseSwitchTarget.Value = target.value; - sparseSwitchTarget.Target = Integer.toHexString(target.target + baseAddress); + + LabelMethodItem label = new LabelMethodItem(baseAddress + target.target, stg, "sswitch_"); + label = labelCache.internLabel(label); + sparseSwitchTarget.Target = label; + targets.add(sparseSwitchTarget); } + } - return targets; + protected void setAttributes(StringTemplate template) { + template.setAttribute("Targets", targets); + } + + public Iterator iterator() { + return new Iterator() { + private Iterator iterator = targets.iterator(); + + public boolean hasNext() { + return iterator.hasNext(); + } + + public LabelMethodItem next() { + return iterator.next().Target; + } + + public void remove() { + iterator.remove(); + } + }; + } + + private static class SparseSwitchTarget { + public int Value; + public LabelMethodItem Target; } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/LabelMethodItem.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/LabelMethodItem.java index be2f7ab5..f61a5ce0 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/LabelMethodItem.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/LabelMethodItem.java @@ -30,17 +30,18 @@ package org.jf.baksmali.Adaptors; import org.antlr.stringtemplate.StringTemplateGroup; import org.antlr.stringtemplate.StringTemplate; +import org.jf.baksmali.baksmali; public class LabelMethodItem extends MethodItem { private final StringTemplateGroup stg; private final String labelPrefix; - private boolean isCommentedOut = false; + private int labelIndex; + private boolean isCommentedOut = true; - public LabelMethodItem(int offset, StringTemplateGroup stg, String labelPrefix, boolean isCommentedOut) { + public LabelMethodItem(int offset, StringTemplateGroup stg, String labelPrefix) { super(offset); this.stg = stg; this.labelPrefix = labelPrefix; - this.isCommentedOut = isCommentedOut; } public int getSortOrder() { @@ -51,8 +52,8 @@ public class LabelMethodItem extends MethodItem { return isCommentedOut; } - public void setCommentedOut(boolean isCommentedOut) { - this.isCommentedOut = isCommentedOut; + public void setUncommented() { + this.isCommentedOut = false; } public int compareTo(MethodItem methodItem) { @@ -81,13 +82,28 @@ public class LabelMethodItem extends MethodItem { @Override public String toString() { StringTemplate template = stg.getInstanceOf("Label"); - template.setAttribute("CommentedOut", this.isCommentedOut); template.setAttribute("Prefix", labelPrefix); - template.setAttribute("HexOffset", getLabelOffset()); + if (baksmali.useIndexedLabels) { + template.setAttribute("Suffix", Integer.toHexString(labelIndex)); + } else { + template.setAttribute("Suffix", getLabelOffset()); + } return template.toString(); } + public String getLabelPrefix() { + return labelPrefix; + } + public String getLabelOffset() { return getHexOffset(); } + + public int getLabelIndex() { + return labelIndex; + } + + public void setLabelIndex(int labelIndex) { + this.labelIndex = labelIndex; + } } diff --git a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java index 8c93ae92..2119b5ca 100644 --- a/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java +++ b/baksmali/src/main/java/org/jf/baksmali/Adaptors/MethodDefinition.java @@ -36,6 +36,7 @@ import org.jf.dexlib.Code.Format.*; import org.jf.dexlib.Code.Instruction; import org.jf.dexlib.Code.Opcode; import org.jf.dexlib.Code.InstructionIterator; +import org.jf.dexlib.Code.OffsetInstruction; import org.jf.dexlib.Util.AccessFlags; import org.antlr.stringtemplate.StringTemplateGroup; import org.antlr.stringtemplate.StringTemplate; @@ -159,7 +160,14 @@ public class MethodDefinition { MethodItemList methodItemList = new MethodItemList(dexFile, stg, codeItem); methodItemList.generateMethodItemList(); - methodItems.addAll(methodItemList.labels.values()); + for (LabelMethodItem labelMethodItem: methodItemList.labels.getLabels()) { + if (labelMethodItem.isCommentedOut()) { + methodItems.add(new CommentedOutMethodItem(stg, labelMethodItem)); + } else { + methodItems.add(labelMethodItem); + } + } + methodItems.addAll(methodItemList.instructions); methodItems.addAll(methodItemList.blanks); methodItems.addAll(methodItemList.catches); @@ -175,7 +183,8 @@ public class MethodDefinition { private final StringTemplateGroup stg; private final CodeItem codeItem; - public HashMap labels = new HashMap(); + public LabelCache labels = new LabelCache(); + public List instructions = new ArrayList(); public List blanks = new ArrayList(); public List catches = new ArrayList(); @@ -264,8 +273,24 @@ public class MethodDefinition { addTries(); addDebugInfo(); + + if (baksmali.useIndexedLabels) { + setLabelIndexes(); + } } + private void addOffsetInstructionMethodItem(OffsetInstructionFormatMethodItem methodItem, boolean commentedOut, + String comment) { + if (commentedOut) { + instructions.add(new CommentedOutMethodItem(stg, methodItem)); + } else { + instructions.add(methodItem); + LabelMethodItem label = methodItem.getLabel(); + label.setUncommented(); + } + } + + private void addInstructionMethodItem(InstructionFormatMethodItem methodItem, boolean commentedOut, String comment) { if (commentedOut) { @@ -275,26 +300,13 @@ public class MethodDefinition { } } - private void addLabelMethodItem(LabelMethodItem labelMethodItem) { - LabelMethodItem internedLabelMethodItem = labels.get(labelMethodItem); - if (internedLabelMethodItem != null) { - if (!labelMethodItem.isCommentedOut() && internedLabelMethodItem.isCommentedOut()) { - internedLabelMethodItem.setCommentedOut(false); - } - } else { - labels.put(labelMethodItem, labelMethodItem); - } - } - private void addMethodItemsForInstruction(int offset, Instruction instruction, boolean commentedOut, String comment) { switch (instruction.getFormat()) { case Format10t: - addInstructionMethodItem( - new Instruction10tMethodItem(codeItem, offset, stg,(Instruction10t)instruction), + addOffsetInstructionMethodItem( + new Instruction10tMethodItem(labels, codeItem, offset, stg,(Instruction10t)instruction), commentedOut, comment); - addLabelMethodItem(new LabelMethodItem(offset + ((Instruction10t)instruction).getOffset(), stg, - "goto_", commentedOut)); return; case Format10x: addInstructionMethodItem( @@ -317,11 +329,9 @@ public class MethodDefinition { commentedOut, comment); return; case Format20t: - addInstructionMethodItem( - new Instruction20tMethodItem(codeItem, offset, stg, (Instruction20t)instruction), + addOffsetInstructionMethodItem( + new Instruction20tMethodItem(labels, codeItem, offset, stg, (Instruction20t)instruction), commentedOut, comment); - addLabelMethodItem(new LabelMethodItem(offset + ((Instruction20t)instruction).getOffset(), stg, - "goto_", commentedOut)); return; case Format21c: addInstructionMethodItem( @@ -339,11 +349,9 @@ public class MethodDefinition { commentedOut, comment); return; case Format21t: - addInstructionMethodItem( - new Instruction21tMethodItem(codeItem, offset, stg, (Instruction21t)instruction), + addOffsetInstructionMethodItem( + new Instruction21tMethodItem(labels, codeItem, offset, stg, (Instruction21t)instruction), commentedOut, comment); - addLabelMethodItem(new LabelMethodItem(offset + ((Instruction21t)instruction).getOffset(), stg, - "cond_", commentedOut)); return; case Format22b: addInstructionMethodItem( @@ -371,11 +379,9 @@ public class MethodDefinition { commentedOut, comment); return; case Format22t: - addInstructionMethodItem( - new Instruction22tMethodItem(codeItem, offset, stg, (Instruction22t)instruction), + addOffsetInstructionMethodItem( + new Instruction22tMethodItem(labels, codeItem, offset, stg, (Instruction22t)instruction), commentedOut, comment); - addLabelMethodItem(new LabelMethodItem(offset + ((Instruction22t)instruction).getOffset(), stg, - "cond_", commentedOut)); return; case Format22x: addInstructionMethodItem( @@ -388,11 +394,9 @@ public class MethodDefinition { commentedOut, comment); return; case Format30t: - addInstructionMethodItem( - new Instruction30tMethodItem(codeItem, offset, stg, (Instruction30t)instruction), + addOffsetInstructionMethodItem( + new Instruction30tMethodItem(labels, codeItem, offset, stg, (Instruction30t)instruction), commentedOut, comment); - addLabelMethodItem(new LabelMethodItem(offset + ((Instruction30t)instruction).getOffset(), stg, - "goto_", commentedOut)); return; case Format31c: addInstructionMethodItem( @@ -405,19 +409,9 @@ public class MethodDefinition { commentedOut, comment); return; case Format31t: - addInstructionMethodItem( - new Instruction31tMethodItem(codeItem, offset, stg, (Instruction31t)instruction), + addOffsetInstructionMethodItem( + new Instruction31tMethodItem(labels, codeItem, offset, stg, (Instruction31t)instruction), commentedOut, comment); - if (instruction.opcode == Opcode.FILL_ARRAY_DATA) { - addLabelMethodItem(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), stg, - "array_", commentedOut)); - } else if (instruction.opcode == Opcode.PACKED_SWITCH) { - addLabelMethodItem(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), stg, - "pswitch_data_", commentedOut)); - } else if (instruction.opcode == Opcode.SPARSE_SWITCH) { - addLabelMethodItem(new LabelMethodItem(offset + ((Instruction31t)instruction).getOffset(), stg, - "sswitch_data_", commentedOut)); - } return; case Format32x: addInstructionMethodItem( @@ -482,16 +476,14 @@ public class MethodDefinition { PackedSwitchDataPseudoInstruction packedSwitchInstruction = (PackedSwitchDataPseudoInstruction)instruction; - addInstructionMethodItem( - new PackedSwitchMethodItem(codeItem, offset, stg, packedSwitchInstruction, baseAddress), - commentedOut, comment); + PackedSwitchMethodItem packedSwitch = new PackedSwitchMethodItem(labels, codeItem, offset, stg, + packedSwitchInstruction, baseAddress); + addInstructionMethodItem(packedSwitch, commentedOut, comment); - Iterator iterator = - packedSwitchInstruction.getTargets(); - while (iterator.hasNext()) { - PackedSwitchDataPseudoInstruction.PackedSwitchTarget target = iterator.next(); - addLabelMethodItem(new LabelMethodItem(baseAddress + target.target, stg, "pswitch_", - commentedOut)); + if (!commentedOut) { + for (LabelMethodItem label: packedSwitch) { + label.setUncommented(); + } } } return; @@ -504,16 +496,14 @@ public class MethodDefinition { SparseSwitchDataPseudoInstruction sparseSwitchInstruction = (SparseSwitchDataPseudoInstruction)instruction; - addInstructionMethodItem( - new SparseSwitchMethodItem(codeItem, offset, stg, sparseSwitchInstruction, baseAddress), - commentedOut, comment); + SparseSwitchMethodItem sparseSwitch = new SparseSwitchMethodItem(labels, codeItem, offset, stg, + sparseSwitchInstruction, baseAddress); + addInstructionMethodItem(sparseSwitch, commentedOut, comment); - Iterator iterator = - sparseSwitchInstruction.getTargets(); - while (iterator.hasNext()) { - SparseSwitchDataPseudoInstruction.SparseSwitchTarget target = iterator.next(); - addLabelMethodItem(new LabelMethodItem(baseAddress + target.target, stg, "sswitch_", - commentedOut)); + if (!commentedOut) { + for (LabelMethodItem label: sparseSwitch) { + label.setUncommented(); + } } } return; @@ -575,35 +565,17 @@ public class MethodDefinition { //add the catch all handler if it exists int catchAllAddress = tryItem.encodedCatchHandler.catchAllHandlerAddress; if (catchAllAddress != -1) { - CatchMethodItem catchMethodItem = new CatchMethodItem(lastInstructionOffset, stg, null, - startAddress, endAddress, catchAllAddress) { - public String getTemplateName() { - return "CatchAll"; - } - }; + CatchMethodItem catchMethodItem = new CatchMethodItem(labels, lastInstructionOffset, stg, null, + startAddress, endAddress, catchAllAddress); catches.add(catchMethodItem); - - addLabelMethodItem(new LabelMethodItem(startAddress, stg, "try_start_", false)); - //use the offset from the last covered instruction, but make the label - //name refer to the address of the next instruction - addLabelMethodItem(new EndTryLabelMethodItem(lastInstructionOffset, stg, endAddress)); - addLabelMethodItem(new LabelMethodItem(catchAllAddress, stg, "handler_", false)); - } //add the rest of the handlers - //TODO: find adjacent handlers for the same type and combine them for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) { //use the offset from the last covered instruction - CatchMethodItem catchMethodItem = new CatchMethodItem(lastInstructionOffset, stg, + CatchMethodItem catchMethodItem = new CatchMethodItem(labels, lastInstructionOffset, stg, handler.exceptionType, startAddress, endAddress, handler.handlerAddress); catches.add(catchMethodItem); - - addLabelMethodItem(new LabelMethodItem(startAddress, stg, "try_start_", false)); - //use the offset from the last covered instruction, but make the label - //name refer to the address of the next instruction - addLabelMethodItem(new EndTryLabelMethodItem(lastInstructionOffset, stg, endAddress)); - addLabelMethodItem(new LabelMethodItem(handler.handlerAddress, stg, "handler_", false)); } } } @@ -676,5 +648,46 @@ public class MethodDefinition { } }); } + + private void setLabelIndexes() { + HashMap nextLabelIndexByType = new HashMap(); + ArrayList sortedLabels = new ArrayList(labels.getLabels()); + + //sort the labels by their location in the method + Collections.sort(sortedLabels); + + for (LabelMethodItem labelMethodItem: sortedLabels) { + Integer labelIndex = nextLabelIndexByType.get(labelMethodItem.getLabelPrefix()); + if (labelIndex == null) { + labelIndex = 0; + } + labelMethodItem.setLabelIndex(labelIndex); + nextLabelIndexByType.put(labelMethodItem.getLabelPrefix(), labelIndex + 1); + } + } + } + + public static class LabelCache { + protected HashMap labels = new HashMap(); + + public LabelCache() { + } + + public LabelMethodItem internLabel(LabelMethodItem labelMethodItem) { + LabelMethodItem internedLabelMethodItem = labels.get(labelMethodItem); + if (internedLabelMethodItem != null) { + if (!labelMethodItem.isCommentedOut()) { + internedLabelMethodItem.setUncommented(); + } + return internedLabelMethodItem; + } + labels.put(labelMethodItem, labelMethodItem); + return labelMethodItem; + } + + + public Collection getLabels() { + return labels.values(); + } } } diff --git a/baksmali/src/main/java/org/jf/baksmali/baksmali.java b/baksmali/src/main/java/org/jf/baksmali/baksmali.java index 841b87ca..d70eb9c5 100644 --- a/baksmali/src/main/java/org/jf/baksmali/baksmali.java +++ b/baksmali/src/main/java/org/jf/baksmali/baksmali.java @@ -43,13 +43,17 @@ import java.io.*; public class baksmali { public static boolean noParameterRegisters = false; public static boolean useLocalsDirective = false; + public static boolean useIndexedLabels = false; public static DeodexUtil deodexUtil = null; public static void disassembleDexFile(DexFile dexFile, Deodexerant deodexerant, String outputDirectory, - boolean noParameterRegisters, boolean useLocalsDirective) + boolean noParameterRegisters, boolean useLocalsDirective, + boolean useIndexedLabels) { baksmali.noParameterRegisters = noParameterRegisters; baksmali.useLocalsDirective = useLocalsDirective; + baksmali.useIndexedLabels = useIndexedLabels; + if (deodexerant != null) { baksmali.deodexUtil = new DeodexUtil(deodexerant); } diff --git a/baksmali/src/main/java/org/jf/baksmali/main.java b/baksmali/src/main/java/org/jf/baksmali/main.java index af396df6..a30da920 100644 --- a/baksmali/src/main/java/org/jf/baksmali/main.java +++ b/baksmali/src/main/java/org/jf/baksmali/main.java @@ -73,6 +73,7 @@ public class main { boolean fixRegisters = false; boolean noParameterRegisters = false; boolean useLocalsDirective = false; + boolean useIndexedLabels = false; String outputDirectory = "out"; @@ -135,6 +136,10 @@ public class main { useLocalsDirective = true; } + if (commandLine.hasOption("i")) { + useIndexedLabels = true; + } + if (commandLine.hasOption("x")) { String deodexerantAddress = commandLine.getOptionValue("x"); String[] parts = deodexerantAddress.split(":"); @@ -186,7 +191,7 @@ public class main { if (disassemble) { baksmali.disassembleDexFile(dexFile, deodexerant, outputDirectory, noParameterRegisters, - useLocalsDirective); + useLocalsDirective, useIndexedLabels); } if ((doDump || write) && !dexFile.isOdex()) { @@ -282,10 +287,15 @@ public class main { .create("x"); Option useLocalsOption = OptionBuilder.withLongOpt("use-locals") - .withDescription("output the .locals directive with the number of non-parameter registers, instead of" + - " the .register directive with the total number of register") + .withDescription("output the .locals directive with the number of non-parameter registers, rather" + + " than the .register directive with the total number of register") .create("l"); + Option indexedLabelsOption = OptionBuilder.withLongOpt("indexed-labels") + .withDescription("create label names using a per-method/per-label-type auto-index as the suffix, " + + " rather than the bytecode offset") + .create("i"); + OptionGroup dumpCommand = new OptionGroup(); options.addOption(versionOption); @@ -299,5 +309,6 @@ public class main { options.addOption(noParameterRegistersOption); options.addOption(deodexerantOption); options.addOption(useLocalsOption); + options.addOption(indexedLabelsOption); } } \ No newline at end of file diff --git a/baksmali/src/main/resources/templates/templates/baksmali.stg b/baksmali/src/main/resources/templates/templates/baksmali.stg index 2c1b00ac..26cf0927 100644 --- a/baksmali/src/main/resources/templates/templates/baksmali.stg +++ b/baksmali/src/main/resources/templates/templates/baksmali.stg @@ -123,18 +123,9 @@ Parameter(ParameterName, Annotations) ::= >> - - -Format31tLabelMap ::= [ - "fill-array-data":"array_", - "packed-switch":"pswitch_data_", - "sparse-switch":"sswitch_data_" -] - - -Format10t(Opcode, Target) ::= +Format10t(Opcode, TargetLabel) ::= << - :goto_ + >> Format10x(Opcode) ::= @@ -157,9 +148,9 @@ Format12x(Opcode, RegisterA, RegisterB) ::= , >> -Format20t(Opcode, Target) ::= +Format20t(Opcode, TargetLabel) ::= << - :goto_ + >> Format21c(Opcode, Register, Reference) ::= @@ -177,9 +168,9 @@ Format21s(Opcode, Register, Literal) ::= , >> -Format21t(Opcode, Register, Target) ::= +Format21t(Opcode, Register, TargetLabel) ::= << - , :cond_ + , >> Format22b(Opcode, RegisterA, RegisterB, Literal) ::= @@ -207,9 +198,9 @@ Format22s(Opcode, RegisterA, RegisterB, Literal) ::= , , >> -Format22t(Opcode, RegisterA, RegisterB, Target) ::= +Format22t(Opcode, RegisterA, RegisterB, TargetLabel) ::= << - , , :cond_ + , , >> Format22x(Opcode, RegisterA, RegisterB) ::= @@ -222,9 +213,9 @@ Format23x(Opcode, RegisterA, RegisterB, RegisterC) ::= , , >> -Format30t(Opcode, Target) ::= +Format30t(Opcode, TargetLabel) ::= << - :goto_ + >> Format31c(Opcode, Register, Reference) ::= @@ -237,9 +228,9 @@ Format31i(Opcode, Register, Literal) ::= , >> -Format31t(Opcode, Register, Target) ::= +Format31t(Opcode, Register, TargetLabel) ::= << - , : + , >> Format32x(Opcode, RegisterA, RegisterB) ::= @@ -322,21 +313,21 @@ ArrayElement(Bytes) ::= PackedSwitchData(Opcode, FirstKey, Targets) ::= << .packed-switch - }; separator="\n"> + }; separator="\n"> .end packed-switch >> SparseSwitchData(Opcode, Targets) ::= << .sparse-switch - -> :sswitch_}; separator="\n"> + -> }; separator="\n"> .end sparse-switch >> -Label(Prefix, HexOffset, CommentedOut) ::= +Label(Prefix, Suffix) ::= << -#: +: >> Line(Line) ::= @@ -379,17 +370,11 @@ Blank(Blank) ::= >> -Catch(ExceptionType, StartAddress, EndAddress, HandlerAddress) ::= +Catch(ExceptionType, StartLabel, EndLabel, HandlerLabel) ::= << -.catch {:try_start_ .. :try_end_} :handler_ +.catch .catchall { .. } >> -CatchAll(StartAddress, EndAddress, HandlerAddress) ::= -<< -.catchall {:try_start_ .. :try_end_} :handler_ ->> - - StringReference(EscapedValue) ::= <<