Skip to content

Commit c31e7cc

Browse files
committed
[SMALI] method-handle parsing
1 parent 0f10065 commit c31e7cc

File tree

1 file changed

+62
-20
lines changed

1 file changed

+62
-20
lines changed

src/main/java/com/reandroid/dex/smali/model/SmaliInstructionOperand.java

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,16 @@
1717

1818
import com.reandroid.dex.common.OperandType;
1919
import com.reandroid.dex.ins.Opcode;
20-
import com.reandroid.dex.key.*;
20+
import com.reandroid.dex.key.CallSiteKey;
21+
import com.reandroid.dex.key.DualKeyReference;
22+
import com.reandroid.dex.key.FieldKey;
23+
import com.reandroid.dex.key.Key;
24+
import com.reandroid.dex.key.KeyReference;
25+
import com.reandroid.dex.key.MethodHandleKey;
26+
import com.reandroid.dex.key.MethodKey;
27+
import com.reandroid.dex.key.ProtoKey;
28+
import com.reandroid.dex.key.StringKey;
29+
import com.reandroid.dex.key.TypeKey;
2130
import com.reandroid.dex.sections.SectionType;
2231
import com.reandroid.dex.smali.SmaliParseException;
2332
import com.reandroid.dex.smali.SmaliReader;
@@ -28,7 +37,7 @@
2837

