mirror of
https://github.com/revanced/Apktool.git
synced 2024-09-05 22:16:13 +02:00
DebugInjector: types recognition using dexlib code analyzer.
This commit is contained in:
parent
d459a4bb8b
commit
e6d2e9c605
@ -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<String> mInitializedRegisters = new HashSet<String>();
|
||||
|
||||
private static final Pattern REGISTER_INFO_PATTERN =
|
||||
Pattern.compile("((?:p|v)\\d+)=\\(([^)]+)\\);");
|
||||
}
|
||||
|
@ -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 :
|
||||
|
Loading…
Reference in New Issue
Block a user