Commit fb43d716 authored by Skylot's avatar Skylot

Replace constants with matched static final fields

parent 3598a127
...@@ -87,9 +87,9 @@ public class ClassNode extends AttrNode implements ILoadable { ...@@ -87,9 +87,9 @@ public class ClassNode extends AttrNode implements ILoadable {
setFieldsTypesFromSignature(); setFieldsTypesFromSignature();
int sfIdx = cls.getSourceFileIndex(); int sfIdx = cls.getSourceFileIndex();
if(sfIdx != DexNode.NO_INDEX) { if (sfIdx != DexNode.NO_INDEX) {
String fileName = dex.getString(sfIdx); String fileName = dex.getString(sfIdx);
if(!this.getFullName().contains(fileName.replace(".java", ""))) { if (!this.getFullName().contains(fileName.replace(".java", ""))) {
this.getAttributes().add(new SourceFileAttr(fileName)); this.getAttributes().add(new SourceFileAttr(fileName));
LOG.debug("Class '{}' compiled from '{}'", this, fileName); LOG.debug("Class '{}' compiled from '{}'", this, fileName);
} }
...@@ -134,10 +134,14 @@ public class ClassNode extends AttrNode implements ILoadable { ...@@ -134,10 +134,14 @@ public class ClassNode extends AttrNode implements ILoadable {
parser.processFields(staticFields); parser.processFields(staticFields);
for (FieldNode f : staticFields) { for (FieldNode f : staticFields) {
if (f.getType().equals(ArgType.STRING)) { AccessInfo accFlags = f.getAccessFlags();
if (accFlags.isStatic() && accFlags.isFinal()) {
FieldValueAttr fv = (FieldValueAttr) f.getAttributes().get(AttributeType.FIELD_VALUE); FieldValueAttr fv = (FieldValueAttr) f.getAttributes().get(AttributeType.FIELD_VALUE);
if (fv != null && fv.getValue() != null) { if (fv != null && fv.getValue() != null) {
constFields.put(fv.getValue(), f); if (accFlags.isPublic())
dex.getConstFields().put(fv.getValue(), f);
else
constFields.put(fv.getValue(), f);
} }
} }
} }
...@@ -231,6 +235,13 @@ public class ClassNode extends AttrNode implements ILoadable { ...@@ -231,6 +235,13 @@ public class ClassNode extends AttrNode implements ILoadable {
return fields; return fields;
} }
public FieldNode getConstField(Object o) {
FieldNode field = constFields.get(o);
if(field == null)
field = dex.getConstFields().get(o);
return field;
}
public FieldNode searchFieldById(int id) { public FieldNode searchFieldById(int id) {
String name = FieldInfo.getNameById(dex, id); String name = FieldInfo.getNameById(dex, id);
for (FieldNode f : fields) { for (FieldNode f : fields) {
...@@ -295,10 +306,6 @@ public class ClassNode extends AttrNode implements ILoadable { ...@@ -295,10 +306,6 @@ public class ClassNode extends AttrNode implements ILoadable {
return accessFlags; return accessFlags;
} }
public Map<Object, FieldNode> getConstFields() {
return constFields;
}
public DexNode dex() { public DexNode dex() {
return dex; return dex;
} }
...@@ -323,5 +330,4 @@ public class ClassNode extends AttrNode implements ILoadable { ...@@ -323,5 +330,4 @@ public class ClassNode extends AttrNode implements ILoadable {
public String toString() { public String toString() {
return getFullName(); return getFullName();
} }
} }
...@@ -7,7 +7,9 @@ import jadx.utils.exceptions.DecodeException; ...@@ -7,7 +7,9 @@ import jadx.utils.exceptions.DecodeException;
import jadx.utils.files.InputFile; import jadx.utils.files.InputFile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import com.android.dx.io.ClassData; import com.android.dx.io.ClassData;
import com.android.dx.io.ClassData.Method; import com.android.dx.io.ClassData.Method;
...@@ -29,6 +31,8 @@ public class DexNode { ...@@ -29,6 +31,8 @@ public class DexNode {
private final List<ClassNode> classes = new ArrayList<ClassNode>(); private final List<ClassNode> classes = new ArrayList<ClassNode>();
private final String[] strings; private final String[] strings;
private final Map<Object, FieldNode> constFields = new HashMap<Object, FieldNode>();
public DexNode(RootNode root, InputFile input) { public DexNode(RootNode root, InputFile input) {
this.root = root; this.root = root;
this.dexBuf = input.getDexBuffer(); this.dexBuf = input.getDexBuffer();
...@@ -59,6 +63,10 @@ public class DexNode { ...@@ -59,6 +63,10 @@ public class DexNode {
return null; return null;
} }
public Map<Object, FieldNode> getConstFields() {
return constFields;
}
// DexBuffer wrappers // DexBuffer wrappers
public String getString(int index) { public String getString(int index) {
...@@ -110,5 +118,4 @@ public class DexNode { ...@@ -110,5 +118,4 @@ public class DexNode {
public String toString() { public String toString() {
return "DEX"; return "DEX";
} }
} }
...@@ -3,7 +3,6 @@ package jadx.dex.nodes; ...@@ -3,7 +3,6 @@ package jadx.dex.nodes;
import jadx.dex.attributes.AttrNode; import jadx.dex.attributes.AttrNode;
import jadx.dex.info.AccessInfo; import jadx.dex.info.AccessInfo;
import jadx.dex.info.AccessInfo.AFType; import jadx.dex.info.AccessInfo.AFType;
import jadx.dex.info.ClassInfo;
import jadx.dex.info.FieldInfo; import jadx.dex.info.FieldInfo;
import jadx.dex.instructions.args.ArgType; import jadx.dex.instructions.args.ArgType;
...@@ -11,26 +10,27 @@ import com.android.dx.io.ClassData.Field; ...@@ -11,26 +10,27 @@ import com.android.dx.io.ClassData.Field;
public class FieldNode extends AttrNode { public class FieldNode extends AttrNode {
private final FieldInfo fieldInfo;
private final AccessInfo accFlags; private final AccessInfo accFlags;
private final String name;
private final ClassInfo declClass;
private ArgType type; private ArgType type; // store signature
public FieldNode(ClassNode cls, Field field) { public FieldNode(ClassNode cls, Field field) {
FieldInfo f = FieldInfo.fromDex(cls.dex(), field.getFieldIndex()); this.fieldInfo = FieldInfo.fromDex(cls.dex(), field.getFieldIndex());
this.name = f.getName(); this.type = fieldInfo.getType();
this.type = f.getType();
this.declClass = f.getDeclClass();
this.accFlags = new AccessInfo(field.getAccessFlags(), AFType.FIELD); this.accFlags = new AccessInfo(field.getAccessFlags(), AFType.FIELD);
} }
public FieldInfo getFieldInfo() {
return fieldInfo;
}
public AccessInfo getAccessFlags() { public AccessInfo getAccessFlags() {
return accFlags; return accFlags;
} }
public String getName() { public String getName() {
return name; return fieldInfo.getName();
} }
public ArgType getType() { public ArgType getType() {
...@@ -41,12 +41,8 @@ public class FieldNode extends AttrNode { ...@@ -41,12 +41,8 @@ public class FieldNode extends AttrNode {
this.type = type; this.type = type;
} }
public ClassInfo getDeclClass() {
return declClass;
}
@Override @Override
public String toString() { public String toString() {
return declClass + "." + name + " " + type; return fieldInfo.getDeclClass() + "." + fieldInfo.getName() + " " + type;
} }
} }
...@@ -7,10 +7,13 @@ import jadx.dex.info.MethodInfo; ...@@ -7,10 +7,13 @@ import jadx.dex.info.MethodInfo;
import jadx.dex.instructions.IndexInsnNode; import jadx.dex.instructions.IndexInsnNode;
import jadx.dex.instructions.InsnType; import jadx.dex.instructions.InsnType;
import jadx.dex.instructions.InvokeNode; import jadx.dex.instructions.InvokeNode;
import jadx.dex.instructions.args.ArgType;
import jadx.dex.instructions.args.InsnArg; import jadx.dex.instructions.args.InsnArg;
import jadx.dex.instructions.args.LiteralArg;
import jadx.dex.instructions.args.RegisterArg; import jadx.dex.instructions.args.RegisterArg;
import jadx.dex.instructions.mods.ConstructorInsn; import jadx.dex.instructions.mods.ConstructorInsn;
import jadx.dex.nodes.BlockNode; import jadx.dex.nodes.BlockNode;
import jadx.dex.nodes.ClassNode;
import jadx.dex.nodes.FieldNode; import jadx.dex.nodes.FieldNode;
import jadx.dex.nodes.InsnNode; import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode; import jadx.dex.nodes.MethodNode;
...@@ -96,15 +99,31 @@ public class ModVisitor extends AbstractVisitor { ...@@ -96,15 +99,31 @@ public class ModVisitor extends AbstractVisitor {
break; break;
case CONST: case CONST:
ClassNode parentClass = mth.getParentClass();
FieldNode f = null;
if (insn.getArgsCount() == 0) { if (insn.getArgsCount() == 0) {
// const-string // const-string
IndexInsnNode node = (IndexInsnNode) insn; IndexInsnNode node = (IndexInsnNode) insn;
FieldNode f = mth.getParentClass().getConstFields().get(node.getIndex()); f = parentClass.getConstField(node.getIndex());
if (f != null) { } else {
InsnNode inode = new IndexInsnNode(InsnType.SGET, f, 0); LiteralArg arg = (LiteralArg) insn.getArg(0);
inode.setResult(insn.getResult()); ArgType type = arg.getType();
replaceInsn(block, i, inode); long lit = arg.getLiteral();
if (Math.abs(lit) > 0xFF) {
if (type.equals(ArgType.INT))
f = parentClass.getConstField((int) lit);
else if (type.equals(ArgType.LONG))
f = parentClass.getConstField(lit);
} }
if (type.equals(ArgType.DOUBLE))
f = parentClass.getConstField(Double.longBitsToDouble(lit));
else if (type.equals(ArgType.FLOAT))
f = parentClass.getConstField(Float.intBitsToFloat((int) lit));
}
if (f != null) {
InsnNode inode = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0);
inode.setResult(insn.getResult());
replaceInsn(block, i, inode);
} }
break; break;
...@@ -233,10 +252,10 @@ public class ModVisitor extends AbstractVisitor { ...@@ -233,10 +252,10 @@ public class ModVisitor extends AbstractVisitor {
} }
private void checkArgsNames(MethodNode mth) { private void checkArgsNames(MethodNode mth) {
for(RegisterArg arg : mth.getArguments(false)) { for (RegisterArg arg : mth.getArguments(false)) {
String name = arg.getTypedVar().getName(); String name = arg.getTypedVar().getName();
if(name != null && NameMapper.isReserved(name)) { if (name != null && NameMapper.isReserved(name)) {
name = name + "_" ; name = name + "_";
arg.getTypedVar().setName(name); arg.getTypedVar().setName(name);
} }
} }
......
...@@ -407,12 +407,7 @@ public class RegionMaker { ...@@ -407,12 +407,7 @@ public class RegionMaker {
otherNode.invertOp(elseOffset); otherNode.invertOp(elseOffset);
} }
IfCondition newArg = IfCondition.fromIfBlock(pred); IfCondition newArg = IfCondition.fromIfBlock(pred);
IfCondition condition; IfCondition condition = IfCondition.and(ifRegion.getCondition(), newArg);
if (otherNode.getTarget() != pred.getStartOffset()) {
condition = IfCondition.and(ifRegion.getCondition(), newArg);
} else {
condition = IfCondition.or(ifRegion.getCondition(), newArg);
}
ifRegion.setCondition(condition); ifRegion.setCondition(condition);
pred.getAttributes().add(AttributeFlag.SKIP); pred.getAttributes().add(AttributeFlag.SKIP);
} }
......
...@@ -4,6 +4,14 @@ import java.util.Arrays; ...@@ -4,6 +4,14 @@ import java.util.Arrays;
public class TestFields extends AbstractTest { public class TestFields extends AbstractTest {
public static class ConstFields {
public static final boolean BOOL = false;
public static final int CONST_INT = 56789;
public static final int ZERO = 0;
public static final String STR = "string";
public static final double PI = 3.14;
}
private static final boolean fbz = false; private static final boolean fbz = false;
private static final boolean fb = true; private static final boolean fb = true;
private static final int fi = 5; private static final int fi = 5;
...@@ -12,14 +20,28 @@ public class TestFields extends AbstractTest { ...@@ -12,14 +20,28 @@ public class TestFields extends AbstractTest {
private static final String fstr = "final string"; private static final String fstr = "final string";
private static final double fd = 3.14; private static final double fd = 3.14;
private static final double[] fda = new double[] { 3.14, 2.7 }; private static final double[] fda = new double[]{3.14, 2.7};
private static int si = 5; private static int si = 5;
public void testConstsFields() {
int r = ConstFields.CONST_INT;
r += ConstFields.BOOL ? 1 : 0;
r += ConstFields.ZERO * 5;
r += ConstFields.STR.length() + ConstFields.STR.indexOf('i');
r += Math.round(ConstFields.PI);
assertEquals(r, 56801);
}
@Override @Override
public boolean testRun() throws Exception { public boolean testRun() throws Exception {
testConstsFields();
String str = "" + fbz + fiz + fb + fi + fstr + fd + Arrays.toString(fda) + si; String str = "" + fbz + fiz + fb + fi + fstr + fd + Arrays.toString(fda) + si;
return str.equals("false0true5final string3.14[3.14, 2.7]5"); return str.equals("false0true5final string3.14[3.14, 2.7]5");
} }
public static void main(String[] args) throws Exception {
new TestFields().testRun();
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment