diff --git a/src/brut/androlib/src/DebugInjector.java b/src/brut/androlib/src/DebugInjector.java index 4dd08bb4..e90f614a 100644 --- a/src/brut/androlib/src/DebugInjector.java +++ b/src/brut/androlib/src/DebugInjector.java @@ -17,7 +17,10 @@ package brut.androlib.src; import brut.androlib.AndrolibException; -import java.util.ListIterator; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.jf.dexlib.Code.Analysis.RegisterType; import org.jf.dexlib.Code.Opcode; /** @@ -76,7 +79,7 @@ public class DebugInjector { switch (line.charAt(0)) { case '#': - return false; + return processComment(line); case ':': append(line); return false; @@ -87,6 +90,72 @@ public class DebugInjector { } } + private boolean processComment(String line) { + if (mFirstInstruction) { + return false; + } + + Matcher m = REGISTER_INFO_PATTERN.matcher(line); + + while (m.find()) { + String localName = m.group(1); + String localType = null; + switch (RegisterType.Category.valueOf(m.group(2))) { + case Reference: + case Null: + case UninitRef: + case UninitThis: + localType = "Ljava/lang/Object;"; + break; + case Boolean: + localType = "Z"; + break; + case Integer: + case One: + case Unknown: + localType = "I"; + break; + case Uninit: + case Conflicted: + if (mInitializedRegisters.remove(localName)) { + mOut.append(".end local ").append(localName) + .append('\n'); + } + continue; + case Short: + case PosShort: + localType = "S"; + break; + case Byte: + case PosByte: + localType = "B"; + break; + case Char: + localType = "C"; + break; + case Float: + localType = "F"; + break; + case LongHi: + case LongLo: + localType = "J"; + break; + case DoubleHi: + case DoubleLo: + localType = "D"; + break; + default: + assert false; + } + + mInitializedRegisters.add(localName); + mOut.append(".local ").append(localName).append(", ") + .append(localName).append(':').append(localType).append('\n'); + } + + return false; + } + private boolean processDirective(String line) { String line2 = line.substring(1); if ( @@ -126,84 +195,9 @@ public class DebugInjector { mOut.append(".line ").append(mIt.nextIndex()).append('\n') .append(line).append('\n'); - int pos = line.indexOf(' '); - if (pos == -1) { - return false; - } - Opcode opcode = Opcode.getOpcodeByName(line.substring(0, pos)); - if (! opcode.setsRegister()) { - return false; - } - - int pos2 = line.indexOf(',', pos); - String register = pos2 == -1 ? line.substring(pos + 1) : - line.substring(pos + 1, pos2); - - mOut.append(".local ").append(register).append(", ").append(register) - .append(':').append(getRegisterTypeForOpcode(opcode)).append('\n'); - return false; } - private String getRegisterTypeForOpcode(Opcode opcode) { - switch (opcode.value) { - case (byte)0x0d: // ? - case (byte)0x1a: - case (byte)0x1b: - case (byte)0x1c: // ? - case (byte)0x22: - case (byte)0x23: // ? - case (byte)0xf4: // ? - return "Ljava/lang/Object;"; - case (byte)0x1f: // ? - case (byte)0x20: // ? - return "Z"; - case (byte)0x21: // ? - return "I"; - } - - String name = opcode.name; - int pos = name.lastIndexOf('-'); - if (pos != -1) { - int pos2 = name.indexOf('/'); - String type = pos2 == -1 ? name.substring(pos + 1) : - name.substring(pos + 1, pos2); - - if (type.equals("object")) { - return "Ljava/lang/Object;"; - } - if (type.equals("int")) { - return "I"; - } - if (type.equals("boolean")) { - return "Z"; - } - if (type.equals("float")) { - return "F"; - } - if (type.equals("double")) { - return "D"; - } - if (type.equals("long")) { - return "J"; - } - if (type.equals("byte")) { - return "B"; - } - if (type.equals("char")) { - return "C"; - } - if (type.equals("short")) { - return "S"; - } - if (type.equals("long")) { - return "J"; - } - } - - return "I"; - } - private String next() { return mIt.next().trim(); } @@ -222,4 +216,8 @@ public class DebugInjector { private final StringBuilder mOut; private boolean mFirstInstruction = true; + private final Set mInitializedRegisters = new HashSet(); + + private static final Pattern REGISTER_INFO_PATTERN = + Pattern.compile("((?:p|v)\\d+)=\\(([^)]+)\\);"); } diff --git a/src/brut/androlib/src/SmaliDecoder.java b/src/brut/androlib/src/SmaliDecoder.java index 22e1493e..33d55b1f 100644 --- a/src/brut/androlib/src/SmaliDecoder.java +++ b/src/brut/androlib/src/SmaliDecoder.java @@ -22,6 +22,7 @@ import java.io.*; import org.jf.baksmali.Adaptors.ClassDefinition; import org.jf.baksmali.baksmali; import org.jf.dexlib.ClassDefItem; +import org.jf.dexlib.Code.Analysis.ClassPath; import org.jf.dexlib.DexFile; /** @@ -44,6 +45,10 @@ public class SmaliDecoder { try { baksmali.useLocalsDirective = true; baksmali.useSequentialLabels = true; + if (mDebug) { + baksmali.registerInfo = org.jf.baksmali.main.DIFFPRE; + ClassPath.dontLoadClassPath = true; + } DexFile dexFile = new DexFile(mApkFile); for (ClassDefItem classDefItem :