Skip to content

Commit

Permalink
[DEX] Better static and annotation value handling
Browse files Browse the repository at this point in the history
  • Loading branch information
REAndroid committed Oct 30, 2024
1 parent 3a24c52 commit 0bc5cdb
Show file tree
Hide file tree
Showing 49 changed files with 905 additions and 891 deletions.
56 changes: 34 additions & 22 deletions src/main/java/com/reandroid/dex/data/AnnotationElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import com.reandroid.dex.common.SectionTool;
import com.reandroid.dex.id.IdItem;
import com.reandroid.dex.id.StringId;
import com.reandroid.dex.key.DataKey;
import com.reandroid.dex.key.Key;
import com.reandroid.dex.key.MethodKey;
import com.reandroid.dex.key.TypeKey;
import com.reandroid.dex.key.*;
import com.reandroid.dex.reference.StringUle128Reference;
import com.reandroid.dex.smali.model.SmaliAnnotationElement;
import com.reandroid.dex.smali.model.SmaliValue;
Expand All @@ -23,38 +20,53 @@
import java.util.Iterator;
import java.util.Objects;

public class AnnotationElement extends DataItem implements Comparable<AnnotationElement>, SmaliFormat {
public class AnnotationElement extends DataItem implements ModifiableKeyItem,
Comparable<AnnotationElement>, SmaliFormat {

private final StringUle128Reference elementName;

private final DataKey<AnnotationElement> mKey;

public AnnotationElement() {
super(2);
this.elementName = new StringUle128Reference(StringId.USAGE_METHOD_NAME);
addChild(0, elementName);
this.mKey = new DataKey<>(this);
}

@Override
public DataKey<AnnotationElement> getKey(){
return mKey;
public AnnotationElementKey getKey(){
return checkKey(new AnnotationElementKey(getName(), getValue()));
}
@Override
public void setKey(Key key) {
AnnotationElementKey elementKey = (AnnotationElementKey) key;
setName(elementKey.getName());
}
public Key getValue() {
DexValueBlock<?> valueBlock = getValueBlock();
if (valueBlock != null) {
return valueBlock.getKey();
}
return null;
}
public void setValue(Key value) {
DexValueBlock<?> valueBlock = DexValueType.forKey(value).newInstance();
setValue(valueBlock);
valueBlock.setKey(value);
}
public DexValueBlock<?> getValue(){
public DexValueBlock<?> getValueBlock(){
return (DexValueBlock<?>) getChildes()[1];
}

@SuppressWarnings("unchecked")
public<T1 extends DexValueBlock<?>> T1 getValue(DexValueType<T1> valueType){
DexValueBlock<?> value = getValue();
DexValueBlock<?> value = getValueBlock();
if(value != null && value.is(valueType)){
return (T1) value;
}
return null;
}
@SuppressWarnings("unchecked")
public<T1 extends DexValueBlock<?>> T1 getOrCreateValue(DexValueType<T1> valueType){
DexValueBlock<?> value = getValue();
DexValueBlock<?> value = getValueBlock();
if(value == null || value == NullValue.PLACE_HOLDER || value.getValueType() != valueType){
value = valueType.newInstance();
setValue(value);
Expand All @@ -72,7 +84,7 @@ public boolean is(MethodKey methodKey) {
methodKey.equalsIgnoreReturnType(getMethodKey());
}
public DexValueType<?> getValueType(){
DexValueBlock<?> value = getValue();
DexValueBlock<?> value = getValueBlock();
if(value != null){
return value.getValueType();
}
Expand All @@ -97,18 +109,18 @@ public void onReadBytes(BlockReader reader) throws IOException {
}

public void replaceKeys(Key search, Key replace){
getValue().replaceKeys(search, replace);
getValueBlock().replaceKeys(search, replace);
}
@Override
public Iterator<IdItem> usedIds(){
return CombiningIterator.singleOne(getNameId(), getValue().usedIds());
return CombiningIterator.singleOne(getNameId(), getValueBlock().usedIds());
}
public void merge(AnnotationElement element){
if(element == this){
return;
}
setName(element.getName());
DexValueBlock<?> coming = element.getValue();
DexValueBlock<?> coming = element.getValueBlock();
DexValueBlock<?> value = getOrCreateValue(coming.getValueType());
value.merge(coming);
}
Expand All @@ -122,7 +134,7 @@ public void fromSmali(SmaliAnnotationElement element){
public void append(SmaliWriter writer) throws IOException {
writer.append(getName());
writer.append(" = ");
getValue().append(writer);
getValueBlock().append(writer);
}


Expand All @@ -137,7 +149,7 @@ public int compareTo(AnnotationElement other) {
return SectionTool.compareIdx(getNameId(), other.getNameId());
}
public TypeKey getDataTypeKey(){
DexValueBlock<?> valueBlock = getValue();
DexValueBlock<?> valueBlock = getValueBlock();
if(valueBlock != null){
return valueBlock.getDataTypeKey();
}
Expand Down Expand Up @@ -174,7 +186,7 @@ public int hashCode() {
if(obj != null){
hash += obj.hashCode();
}
obj = getValue();
obj = getValueBlock();
hash = hash * 31;
if(obj != null){
hash = hash + obj.hashCode();
Expand All @@ -193,12 +205,12 @@ public boolean equals(Object obj) {
if(!Objects.equals(getName(), element.getName())){
return false;
}
return Objects.equals(getValue(), element.getValue());
return Objects.equals(getValueBlock(), element.getValueBlock());
}

@Override
public String toString() {
return getName() + " = " + getValue();
return getName() + " = " + getValueBlock();
}

public static final Creator<AnnotationElement> CREATOR = new Creator<AnnotationElement>() {
Expand Down
39 changes: 25 additions & 14 deletions src/main/java/com/reandroid/dex/data/AnnotationItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
import com.reandroid.dex.common.SectionTool;
import com.reandroid.dex.id.IdItem;
import com.reandroid.dex.id.TypeId;
import com.reandroid.dex.key.DataKey;
import com.reandroid.dex.key.Key;
import com.reandroid.dex.key.ModifiableKeyItem;
import com.reandroid.dex.key.TypeKey;
import com.reandroid.dex.key.*;
import com.reandroid.dex.reference.Ule128IdItemReference;
import com.reandroid.dex.sections.SectionType;
import com.reandroid.dex.smali.SmaliDirective;
Expand Down Expand Up @@ -56,8 +53,6 @@ public class AnnotationItem extends DataItem

private final boolean mValueEntry;

private final DataKey<AnnotationItem> mItemKey;

public AnnotationItem(boolean valueEntry) {
super(valueEntry? 3 : 4);
this.mValueEntry = valueEntry;
Expand All @@ -77,8 +72,6 @@ public AnnotationItem(boolean valueEntry) {
addChild(i++, visibility);
}

this.mItemKey = new DataKey<>(this);

addChild(i++, typeId);
addChild(i++, elementsCount);
addChild(i, annotationElements);
Expand All @@ -97,6 +90,9 @@ public boolean removeIf(Predicate<AnnotationElement> filter){
public void remove(AnnotationElement element){
annotationElements.remove(element);
}
public void clear() {
annotationElements.clearChildes();
}
public AnnotationElement getOrCreateElement(String name){
AnnotationElement element = getElement(name);
if(element != null){
Expand All @@ -121,7 +117,7 @@ public boolean containsName(String name){
public DexValueBlock<?> getElementValue(String name){
AnnotationElement element = getElement(name);
if(element != null){
return element.getValue();
return element.getValueBlock();
}
return null;
}
Expand All @@ -133,6 +129,17 @@ public AnnotationElement getElement(String name){
}
return null;
}
public AnnotationElementKey[] getElements() {
int length = getElementsCount();
AnnotationElementKey[] results = new AnnotationElementKey[length];
for (int i = 0; i < length; i++) {
results[i] = getElement(i).getKey();
}
return results;
}
public void addElement(AnnotationElementKey element) {
createNewElement().setKey(element);
}
public String[] getNames(){
CountedList<AnnotationElement> elements = annotationElements;
int length = elements.size();
Expand All @@ -146,14 +153,18 @@ public String[] getNames(){
return results;
}
@Override
public DataKey<AnnotationItem> getKey(){
return mItemKey;
public AnnotationItemKey getKey(){
return checkKey(new AnnotationItemKey(getVisibility(), getTypeKey(), getElements()));
}
@SuppressWarnings("unchecked")
@Override
public void setKey(Key key){
DataKey<AnnotationItem> itemKey = (DataKey<AnnotationItem>) key;
merge(itemKey.getItem());
AnnotationItemKey itemKey = (AnnotationItemKey) key;
setVisibility(itemKey.getVisibility());
setType(itemKey.getType());
clear();
for (AnnotationElementKey elementKey : itemKey) {
addElement(elementKey);
}
}
@Override
public Iterator<AnnotationElement> iterator(){
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/reandroid/dex/data/AnnotationSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public SectionType<AnnotationSet> getSectionType() {
public DexValueBlock<?> getValue(TypeKey typeKey, String name){
AnnotationElement element = getElement(typeKey, name);
if(element != null){
return element.getValue();
return element.getValueBlock();
}
return null;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/reandroid/dex/data/DefArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ public final boolean sort(Comparator<? super T> comparator) {
onPostSort();
return changed;
}
void onPreSort(){
private void onPreSort() {
ClassId classId = getClassId();
if(classId != null){
classId.getUniqueAnnotationsDirectory();
}
linkAnnotation();
}
void onPostSort(){
private void onPostSort(){
resetIndex();
sortAnnotations();
}
Expand Down
53 changes: 21 additions & 32 deletions src/main/java/com/reandroid/dex/data/EncodedArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import com.reandroid.arsc.io.BlockReader;
import com.reandroid.dex.base.Ule128Item;
import com.reandroid.dex.id.IdItem;
import com.reandroid.dex.key.DataKey;
import com.reandroid.dex.key.ArrayKey;
import com.reandroid.dex.key.Key;
import com.reandroid.dex.key.ModifiableKeyItem;
import com.reandroid.dex.sections.SectionType;
Expand All @@ -33,15 +33,13 @@
import com.reandroid.utils.collection.IterableIterator;

import java.io.IOException;
import java.util.Comparator;
import java.util.Iterator;
import java.util.function.Predicate;

public class EncodedArray extends DataItem implements ModifiableKeyItem, Iterable<DexValueBlock<?>> {

private final Ule128Item valuesCountReference;
private final BlockList<DexValueBlock<?>> valueList;
private final DataKey<EncodedArray> itemKey;

public EncodedArray() {
super(2);
Expand All @@ -50,19 +48,24 @@ public EncodedArray() {
this.valueList.setCreator(CREATOR);
addChild(0, valuesCountReference);
addChild(1, valueList);
this.itemKey = new DataKey<>(this);
}

@Override
public DataKey<EncodedArray> getKey() {
return itemKey;
public ArrayKey getKey() {
int size = size();
Key[] keys = new Key[size];
for (int i = 0; i < size; i++) {
keys[i] = get(i).getKey();
}
return checkKey(new ArrayKey(keys));
}

@SuppressWarnings("unchecked")
@Override
public void setKey(Key key) {
DataKey<EncodedArray> other = (DataKey<EncodedArray>) key;
merge(other.getItem());
ArrayKey arrayKey = (ArrayKey) key;
clear();
for (Key k : arrayKey) {
add(k);
}
}

@Override
Expand Down Expand Up @@ -90,6 +93,12 @@ public<T1 extends DexValueBlock<?>> T1 getOrCreate(DexValueType<T1> valueType, i
public int size(){
return getValueList().getCount();
}

public void add(Key key) {
DexValueBlock<?> valueBlock = DexValueType.forKey(key).newInstance();
add(valueBlock);
valueBlock.setKey(key);
}
public void add(DexValueBlock<?> value){
getValueList().add(value);
}
Expand All @@ -109,26 +118,6 @@ public void set(int i, DexValueBlock<?> value){
public void clear(){
getValueList().clearChildes();
}
public void removeAll(){
getValueList().clearTemporarily();
}
public boolean sort(Comparator<? super DexValueBlock<?>> comparator){
return getValueList().sort(comparator);
}
public void trimNull(){
int size = size();
int updatedSize = 0;
for(int i = 0; i < size; i++){
DexValueBlock<?> value = get(i);
if(value != null && !value.is(DexValueType.NULL) && !value.isTemporary()) {
updatedSize = i + 1;
}
}
if(updatedSize != size){
setSize(updatedSize);
}
}


public void ensureSize(int size){
if(size > size()){
Expand All @@ -141,8 +130,8 @@ public void setSize(int size) {
}
valuesCountReference.set(size);
BlockList<DexValueBlock<?>> valueList = this.getValueList();
if(size == 0){
valueList.clearTemporarily();
if(size == 0) {
valueList.setSize(0);
return;
}
int current = valueList.size();
Expand Down
Loading

0 comments on commit 0bc5cdb

Please sign in to comment.