Skip to content

Commit 2664403

Browse files
committed
[DEX] Switch and payload accessing
1 parent 70252a4 commit 2664403

3 files changed

Lines changed: 72 additions & 23 deletions

File tree

src/main/java/com/reandroid/dex/ins/InsSwitch.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,42 +21,42 @@
2121

2222
public abstract class InsSwitch extends Ins31t {
2323

24-
private InsSwitchPayload switchPayload;
24+
private InsSwitchPayload<?> switchPayload;
2525

2626
public InsSwitch(Opcode<?> opcode) {
2727
super(opcode);
2828
}
2929

30-
public InsSwitchPayload getPayload() {
31-
InsSwitchPayload switchPayload = this.switchPayload;
32-
if(switchPayload == null) {
30+
public InsSwitchPayload<? extends SwitchEntry> getPayload() {
31+
InsSwitchPayload<?> switchPayload = this.switchPayload;
32+
if (switchPayload == null) {
3333
switchPayload = findByAddress();
34-
if(switchPayload != null) {
34+
if (switchPayload != null) {
3535
this.switchPayload = switchPayload;
3636
switchPayload.setSwitch(this);
3737
}
3838
}
3939
return switchPayload;
4040
}
41-
public void setPayload(InsSwitchPayload switchPayload) {
41+
public void setPayload(InsSwitchPayload<?> switchPayload) {
4242
this.switchPayload = switchPayload;
4343
setTargetAddress(switchPayload.getAddress());
4444
}
4545

46-
private InsSwitchPayload findByAddress() {
46+
private InsSwitchPayload<?> findByAddress() {
4747
InstructionList instructionList = getInstructionList();
48-
if(instructionList != null){
49-
Iterator<? extends InsSwitchPayload> iterator = instructionList
48+
if (instructionList != null) {
49+
Iterator<? extends InsSwitchPayload<?>> iterator = instructionList
5050
.iterator(getPayloadOpcode());
5151
int address = getTargetAddress();
52-
while (iterator.hasNext()){
53-
InsSwitchPayload switchPayload = iterator.next();
54-
if(switchPayload.getAddress() == address){
52+
while (iterator.hasNext()) {
53+
InsSwitchPayload<?> switchPayload = iterator.next();
54+
if (switchPayload.getAddress() == address) {
5555
return switchPayload;
5656
}
5757
}
5858
}
5959
return null;
6060
}
61-
public abstract Opcode<? extends InsSwitchPayload> getPayloadOpcode();
61+
public abstract Opcode<? extends InsSwitchPayload<?>> getPayloadOpcode();
6262
}

src/main/java/com/reandroid/dex/ins/SwitchEntry.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ public interface SwitchEntry extends PayloadEntry, Label {
2121
@Override
2222
InsSwitchPayload<?> getPayload();
2323

24+
default InsSwitch getInsSwitch() {
25+
InsSwitchPayload<?> payload = getPayload();
26+
if (payload != null) {
27+
return payload.getSwitch();
28+
}
29+
return null;
30+
}
2431
@Override
2532
default boolean isRemoved() {
2633
return getPayload().isRemoved();
@@ -32,7 +39,7 @@ default void updateTargetAddress() {
3239
}
3340

3441
default void addEquivalentIfEq(int constRegister) {
35-
InsSwitch insSwitch = getPayload().getSwitch();
42+
InsSwitch insSwitch = getInsSwitch();
3643
InstructionList instructionList = insSwitch.getInstructionList();
3744

3845
Ins targetIns = getTargetIns();

src/main/java/com/reandroid/dex/model/DexInstruction.java

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,7 @@
2424
import com.reandroid.dex.id.IdItem;
2525
import com.reandroid.dex.id.MethodId;
2626
import com.reandroid.dex.id.StringId;
27-
import com.reandroid.dex.ins.ConstNumber;
28-
import com.reandroid.dex.ins.ConstNumberLong;
29-
import com.reandroid.dex.ins.Ins;
30-
import com.reandroid.dex.ins.InsConstStringJumbo;
31-
import com.reandroid.dex.ins.Label;
32-
import com.reandroid.dex.ins.Opcode;
33-
import com.reandroid.dex.ins.RegistersSet;
34-
import com.reandroid.dex.ins.SizeXIns;
27+
import com.reandroid.dex.ins.*;
3528
import com.reandroid.dex.key.FieldKey;
3629
import com.reandroid.dex.key.Key;
3730
import com.reandroid.dex.key.MethodKey;
@@ -311,6 +304,15 @@ public boolean isMethodInvokeInterface() {
311304
public boolean isMethodInvoke() {
312305
return getOpcode().isMethodInvoke();
313306
}
307+
public boolean isMove() {
308+
return getOpcode().isMove();
309+
}
310+
public boolean isMoveResult() {
311+
return getOpcode().isMoveResult();
312+
}
313+
public boolean hasOutRegisters() {
314+
return getOpcode().hasOutRegisters();
315+
}
314316
public int getTargetAddress() {
315317
Ins ins = getIns();
316318
if (ins instanceof Label) {
@@ -536,6 +538,36 @@ public Iterator<DexInstruction> getTargetingInstructionsIfOpcode(Predicate<Opcod
536538
iterator = FilterIterator.of(iterator, ins -> predicate.test(ins.getOpcode()));
537539
return DexInstruction.createAll(getDexMethod(), iterator);
538540
}
541+
// for switch payload instruction
542+
public Iterator<DexInstruction> getTargetSwitchCases() {
543+
Ins ins = getIns();
544+
if (!(ins instanceof InsSwitchPayload)) {
545+
return EmptyIterator.of();
546+
}
547+
InsSwitchPayload<? extends SwitchEntry> payload = (InsSwitchPayload<? extends SwitchEntry>) ins;
548+
Iterator<? extends SwitchEntry> switchEntryIterator = payload.iterator();
549+
if (!switchEntryIterator.hasNext()) {
550+
return EmptyIterator.of();
551+
}
552+
Iterator<Ins> iterator = ComputeIterator.of(switchEntryIterator, SwitchEntry::getTargetIns);
553+
iterator = CollectionUtil.copyOfUniqueOf(iterator);
554+
return DexInstruction.createAll(getDexMethod(), iterator);
555+
}
556+
public DexInstruction getTargetingSwitch() {
557+
return CollectionUtil.getFirst(getTargetingSwitches(null));
558+
}
559+
public Iterator<DexInstruction> getTargetingSwitches(Opcode<? extends InsSwitch> switchOpcode) {
560+
Iterator<SwitchEntry> switchEntryIterator = getIns().getForcedExtraLines(SwitchEntry.class);
561+
if (!switchEntryIterator.hasNext()) {
562+
return EmptyIterator.of();
563+
}
564+
Iterator<InsSwitch> iterator = ComputeIterator.of(switchEntryIterator, SwitchEntry::getInsSwitch);
565+
if (switchOpcode != null) {
566+
iterator = FilterIterator.of(iterator, ins -> ins.getOpcode() == switchOpcode);
567+
}
568+
iterator = CollectionUtil.copyOfUniqueOf(iterator);
569+
return DexInstruction.createAll(getDexMethod(), iterator);
570+
}
539571
public DexInstruction getNext() {
540572
return getDexMethod().getInstruction(getIndex() + 1);
541573
}
@@ -548,6 +580,16 @@ public DexInstruction getPrevious() {
548580
public Iterator<DexInstruction> getPreviousInstructions() {
549581
return LinkedIterator.of(this, DexInstruction::getPrevious);
550582
}
583+
public DexInstruction getMoveResult() {
584+
if (!hasOutRegisters()) {
585+
return null;
586+
}
587+
DexInstruction next = getNext();
588+
if (next != null && next.isMoveResult()) {
589+
return next;
590+
}
591+
return null;
592+
}
551593

552594
public DexInstruction getPreviousReader(int register) {
553595
return getPreviousReader(register, CollectionUtil.getAcceptAll());
@@ -643,7 +685,7 @@ public String toString() {
643685
return getIns().toString();
644686
}
645687

646-
public static Iterator<DexInstruction> createAll(DexMethod dexMethod, Iterator<Ins> iterator) {
688+
public static Iterator<DexInstruction> createAll(DexMethod dexMethod, Iterator<? extends Ins> iterator) {
647689
if (dexMethod == null || !iterator.hasNext()) {
648690
return EmptyIterator.of();
649691
}

0 commit comments

Comments
 (0)