Search in sources :

Example 1 with DexFieldNode

use of com.googlecode.d2j.node.DexFieldNode in project dex2jar by pxb1988.

the class DexFix method fixStaticFinalFieldValue.

/**
     * init value to default if the field is static and final, and the field is not init in clinit method
     *
     * erase the default value if the field is init in clinit method
     * 
     * @param classNode
     */
public static void fixStaticFinalFieldValue(final DexClassNode classNode) {
    if (classNode.fields == null) {
        return;
    }
    final Map<String, DexFieldNode> fs = new HashMap<>();
    final Map<String, DexFieldNode> shouldNotBeAssigned = new HashMap<>();
    for (DexFieldNode fn : classNode.fields) {
        if ((fn.access & ACC_STATIC_FINAL) == ACC_STATIC_FINAL) {
            if (fn.cst == null) {
                char t = fn.field.getType().charAt(0);
                if (t == 'L' || t == '[') {
                    // ignore Object
                    continue;
                }
                fs.put(fn.field.getName() + ":" + fn.field.getType(), fn);
            } else if (isPrimitiveZero(fn.field.getType(), fn.cst)) {
                shouldNotBeAssigned.put(fn.field.getName() + ":" + fn.field.getType(), fn);
            }
        }
    }
    if (fs.isEmpty() && shouldNotBeAssigned.isEmpty()) {
        return;
    }
    DexMethodNode node = null;
    if (classNode.methods != null) {
        for (DexMethodNode mn : classNode.methods) {
            if (mn.method.getName().equals("<clinit>")) {
                node = mn;
                break;
            }
        }
    }
    if (node != null) {
        if (node.codeNode != null) {
            node.codeNode.accept(new DexCodeVisitor() {

                @Override
                public void visitFieldStmt(Op op, int a, int b, Field field) {
                    switch(op) {
                        case SPUT:
                        case SPUT_BOOLEAN:
                        case SPUT_BYTE:
                        case SPUT_CHAR:
                        case SPUT_OBJECT:
                        case SPUT_SHORT:
                        case SPUT_WIDE:
                            if (field.getOwner().equals(classNode.className)) {
                                String key = field.getName() + ":" + field.getType();
                                fs.remove(key);
                                DexFieldNode dn = shouldNotBeAssigned.get(key);
                                if (dn != null) {
                                    //System.out.println(field.getName() + ":" + field.getType());
                                    dn.cst = null;
                                }
                            }
                            break;
                        default:
                            // ignored
                            break;
                    }
                }
            });
        } else {
            // has init but no code
            return;
        }
    }
    for (DexFieldNode fn : fs.values()) {
        fn.cst = getDefaultValueOfType(fn.field.getType().charAt(0));
    }
}
Also used : Op(com.googlecode.d2j.reader.Op) Field(com.googlecode.d2j.Field) HashMap(java.util.HashMap) DexFieldNode(com.googlecode.d2j.node.DexFieldNode) DexMethodNode(com.googlecode.d2j.node.DexMethodNode) DexCodeVisitor(com.googlecode.d2j.visitors.DexCodeVisitor)

Aggregations

Field (com.googlecode.d2j.Field)1 DexFieldNode (com.googlecode.d2j.node.DexFieldNode)1 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)1 Op (com.googlecode.d2j.reader.Op)1 DexCodeVisitor (com.googlecode.d2j.visitors.DexCodeVisitor)1 HashMap (java.util.HashMap)1