public ClassNode(DexNode dex, ClassDef cls) { this.dex = dex; this.clsInfo = ClassInfo.fromDex(dex, cls.getTypeIndex()); try { if (cls.getSupertypeIndex() == DexNode.NO_INDEX) { this.superClass = null; } else { this.superClass = dex.getType(cls.getSupertypeIndex()); this.interfaces = new ArrayList<>(cls.getInterfaces().length); for (short interfaceIdx : cls.getInterfaces()) { this.interfaces.add(dex.getType(interfaceIdx)); if (cls.getClassDataOffset() != 0) { ClassData clsData = dex.readClassData(cls); int mthsCount = clsData.getDirectMethods().length + clsData.getVirtualMethods().length; setFieldsTypesFromSignature(); int sfIdx = cls.getSourceFileIndex(); if (sfIdx != DexNode.NO_INDEX) { String fileName = dex.getString(sfIdx); accFlagsValue = (Integer) a.getValues().get("accessFlags"); } else { accFlagsValue = cls.getAccessFlags();
private void loadAnnotations(ClassDef cls) { int offset = cls.getAnnotationsOffset(); if (offset != 0) { try { new AnnotationsParser(this).parse(offset); } catch (Exception e) { LOG.error("Error parsing annotations in {}", this, e); } } }
private void loadStaticValues(ClassDef cls, List<FieldNode> staticFields) throws DecodeException { for (FieldNode f : staticFields) { if (f.getAccessFlags().isFinal()) { f.addAttr(FieldInitAttr.NULL_VALUE); } } int offset = cls.getStaticValuesOffset(); if (offset == 0) { return; } Dex.Section section = dex.openSection(offset); StaticValuesParser parser = new StaticValuesParser(dex, section); parser.processFields(staticFields); // process const fields root().getConstValues().processConstFields(this, staticFields); }
public ClassDef adjust(ClassDef classDef) { return new ClassDef(target, classDef.getOffset(), adjustType(classDef.getTypeIndex()), classDef.getAccessFlags(), adjustType(classDef.getSupertypeIndex()), adjustTypeListOffset(classDef.getInterfacesOffset()), classDef.getSourceFileIndex(), classDef.getAnnotationsOffset(), classDef.getClassDataOffset(), classDef.getStaticValuesOffset()); }
if (classDef.getSupertypeIndex() == ClassDef.NO_INDEX) { max = 0; // this is Object.class or an interface } else if (classDef.getSupertypeIndex() == classDef.getTypeIndex()) { throw new DexException("Class with type index " + classDef.getTypeIndex() + " extends itself"); } else { SortableType sortableSupertype = types[classDef.getSupertypeIndex()]; if (sortableSupertype == null) { max = 1; // unknown, so assume it's a root. for (short interfaceIndex : classDef.getInterfaces()) { SortableType implemented = types[interfaceIndex]; if (implemented == null) {
public int getTypeIndex() { return classDef.getTypeIndex(); }
/** * Prints usages to out. Returns the number of matches found. */ public int grep() { for (ClassDef classDef : dex.classDefs()) { currentClass = classDef; currentMethod = null; if (classDef.getClassDataOffset() == 0) { continue; } ClassData classData = dex.readClassData(classDef); // find the strings in encoded constants int staticValuesOffset = classDef.getStaticValuesOffset(); if (staticValuesOffset != 0) { readArray(new EncodedValueReader(dex.open(staticValuesOffset))); } // find the strings in method bodies for (ClassData.Method method : classData.allMethods()) { currentMethod = method; if (method.getCodeOffset() != 0) { codeReader.visitAll(dex.readCode(method).getInstructions()); } } } currentClass = null; currentMethod = null; return count; }
if (classDef.getSupertypeIndex() == ClassDef.NO_INDEX) { max = 0; // this is Object.class or an interface } else { SortableType sortableSupertype = types[classDef.getSupertypeIndex()]; if (sortableSupertype == null) { max = 1; // unknown, so assume it's a root. for (short interfaceIndex : classDef.getInterfaces()) { SortableType implemented = types[interfaceIndex]; if (implemented == null) {
public ClassData readClassData(ClassDef classDef) { int offset = classDef.getClassDataOffset(); if (offset == 0) { throw new IllegalArgumentException("offset == 0"); } return open(offset).readClassData(); }
public ClassDef readClassDef() { int offset = getPosition(); int type = readInt(); int accessFlags = readInt(); int supertype = readInt(); int interfacesOffset = readInt(); int sourceFileIndex = readInt(); int annotationsOffset = readInt(); int classDataOffset = readInt(); int staticValuesOffset = readInt(); return new ClassDef(Dex.this, offset, type, accessFlags, supertype, interfacesOffset, sourceFileIndex, annotationsOffset, classDataOffset, staticValuesOffset); }
public ClassDef adjust(ClassDef classDef) { return new ClassDef(target, classDef.getOffset(), adjustType(classDef.getTypeIndex()), classDef.getAccessFlags(), adjustType(classDef.getSupertypeIndex()), adjustTypeListOffset(classDef.getInterfacesOffset()), classDef.getSourceFileIndex(), classDef.getAnnotationsOffset(), classDef.getClassDataOffset(), classDef.getStaticValuesOffset()); }
/** * Returns the set of types that can be assigned to {@code typeIndex}. */ private Set<Integer> findAssignableTypes(Dex dex, int typeIndex) { Set<Integer> assignableTypes = new HashSet<Integer>(); assignableTypes.add(typeIndex); for (ClassDef classDef : dex.classDefs()) { if (assignableTypes.contains(classDef.getSupertypeIndex())) { assignableTypes.add(classDef.getTypeIndex()); continue; } for (int implemented : classDef.getInterfaces()) { if (assignableTypes.contains(implemented)) { assignableTypes.add(classDef.getTypeIndex()); break; } } } return assignableTypes; } }
public int getTypeIndex() { return classDef.getTypeIndex(); }
/** * Prints usages to out. Returns the number of matches found. */ public int grep() { for (ClassDef classDef : dex.classDefs()) { currentClass = classDef; currentMethod = null; if (classDef.getClassDataOffset() == 0) { continue; } ClassData classData = dex.readClassData(classDef); // find the strings in encoded constants int staticValuesOffset = classDef.getStaticValuesOffset(); if (staticValuesOffset != 0) { readArray(new EncodedValueReader(dex.open(staticValuesOffset))); } // find the strings in method bodies for (ClassData.Method method : classData.allMethods()) { currentMethod = method; if (method.getCodeOffset() != 0) { codeReader.visitAll(dex.readCode(method).getInstructions()); } } } currentClass = null; currentMethod = null; return count; }
if (classDef.getSupertypeIndex() == ClassDef.NO_INDEX) { max = 0; // this is Object.class or an interface } else { SortableType sortableSupertype = types[classDef.getSupertypeIndex()]; if (sortableSupertype == null) { max = 1; // unknown, so assume it's a root. for (short interfaceIndex : classDef.getInterfaces()) { SortableType implemented = types[interfaceIndex]; if (implemented == null) {
public ClassData readClassData(ClassDef classDef) { int offset = classDef.getClassDataOffset(); if (offset == 0) { throw new IllegalArgumentException("offset == 0"); } return open(offset).readClassData(); }
public ClassDef readClassDef() { int offset = getPosition(); int type = readInt(); int accessFlags = readInt(); int supertype = readInt(); int interfacesOffset = readInt(); int sourceFileIndex = readInt(); int annotationsOffset = readInt(); int classDataOffset = readInt(); int staticValuesOffset = readInt(); return new ClassDef(Dex.this, offset, type, accessFlags, supertype, interfacesOffset, sourceFileIndex, annotationsOffset, classDataOffset, staticValuesOffset); }
public ClassDef adjust(ClassDef classDef) { return new ClassDef(target, classDef.getOffset(), adjustType(classDef.getTypeIndex()), classDef.getAccessFlags(), adjustType(classDef.getSupertypeIndex()), adjustTypeListOffset(classDef.getInterfacesOffset()), classDef.getSourceFileIndex(), classDef.getAnnotationsOffset(), classDef.getClassDataOffset(), classDef.getStaticValuesOffset()); }
/** * Returns the set of types that can be assigned to {@code typeIndex}. */ private Set<Integer> findAssignableTypes(Dex dex, int typeIndex) { Set<Integer> assignableTypes = new HashSet<Integer>(); assignableTypes.add(typeIndex); for (ClassDef classDef : dex.classDefs()) { if (assignableTypes.contains(classDef.getSupertypeIndex())) { assignableTypes.add(classDef.getTypeIndex()); continue; } for (int implemented : classDef.getInterfaces()) { if (assignableTypes.contains(implemented)) { assignableTypes.add(classDef.getTypeIndex()); break; } } } return assignableTypes; } }
public int getTypeIndex() { return classDef.getTypeIndex(); }