提交 fb43d716 编写于 作者: S Skylot

Replace constants with matched static final fields

上级 3598a127
......@@ -87,9 +87,9 @@ public class ClassNode extends AttrNode implements ILoadable {
setFieldsTypesFromSignature();
int sfIdx = cls.getSourceFileIndex();
if(sfIdx != DexNode.NO_INDEX) {
if (sfIdx != DexNode.NO_INDEX) {
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));
LOG.debug("Class '{}' compiled from '{}'", this, fileName);
}
......@@ -134,10 +134,14 @@ public class ClassNode extends AttrNode implements ILoadable {
parser.processFields(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);
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 {
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) {
String name = FieldInfo.getNameById(dex, id);
for (FieldNode f : fields) {
......@@ -295,10 +306,6 @@ public class ClassNode extends AttrNode implements ILoadable {
return accessFlags;
}
public Map<Object, FieldNode> getConstFields() {
return constFields;
}
public DexNode dex() {
return dex;
}
......@@ -323,5 +330,4 @@ public class ClassNode extends AttrNode implements ILoadable {
public String toString() {
return getFullName();
}
}
......@@ -7,7 +7,9 @@ import jadx.utils.exceptions.DecodeException;
import jadx.utils.files.InputFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.android.dx.io.ClassData;
import com.android.dx.io.ClassData.Method;
......@@ -29,6 +31,8 @@ public class DexNode {
private final List<ClassNode> classes = new ArrayList<ClassNode>();
private final String[] strings;
private final Map<Object, FieldNode> constFields = new HashMap<Object, FieldNode>();
public DexNode(RootNode root, InputFile input) {
this.root = root;
this.dexBuf = input.getDexBuffer();
......@@ -59,6 +63,10 @@ public class DexNode {
return null;
}
public Map<Object, FieldNode> getConstFields() {
return constFields;
}
// DexBuffer wrappers
public String getString(int index) {
......@@ -110,5 +118,4 @@ public class DexNode {
public String toString() {
return "DEX";
}
}
......@@ -3,7 +3,6 @@ package jadx.dex.nodes;
import jadx.dex.attributes.AttrNode;
import jadx.dex.info.AccessInfo;
import jadx.dex.info.AccessInfo.AFType;
import jadx.dex.info.ClassInfo;
import jadx.dex.info.FieldInfo;
import jadx.dex.instructions.args.ArgType;
......@@ -11,26 +10,27 @@ import com.android.dx.io.ClassData.Field;
public class FieldNode extends AttrNode {
private final FieldInfo fieldInfo;
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) {
FieldInfo f = FieldInfo.fromDex(cls.dex(), field.getFieldIndex());
this.name = f.getName();
this.type = f.getType();
this.declClass = f.getDeclClass();
this.fieldInfo = FieldInfo.fromDex(cls.dex(), field.getFieldIndex());
this.type = fieldInfo.getType();
this.accFlags = new AccessInfo(field.getAccessFlags(), AFType.FIELD);
}
public FieldInfo getFieldInfo() {
return fieldInfo;
}
public AccessInfo getAccessFlags() {
return accFlags;
}
public String getName() {
return name;
return fieldInfo.getName();
}
public ArgType getType() {
......@@ -41,12 +41,8 @@ public class FieldNode extends AttrNode {
this.type = type;
}
public ClassInfo getDeclClass() {
return declClass;
}
@Override
public String toString() {
return declClass + "." + name + " " + type;
return fieldInfo.getDeclClass() + "." + fieldInfo.getName() + " " + type;
}
}
......@@ -7,10 +7,13 @@ import jadx.dex.info.MethodInfo;
import jadx.dex.instructions.IndexInsnNode;
import jadx.dex.instructions.InsnType;
import jadx.dex.instructions.InvokeNode;
import jadx.dex.instructions.args.ArgType;
import jadx.dex.instructions.args.InsnArg;
import jadx.dex.instructions.args.LiteralArg;
import jadx.dex.instructions.args.RegisterArg;
import jadx.dex.instructions.mods.ConstructorInsn;
import jadx.dex.nodes.BlockNode;
import jadx.dex.nodes.ClassNode;
import jadx.dex.nodes.FieldNode;
import jadx.dex.nodes.InsnNode;
import jadx.dex.nodes.MethodNode;
......@@ -96,15 +99,31 @@ public class ModVisitor extends AbstractVisitor {
break;
case CONST:
ClassNode parentClass = mth.getParentClass();
FieldNode f = null;
if (insn.getArgsCount() == 0) {
// const-string
IndexInsnNode node = (IndexInsnNode) insn;
FieldNode f = mth.getParentClass().getConstFields().get(node.getIndex());
if (f != null) {
InsnNode inode = new IndexInsnNode(InsnType.SGET, f, 0);
inode.setResult(insn.getResult());
replaceInsn(block, i, inode);
f = parentClass.getConstField(node.getIndex());
} else {
LiteralArg arg = (LiteralArg) insn.getArg(0);
ArgType type = arg.getType();
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;
......@@ -233,10 +252,10 @@ public class ModVisitor extends AbstractVisitor {
}
private void checkArgsNames(MethodNode mth) {
for(RegisterArg arg : mth.getArguments(false)) {
for (RegisterArg arg : mth.getArguments(false)) {
String name = arg.getTypedVar().getName();
if(name != null && NameMapper.isReserved(name)) {
name = name + "_" ;
if (name != null && NameMapper.isReserved(name)) {
name = name + "_";
arg.getTypedVar().setName(name);
}
}
......
......@@ -407,12 +407,7 @@ public class RegionMaker {
otherNode.invertOp(elseOffset);
}
IfCondition newArg = IfCondition.fromIfBlock(pred);
IfCondition condition;
if (otherNode.getTarget() != pred.getStartOffset()) {
condition = IfCondition.and(ifRegion.getCondition(), newArg);
} else {
condition = IfCondition.or(ifRegion.getCondition(), newArg);
}
IfCondition condition = IfCondition.and(ifRegion.getCondition(), newArg);
ifRegion.setCondition(condition);
pred.getAttributes().add(AttributeFlag.SKIP);
}
......
......@@ -4,6 +4,14 @@ import java.util.Arrays;
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 fb = true;
private static final int fi = 5;
......@@ -12,14 +20,28 @@ public class TestFields extends AbstractTest {
private static final String fstr = "final string";
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;
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
public boolean testRun() throws Exception {
testConstsFields();
String str = "" + fbz + fiz + fb + fi + fstr + fd + Arrays.toString(fda) + si;
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% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册