Skip to content

Commit

Permalink
[DEX] Refactor smali model classes
Browse files Browse the repository at this point in the history
  • Loading branch information
REAndroid committed Oct 31, 2024
1 parent c53c4c6 commit c89eafa
Show file tree
Hide file tree
Showing 19 changed files with 290 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@

import com.reandroid.dex.key.AnnotationElementKey;
import com.reandroid.dex.key.Key;
import com.reandroid.dex.key.KeyReference;
import com.reandroid.dex.smali.SmaliParseException;
import com.reandroid.dex.smali.SmaliReader;
import com.reandroid.dex.smali.SmaliWriter;

import java.io.IOException;

public class SmaliAnnotationElement extends Smali{
public class SmaliAnnotationElement extends Smali implements KeyReference {

private String name;
private SmaliValue value;
Expand All @@ -31,9 +33,16 @@ public SmaliAnnotationElement(){
super();
}

@Override
public AnnotationElementKey getKey() {
return new AnnotationElementKey(getName(), getValueKey());
}
@Override
public void setKey(Key key) {
AnnotationElementKey elementKey = (AnnotationElementKey) key;
setName(elementKey.getName());
setValue(elementKey.getValue());
}
public String getName() {
return name;
}
Expand All @@ -50,6 +59,12 @@ public Key getValueKey() {
public SmaliValue getValue() {
return value;
}

public void setValue(Key key) {
SmaliValue smaliValue = SmaliValueFactory.createForValue(key);
setValue(smaliValue);
smaliValue.setKey(key);
}
public void setValue(SmaliValue value) {
this.value = value;
if(value != null){
Expand Down Expand Up @@ -78,11 +93,9 @@ public void parse(SmaliReader reader) throws IOException{
int length = i - reader.position();
setName(reader.readString(length));
reader.skipWhitespaces();
if(reader.readASCII() != '='){
// throw
}
SmaliParseException.expect(reader, '=');
reader.skipWhitespaces();
SmaliValue smaliValue = SmaliValue.create(reader);
SmaliValue smaliValue = SmaliValueFactory.create(reader);
setValue(smaliValue);
smaliValue.parse(reader);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@
package com.reandroid.dex.smali.model;

import com.reandroid.dex.common.AnnotationVisibility;
import com.reandroid.dex.key.AnnotationElementKey;
import com.reandroid.dex.key.AnnotationItemKey;
import com.reandroid.dex.key.TypeKey;
import com.reandroid.dex.key.*;
import com.reandroid.dex.smali.*;

import java.io.IOException;

public class SmaliAnnotationItem extends SmaliSet<SmaliAnnotationElement> implements SmaliRegion {
public class SmaliAnnotationItem extends SmaliSet<SmaliAnnotationElement>
implements KeyReference, SmaliRegion {

private final SmaliDirective smaliDirective;
private AnnotationVisibility visibility;
Expand All @@ -41,6 +40,7 @@ public SmaliAnnotationItem(){
this(false);
}

@Override
public AnnotationItemKey getKey() {
int length = this.size();
AnnotationElementKey[] elements = new AnnotationElementKey[length];
Expand All @@ -49,6 +49,16 @@ public AnnotationItemKey getKey() {
}
return new AnnotationItemKey(getVisibility(), getType(), elements);
}
@Override
public void setKey(Key key) {
clear();
AnnotationItemKey itemKey = (AnnotationItemKey) key;
setVisibility(itemKey.getVisibility());
setType(itemKey.getType());
for (AnnotationElementKey elementKey : itemKey) {
newElement().setKey(elementKey);
}
}
public AnnotationVisibility getVisibility() {
return visibility;
}
Expand All @@ -70,6 +80,11 @@ public void setType(TypeKey type) {
this.type = type;
}

public SmaliAnnotationElement newElement() {
SmaliAnnotationElement element = new SmaliAnnotationElement();
add(element);
return element;
}
@Override
public SmaliDirective getSmaliDirective() {
return smaliDirective;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/reandroid/dex/smali/model/SmaliField.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ void fixUninitializedFinalValue() {
return;
}
if(!isInitializedInStaticConstructor(smaliClass, fieldKey)) {
setValue(SmaliValue.createDefaultFor(fieldKey.getType()));
setValue(SmaliValueFactory.createForField(fieldKey.getType()));
}
}
private boolean isInitializedInStaticConstructor(SmaliClass smaliClass, FieldKey fieldKey) {
Expand Down Expand Up @@ -156,7 +156,7 @@ private void parseValue(SmaliReader reader) throws IOException {
}
reader.skip(1); // =
reader.skipWhitespaces();
SmaliValue value = SmaliValue.create(reader);
SmaliValue value = SmaliValueFactory.create(reader);
setValue(value);
value.parse(reader);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public Opcode<InsArrayData> getOpcode() {
}
@Override
public SmaliValueNumber<?> newEntry(SmaliReader reader) throws IOException {
SmaliValue value = SmaliValue.create(reader);
SmaliValue value = SmaliValueFactory.create(reader);
if(!(value instanceof SmaliValueNumber)){
throw new SmaliParseException("Unrecognized array data entry", reader);
}
Expand Down
114 changes: 8 additions & 106 deletions src/main/java/com/reandroid/dex/smali/model/SmaliValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,123 +15,25 @@
*/
package com.reandroid.dex.smali.model;

import com.reandroid.dex.key.Key;
import com.reandroid.dex.key.TypeKey;
import com.reandroid.dex.key.*;
import com.reandroid.dex.smali.SmaliDirective;
import com.reandroid.dex.smali.SmaliParseException;
import com.reandroid.dex.smali.SmaliReader;
import com.reandroid.dex.value.*;

import java.io.IOException;

public class SmaliValue extends Smali{
public abstract class SmaliValue extends Smali implements KeyReference {

public SmaliValue(){
super();
}

public DexValueType<?> getValueType(){
return null;
}
public Key getKey() {
throw new RuntimeException("Method not implemented");
}
public abstract DexValueType<?> getValueType();
@Override
public void parse(SmaliReader reader) throws IOException {
}

public static SmaliValue create(SmaliReader reader) throws IOException{
reader.skipSpaces();
int position = reader.position();
byte b = reader.get(position);
if(b == '.'){
SmaliDirective directive = SmaliDirective.parse(reader, false);
if(directive == SmaliDirective.ENUM){
return new SmaliValueEnum();
}
if(directive == SmaliDirective.SUB_ANNOTATION){
return new SmaliValueAnnotation();
}
throw new SmaliParseException("Unrecognized value", reader);
}
if(b == '{'){
return new SmaliValueArray();
}
if(b == '\''){
return new SmaliValueChar();
}
if(b == 'n'){
return new SmaliValueNull();
}
if(b == 't' || b == 'f'){
return new SmaliValueBoolean();
}
if(b == '-' || b == '+'){
position ++;
b = reader.get(position);
}
if(b == '0' && reader.get(position + 1) == 'x'){
b = reader.get(reader.indexOfWhiteSpaceOrComment() - 1);
if(b == 't'){
return new SmaliValueByte();
}
if(b == 'S' || b == 's'){
return new SmaliValueShort();
}
if(b == 'L'){
return new SmaliValueLong();
}
return new SmaliValueInteger();
}
byte[] infinity = new byte[]{'I', 'n', 'f', 'i', 'n', 'i', 't', 'y'};
if(reader.startsWith(infinity, position)){
b = reader.get(infinity.length + position);
if(b == 'f'){
return new SmaliValueFloat();
}
return new SmaliValueDouble();
}
byte[] nan = new byte[]{'N', 'a', 'N'};
if(reader.startsWith(nan, position)){
b = reader.get(nan.length + position);
if(b == 'f'){
return new SmaliValueFloat();
}
return new SmaliValueDouble();
}
if(b <= '9' && b >= '0'){
b = reader.get(reader.indexOfWhiteSpaceOrComment() - 1);
if(b == 'f'){
return new SmaliValueFloat();
}
return new SmaliValueDouble();
}
return new SmaliValueSectionData();
}

public static SmaliValue createDefaultFor(TypeKey typeKey){
SmaliValue smaliValue;
if(typeKey.isTypeArray() || !typeKey.isPrimitive()) {
smaliValue = new SmaliValueNull();
}else if(TypeKey.TYPE_I.equals(typeKey)) {
smaliValue = new SmaliValueInteger();
} else if(TypeKey.TYPE_J.equals(typeKey)) {
smaliValue = new SmaliValueLong();
} else if(TypeKey.TYPE_D.equals(typeKey)) {
smaliValue = new SmaliValueDouble();
} else if(TypeKey.TYPE_F.equals(typeKey)) {
smaliValue = new SmaliValueFloat();
} else if(TypeKey.TYPE_S.equals(typeKey)) {
smaliValue = new SmaliValueShort();
} else if(TypeKey.TYPE_B.equals(typeKey)) {
smaliValue = new SmaliValueByte();
} else if(TypeKey.TYPE_C.equals(typeKey)) {
smaliValue = new SmaliValueChar();
} else if(TypeKey.TYPE_Z.equals(typeKey)) {
smaliValue = new SmaliValueBoolean();
}else {
throw new IllegalArgumentException("Undefined: " + typeKey);
}
return smaliValue;
}
public abstract Key getKey();
@Override
public abstract void setKey(Key key);
@Override
public abstract void parse(SmaliReader reader) throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package com.reandroid.dex.smali.model;

import com.reandroid.dex.key.AnnotationItemKey;
import com.reandroid.dex.key.Key;
import com.reandroid.dex.smali.SmaliDirective;
import com.reandroid.dex.smali.SmaliReader;
import com.reandroid.dex.smali.SmaliRegion;
Expand All @@ -40,10 +41,22 @@ public AnnotationItemKey getKey() {
}
return null;
}
@Override
public void setKey(Key key) {
getOrCreateValue().setKey(key);
}

public SmaliAnnotationItem getValue() {
return value;
}
public SmaliAnnotationItem getOrCreateValue() {
SmaliAnnotationItem value = getValue();
if (value == null) {
value = new SmaliAnnotationItem();
setValue(value);
}
return value;
}
public void setValue(SmaliAnnotationItem value) {
this.value = value;
if(value != null){
Expand Down
19 changes: 15 additions & 4 deletions src/main/java/com/reandroid/dex/smali/model/SmaliValueArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ public ArrayKey getKey() {
}
return new ArrayKey(elements);
}
@Override
public void setKey(Key key) {
ArrayKey arrayKey = (ArrayKey) key;
clear();
for (Key entry : arrayKey) {
addValue(entry);
}
}

public SmaliSet<SmaliValue> getValues() {
return values;
Expand All @@ -62,6 +70,11 @@ public boolean remove(SmaliValue value) {
public void clear() {
values.clear();
}
public void addValue(Key value) {
SmaliValue smaliValue = SmaliValueFactory.createForValue(value);
add(smaliValue);
smaliValue.setKey(value);
}
public boolean add(SmaliValue value) {
return values.add(value);
}
Expand Down Expand Up @@ -121,16 +134,14 @@ public void parse(SmaliReader reader) throws IOException {
}
}
reader.skipWhitespaces();
if(reader.readASCII() != '}'){
// throw
}
SmaliParseException.expect(reader, '}');
}
private SmaliValue createNext(SmaliReader reader) throws IOException {
reader.skipWhitespacesOrComment();
byte b = reader.get();
if(b == '}'){
return null;
}
return SmaliValue.create(reader);
return SmaliValueFactory.create(reader);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.reandroid.dex.smali.model;

import com.reandroid.dex.key.Key;
import com.reandroid.dex.key.PrimitiveKey;
import com.reandroid.dex.smali.SmaliParseException;
import com.reandroid.dex.smali.SmaliReader;
Expand Down Expand Up @@ -42,6 +43,11 @@ public void setValue(boolean value) {
public PrimitiveKey getKey() {
return PrimitiveKey.of(getValue());
}
@Override
public void setKey(Key key) {
setValue(((PrimitiveKey.BooleanKey)key).value());
}

@Override
public DexValueType<?> getValueType() {
return DexValueType.BOOLEAN;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.reandroid.dex.smali.model;

import com.reandroid.dex.key.Key;
import com.reandroid.dex.key.PrimitiveKey;
import com.reandroid.dex.smali.SmaliParseException;
import com.reandroid.dex.smali.SmaliReader;
Expand Down Expand Up @@ -68,6 +69,10 @@ public long unsignedLong() {
public PrimitiveKey getKey() {
return PrimitiveKey.of(getValue());
}
@Override
public void setKey(Key key) {
setValue(((PrimitiveKey.ByteKey) key).value());
}

@Override
public DexValueType<?> getValueType() {
Expand Down
Loading

0 comments on commit c89eafa

Please sign in to comment.