2938
public abstract class SmaliInstructionOperand extends Smali {
3039

31-
public SmaliInstructionOperand(){
40+
public SmaliInstructionOperand() {
3241
super();
3342
}
3443

@@ -38,16 +47,14 @@ public SmaliInstructionOperand(){
3847
public abstract void append(SmaliWriter writer) throws IOException;
3948

4049
@Override
41-
public final void parse(SmaliReader reader) throws IOException {
42-
throw new RuntimeException("Must call parse(Opcode, SmaliReader)");
43-
}
50+
public abstract void parse(SmaliReader reader) throws IOException;
4451
public abstract void parse(Opcode<?> opcode, SmaliReader reader) throws IOException;
4552

4653
public static class SmaliLabelOperand extends SmaliInstructionOperand {
4754

4855
private final SmaliLabel label;
4956

50-
public SmaliLabelOperand(){
57+
public SmaliLabelOperand() {
5158
super();
5259
this.label = new SmaliLabel();
5360
this.label.setParent(this);
@@ -72,6 +79,10 @@ public void append(SmaliWriter writer) throws IOException {
7279
getLabel().append(writer);
7380
}
7481

82+
@Override
83+
public void parse(SmaliReader reader) throws IOException {
84+
getLabel().parse(reader);
85+
}
7586
@Override
7687
public void parse(Opcode<?> opcode, SmaliReader reader) throws IOException {
7788
getLabel().parse(reader);
@@ -81,7 +92,7 @@ public static class SmaliHexOperand extends SmaliInstructionOperand {
8192

8293
private SmaliValueNumber<?> valueNumber;
8394

84-
public SmaliHexOperand(){
95+
public SmaliHexOperand() {
8596
super();
8697
valueNumber = new SmaliValueInteger();
8798
}
@@ -95,7 +106,7 @@ public SmaliValueNumber<?> getValueNumber() {
95106
}
96107
public void setNumberValue(SmaliValueNumber<?> valueNumber) {
97108
this.valueNumber = valueNumber;
98-
if(valueNumber != null){
109+
if (valueNumber != null) {
99110
valueNumber.setParent(this);
100111
}
101112
}
@@ -115,6 +126,10 @@ public void append(SmaliWriter writer) throws IOException {
115126
writer.appendOptional(getValueNumber());
116127
}
117128

129+
@Override
130+
public void parse(SmaliReader reader) throws IOException {
131+
parse(null, reader);
132+
}
118133
@Override
119134
public void parse(Opcode<?> opcode, SmaliReader reader) throws IOException {
120135
reader.skipSpaces();
@@ -125,7 +140,7 @@ public void parse(Opcode<?> opcode, SmaliReader reader) throws IOException {
125140
validate(opcode, reader, position);
126141
}
127142
private void validate(Opcode<?> opcode, SmaliReader reader, int position) throws IOException {
128-
if (opcode == Opcode.CONST_WIDE) {
143+
if (opcode == null || opcode == Opcode.CONST_WIDE) {
129144
return;
130145
}
131146
long value = getValueAsLong();
@@ -178,7 +193,7 @@ public int hashCode() {
178193
public static class SmaliDecimalOperand extends SmaliInstructionOperand {
179194
private int number;
180195

181-
public SmaliDecimalOperand(){
196+
public SmaliDecimalOperand() {
182197
super();
183198
}
184199

@@ -203,6 +218,11 @@ public void append(SmaliWriter writer) throws IOException {
203218
writer.appendInteger(getNumber());
204219
}
205220

221+
@Override
222+
public void parse(SmaliReader reader) throws IOException {
223+
reader.skipSpaces();
224+
setNumber(reader.readInteger());
225+
}
206226
@Override
207227
public void parse(Opcode<?> opcode, SmaliReader reader) throws IOException {
208228
reader.skipSpaces();
@@ -228,7 +248,7 @@ public static class SmaliKeyOperand extends SmaliInstructionOperand implements K
228248
private final OperandType operandType;
229249
private Key key;
230250

231-
public SmaliKeyOperand(OperandType operandType){
251+
public SmaliKeyOperand(OperandType operandType) {
232252
super();
233253
this.operandType = operandType;
234254
}
@@ -254,30 +274,38 @@ public OperandType getOperandType() {
254274
@Override
255275
public void append(SmaliWriter writer) throws IOException {
256276
Key key = getKey();
257-
if(key != null){
277+
if (key != null) {
258278
key.append(writer);
259279
}
260280
}
281+
282+
@Override
283+
public void parse(SmaliReader reader) throws IOException {
284+
setKey(parseKey(getOperandType().getSectionType(), reader));
285+
}
261286
@Override
262287
public void parse(Opcode<?> opcode, SmaliReader reader) throws IOException {
263288
setKey(parseKey(opcode.getSectionType(), reader));
264289
}
290+
265291
Key parseKey(SectionType<?> sectionType, SmaliReader reader) throws IOException {
266292
Key key;
267-
if(sectionType == SectionType.STRING_ID){
293+
if (sectionType == SectionType.STRING_ID) {
268294
key = StringKey.read(reader);
269-
}else if(sectionType == SectionType.TYPE_ID){
295+
} else if (sectionType == SectionType.TYPE_ID) {
270296
key = TypeKey.read(reader);
271-
}else if(sectionType == SectionType.FIELD_ID){
297+
} else if (sectionType == SectionType.FIELD_ID) {
272298
key = FieldKey.read(reader);
273-
}else if(sectionType == SectionType.PROTO_ID){
299+
} else if (sectionType == SectionType.PROTO_ID) {
274300
key = ProtoKey.read(reader);
275-
}else if(sectionType == SectionType.METHOD_ID){
301+
} else if (sectionType == SectionType.METHOD_ID) {
276302
key = MethodKey.read(reader);
277-
}else if(sectionType == SectionType.CALL_SITE_ID){
303+
} else if (sectionType == SectionType.CALL_SITE_ID) {
278304
key = CallSiteKey.read(reader);
279-
}else {
280-
throw new SmaliParseException("Invalid key", reader);
305+
} else if (sectionType == SectionType.METHOD_HANDLE) {
306+
key = MethodHandleKey.read(reader);
307+
} else {
308+
throw new SmaliParseException("Undefined section type: " + sectionType, reader);
281309
}
282310
return key;
283311
}
@@ -325,6 +353,15 @@ public void append(SmaliWriter writer) throws IOException {
325353
key.append(writer);
326354
}
327355
}
356+
357+
@Override
358+
public void parse(SmaliReader reader) throws IOException {
359+
super.parse(reader);
360+
reader.skipWhitespaces();
361+
SmaliParseException.expect(reader, ',');
362+
reader.skipWhitespaces();
363+
setKey2(parseKey(getOperandType().getSectionType2(), reader));
364+
}
328365
@Override
329366
public void parse(Opcode<?> opcode, SmaliReader reader) throws IOException {
330367
super.parse(opcode, reader);
@@ -366,6 +403,11 @@ public OperandType getOperandType() {
366403
@Override
367404
public void append(SmaliWriter writer) {
368405
}
406+
407+
@Override
408+
public void parse(SmaliReader reader) {
409+
reader.skipSpaces();
410+
}
369411
@Override
370412
public void parse(Opcode<?> opcode, SmaliReader reader) {
371413
reader.skipSpaces();

0 commit comments

Comments
 (0)