Skip to content

Commit

Permalink
[DEX] Link front end models
Browse files Browse the repository at this point in the history
  • Loading branch information
REAndroid committed Sep 22, 2023
1 parent 1cc2642 commit 37ab0eb
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 33 deletions.
4 changes: 4 additions & 0 deletions src/main/java/com/reandroid/dex/index/ClassId.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public ClassId() {
this.staticValues = new ItemOffsetReference<>(SectionType.ENCODED_ARRAY, this, offset += 4);
}

@Override
public String getKey(){
return getName();
}
public String getName(){
TypeId typeId = getClassType();
if(typeId != null){
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/reandroid/dex/index/MethodId.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ StringReference getNameReference(){
public TypeId getClassType(){
return classType.getItem();
}
public void setClassType(TypeId typeId){
classType.setItem(typeId);
}
public String getClassName() {
return classType.getKey();
}
Expand Down Expand Up @@ -90,6 +93,9 @@ public Iterator<TypeId> getParameters(){
public ProtoId getProto(){
return proto.getItem();
}
public void setProto(ProtoId protoId) {
proto.setItem(protoId);
}

public TypeId getReturnTypeId() {
ProtoId protoId = getProto();
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/reandroid/dex/item/Def.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ public boolean isStatic(){
T getItem(){
return mItem;
}
void setItem(T item) {
this.mItem = item;
updateIndex();
}

int getIdIndex() {
DefArray<?> parentArray = getParentInstance(DefArray.class);
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/com/reandroid/dex/item/MethodDef.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@
import com.reandroid.dex.index.MethodId;
import com.reandroid.dex.index.ProtoId;
import com.reandroid.dex.index.TypeId;
import com.reandroid.dex.ins.Ins;
import com.reandroid.dex.sections.Section;
import com.reandroid.dex.sections.SectionType;
import com.reandroid.dex.writer.SmaliWriter;
import com.reandroid.utils.CompareUtil;
import com.reandroid.utils.collection.EmptyIterator;

import java.io.IOException;
import java.util.Iterator;
import java.util.Objects;

public class MethodDef extends Def<MethodId> implements Comparable<MethodDef>{
private final OffsetUle128Item<CodeItem> codeOffset;
Expand All @@ -35,9 +38,43 @@ public MethodDef() {
this.codeOffset = new OffsetUle128Item<>(SectionType.CODE);
addChild(2, codeOffset);
}

public String getName() {
MethodId methodId = getMethodId();
if(methodId != null) {
return methodId.getName();
}
return null;
}
public void setName(String name) {
if(Objects.equals(getName(), name)){
return;
}
MethodId methodId = createMethodId();
methodId.setName(name);
}
private MethodId createMethodId() {
MethodId exist = getMethodId();
Section<MethodId> section = getSection(SectionType.METHOD_ID);
MethodId methodId = section.createIdItem();
methodId.setName(exist.getName());
methodId.setClassType(exist.getClassType());
methodId.setProto(exist.getProto());
setItem(methodId);
return methodId;
}
public MethodId getMethodId(){
return getItem();
}

public Iterator<Ins> getInstructions() {
InstructionList instructionList = getInstructionList();
if(instructionList != null) {
return instructionList.iterator();
}
return EmptyIterator.of();
}

public InstructionList getInstructionList(){
CodeItem codeItem = getCodeItem();
if(codeItem != null){
Expand Down
78 changes: 50 additions & 28 deletions src/main/java/com/reandroid/dex/model/DexClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,47 @@
import com.reandroid.dex.index.ClassId;
import com.reandroid.dex.index.ItemOffsetReference;
import com.reandroid.dex.item.StringData;
import com.reandroid.dex.index.TypeId;
import com.reandroid.dex.item.*;
import com.reandroid.dex.writer.SmaliWriter;
import com.reandroid.utils.collection.ComputeIterator;
import com.reandroid.utils.collection.EmptyIterator;
import com.reandroid.utils.collection.EmptyList;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import com.reandroid.utils.collection.*;

import java.io.*;
import java.util.*;
import java.util.function.Predicate;

public class DexClass implements Comparable<DexClass>{
public class DexClass extends DexModel implements Comparable<DexClass> {
private final DexFile dexFile;
private final ClassId classId;

public DexClass(ClassId classId){
public DexClass(DexFile dexFile, ClassId classId){
this.dexFile = dexFile;
this.classId = classId;
}

public Set<DexClass> listSuperClasses(){
Set<DexClass> results = new HashSet<>();
listSuperClasses(results);
return results;
}
private void listSuperClasses(Set<DexClass> results) {
DexClass dexClass = getSuperClass();
if(dexClass != null && !results.contains(dexClass)){
results.add(dexClass);
dexClass.listSuperClasses(results);
}
Iterator<String> interfaceNames = getInterfaces();
while (interfaceNames.hasNext()){
dexClass = dexFile.get(interfaceNames.next());
if(dexClass != null && !results.contains(dexClass)){
results.add(dexClass);
dexClass.listSuperClasses(results);
}
}
}

public DexClass getSuperClass() {
return dexFile.get(getSuperClassName());
}
public Iterator<DexField> getStaticFields() {
ClassData classData = getClassData();
if(classData != null){
Expand All @@ -53,6 +71,9 @@ public Iterator<DexField> getInstanceFields() {
return ComputeIterator.of(getClassData()
.getInstanceFields().iterator(), this::createField);
}
public Iterator<DexMethod> getMethods() {
return new CombiningIterator<>(getDirectMethods(), getVirtualMethods());
}
public Iterator<DexMethod> getDirectMethods() {
return ComputeIterator.of(getClassData()
.getDirectMethods().iterator(), this::createMethod);
Expand Down Expand Up @@ -91,13 +112,16 @@ private String toFilePath(){
return name + ".smali";
}

public DexFile getDexFile() {
return dexFile;
}
public ClassId getClassId() {
return classId;
}
public String getName(){
return getClassId().getName();
}
public String getSuperClass(){
public String getSuperClassName(){
return getClassId().getSuperClass().getName();
}
public void setSuperClass(String superClass){
Expand All @@ -113,6 +137,10 @@ public String getSourceFile(){
public void setSourceFile(String sourceFile){
getClassId().setSourceFile(sourceFile);
}

public Iterator<DexClass> getInterfaceClasses(){
return ComputeIterator.of(getInterfaces(), DexClass.this.dexFile::get);
}
public Iterator<String> getInterfaces(){
TypeList typeList = getClassId().getInterfaces();
if(typeList != null){
Expand Down Expand Up @@ -159,7 +187,10 @@ public AnnotationSet getAnnotations(){
}

ClassData getClassData(){
return getClassId().getClassData();
ClassId classId = getClassId();
ClassData classData = classId.getClassData();
classData.setClassId(classId);
return classData;
}
EncodedArray getStaticValues(){
return getClassId().getStaticValues();
Expand Down Expand Up @@ -205,17 +236,8 @@ public int hashCode() {
return 0;
}
@Override
public String toString() {
String name = getName();
if(name != null){
return name;
}
return "null";
}

public static DexClass create(ClassId classId){
DexClass dexClass = new DexClass(classId);
dexClass.refresh();
return dexClass;
public void append(SmaliWriter writer) throws IOException {
getClassData();
getClassId().append(writer);
}
}
10 changes: 9 additions & 1 deletion src/main/java/com/reandroid/dex/model/DexField.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@
import com.reandroid.dex.item.FieldDef;
import com.reandroid.dex.item.StringData;
import com.reandroid.dex.value.DexValueBlock;
import com.reandroid.dex.writer.SmaliFormat;
import com.reandroid.dex.writer.SmaliWriter;

import java.io.IOException;
import java.util.Iterator;

public class DexField {
public class DexField extends DexModel {

private final DexClass dexClass;
private final FieldDef fieldDef;
Expand Down Expand Up @@ -95,4 +98,9 @@ public String toString() {
}
return builder.toString();
}

@Override
public void append(SmaliWriter writer) throws IOException {
getFieldDef().append(writer);
}
}
13 changes: 12 additions & 1 deletion src/main/java/com/reandroid/dex/model/DexFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,18 @@ public DexFile(DexFileBlock dexFileBlock){
this.dexFileBlock = dexFileBlock;
}
public Iterator<DexClass> getDexClasses() {
return ComputeIterator.of(getClassIds(), DexClass::new);
return ComputeIterator.of(getClassIds(), this::create);
}
public DexClass get(String typeName){
Section<ClassId> section = getDexFileBlock().get(SectionType.CLASS_ID);
ClassId classId = section.getPool().get(typeName);
if(classId == null) {
return null;
}
return create(classId);
}
private DexClass create(ClassId classId) {
return new DexClass(this, classId);
}
public Marker getOrCreateMarker() {
Marker marker = CollectionUtil.getFirst(getMarkers());
Expand Down
40 changes: 40 additions & 0 deletions src/main/java/com/reandroid/dex/model/DexInstruction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2022 github.com/REAndroid
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.reandroid.dex.model;

import com.reandroid.dex.ins.Ins;
import com.reandroid.dex.writer.SmaliWriter;

import java.io.IOException;

public class DexInstruction extends DexModel{
private final DexMethod dexMethod;
private final Ins ins;

public DexInstruction(DexMethod dexMethod, Ins ins) {
this.dexMethod = dexMethod;
this.ins = ins;
}

public Ins getIns() {
return ins;
}

@Override
public void append(SmaliWriter writer) throws IOException {
getIns().append(writer);
}
}
26 changes: 23 additions & 3 deletions src/main/java/com/reandroid/dex/model/DexMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,37 @@
import com.reandroid.dex.common.AccessFlag;
import com.reandroid.dex.index.MethodId;
import com.reandroid.dex.index.TypeId;
import com.reandroid.dex.ins.Ins;
import com.reandroid.dex.item.MethodDef;
import com.reandroid.dex.writer.SmaliWriter;
import com.reandroid.utils.collection.ComputeIterator;

import java.io.IOException;
import java.util.Iterator;

public class DexMethod {
public class DexMethod extends DexModel {
private final DexClass dexClass;
private final MethodDef methodDef;

public DexMethod(DexClass dexClass, MethodDef methodDef){
this.dexClass = dexClass;
this.methodDef = methodDef;
}
public Iterator<DexMethod> getImplementations() {
return null;
}
public Iterator<DexMethod> getSuperMethods() {
return null;
}

public String getAccessFlags() {
return AccessFlag.formatForField(getMethodDef().getAccessFlagsValue());
}
public String getName(){
return getMethodId().getName();
return getMethodDef().getName();
}
public void setName(String name){
getMethodId().setName(name);
getMethodDef().setName(name);
}
public int getParametersCount() {
return getMethodId().getParametersCount();
Expand All @@ -61,6 +70,12 @@ public String getReturnType() {
}
return null;
}
public Iterator<DexInstruction> getInstructions() {
return ComputeIterator.of(getMethodDef().getInstructions(), this::create);
}
private DexInstruction create(Ins ins){
return new DexInstruction(this, ins);
}

public String getKey(){
return getMethodId().getKey();
Expand All @@ -74,6 +89,11 @@ public DexClass getDexClass() {
public MethodDef getMethodDef() {
return methodDef;
}

@Override
public void append(SmaliWriter writer) throws IOException {
getMethodDef().append(writer);
}
@Override
public String toString() {
return getKey();
Expand Down
Loading

0 comments on commit 37ab0eb

Please sign in to comment.