use of com.googlecode.d2j.DexLabel in project dex2jar by pxb1988.
the class Dex2IRConverter method fixExceptionHandlers.
/**
* issue 63
* <pre>
* L1:
* STMTs
* L2:
* RETURN
* L1~L2 > L2 Exception
* </pre>
* <p/>
* fix to
* <p/>
* <pre>
* L1:
* STMTs
* L2:
* RETURN
* L3:
* goto L2
* L1~L2 > L3 Exception
* </pre>
*/
private void fixExceptionHandlers() {
if (dexCodeNode.tryStmts == null) {
return;
}
Queue<Integer> q = new LinkedList<>();
Set<Integer> handlers = new TreeSet<>();
for (TryCatchNode tcb : dexCodeNode.tryStmts) {
for (DexLabel h : tcb.handler) {
int index = indexOf(h);
// add the next insn after label
q.add(index + 1);
handlers.add(index);
}
}
q.add(0);
Map<Integer, DexLabel> needChange = new HashMap<>();
BitSet access = new BitSet(insnList.size());
while (!q.isEmpty()) {
Integer key = q.poll();
int index = key;
if (access.get(index)) {
continue;
} else {
access.set(index);
}
if (handlers.contains(key)) {
// the cfg goes to a exception handler
needChange.put(key, null);
}
DexStmtNode node = insnList.get(key);
if (node.op == null) {
q.add(index + 1);
} else {
Op op = node.op;
if (op.canContinue()) {
q.add(index + 1);
}
if (op.canBranch()) {
JumpStmtNode jump = (JumpStmtNode) node;
q.add(indexOf(jump.label));
}
if (op.canSwitch()) {
for (DexLabel dexLabel : ((BaseSwitchStmtNode) node).labels) {
q.add(indexOf(dexLabel));
}
}
}
}
if (needChange.size() > 0) {
for (TryCatchNode tcb : dexCodeNode.tryStmts) {
DexLabel[] handler = tcb.handler;
for (int i = 0; i < handler.length; i++) {
DexLabel h = handler[i];
int index = indexOf(h);
if (needChange.containsKey(index)) {
DexLabel n = needChange.get(index);
if (n == null) {
n = new DexLabel();
needChange.put(index, n);
DexLabelStmtNode dexStmtNode = new DexLabelStmtNode(n);
dexStmtNode.__index = insnList.size();
insnList.add(dexStmtNode);
labelMap.put(n, dexStmtNode);
JumpStmtNode jumpStmtNode = new JumpStmtNode(Op.GOTO, 0, 0, h);
jumpStmtNode.__index = insnList.size();
insnList.add(jumpStmtNode);
}
handler[i] = n;
}
}
}
}
}
use of com.googlecode.d2j.DexLabel in project dex2jar by pxb1988.
the class ArrayTypeTest method merge1.
@Test
public static void merge1(DexClassVisitor cv) {
// obj = array
DexMethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, new Method("La;", "b", new String[] {}, "V"));
DexCodeVisitor code = mv.visitCode();
DexLabel L0 = new DexLabel();
DexLabel L1 = new DexLabel();
code.visitRegister(3);
code.visitConstStmt(CONST, 0, 0);
code.visitJumpStmt(GOTO, -1, -1, L1);
code.visitLabel(L0);
code.visitStmt2R(ARRAY_LENGTH, 1, 0);
code.visitConstStmt(CONST, 1, 0);
code.visitStmt3R(AGET, 2, 0, 1);
code.visitStmt0R(RETURN_VOID);
code.visitLabel(L1);
code.visitConstStmt(CONST, 1, 1);
code.visitTypeStmt(NEW_ARRAY, 0, 1, "[Ljava/security/cert/X509Certificate;");
code.visitJumpStmt(GOTO, -1, -1, L0);
code.visitEnd();
mv.visitEnd();
}
use of com.googlecode.d2j.DexLabel in project dex2jar by pxb1988.
the class CodeWriter method visitPackedSwitchStmt.
@Override
public void visitPackedSwitchStmt(Op op, int aA, final int first_case, final DexLabel[] labels) {
Label switch_data_location = new Label();
final JumpOp jumpOp = new JumpOp(op, aA, 0, switch_data_location);
ops.add(jumpOp);
tailOps.add(switch_data_location);
tailOps.add(new Insn() {
@Override
public int getCodeUnitSize() {
return (labels.length * 2) + 4;
}
@Override
public void write(ByteBuffer out) {
out.putShort((short) 0x0100).putShort((short) labels.length).putInt(first_case);
for (int i = 0; i < labels.length; i++) {
out.putInt(getLabel(labels[i]).offset - jumpOp.offset);
}
}
});
}
use of com.googlecode.d2j.DexLabel in project dex2jar by pxb1988.
the class CodeWriter method visitSparseSwitchStmt.
@Override
public void visitSparseSwitchStmt(Op op, int ra, final int[] cases, final DexLabel[] labels) {
Label switch_data_location = new Label();
final JumpOp jumpOp = new JumpOp(op, ra, 0, switch_data_location);
ops.add(jumpOp);
tailOps.add(switch_data_location);
tailOps.add(new Insn() {
@Override
public int getCodeUnitSize() {
return (cases.length * 4) + 2;
}
@Override
public void write(ByteBuffer out) {
out.putShort((short) 0x0200).putShort((short) cases.length);
for (int i = 0; i < cases.length; i++) {
out.putInt(cases[i]);
}
for (int i = 0; i < cases.length; i++) {
out.putInt(getLabel(labels[i]).offset - jumpOp.offset);
}
}
});
}
use of com.googlecode.d2j.DexLabel in project dex2jar by pxb1988.
the class Dex2IRConverter method initExceptionHandlers.
private void initExceptionHandlers(DexCodeNode dexCodeNode, BitSet[] exBranch, BitSet handlers) {
if (dexCodeNode.tryStmts != null) {
for (TryCatchNode tcb : dexCodeNode.tryStmts) {
target.traps.add(new Trap(getLabel(tcb.start), getLabel(tcb.end), getLabels(tcb.handler), tcb.type));
for (DexLabel h : tcb.handler) {
handlers.set(indexOf(h));
}
int endIndex = indexOf(tcb.end);
for (int p = indexOf(tcb.start) + 1; p < endIndex; p++) {
DexStmtNode stmt = insnList.get(p);
if (stmt.op != null && stmt.op.canThrow()) {
BitSet x = exBranch[p];
if (x == null) {
x = exBranch[p] = new BitSet(insnList.size());
}
for (DexLabel h : tcb.handler) {
int hIndex = indexOf(h);
x.set(hIndex);
parentCount[hIndex]++;
}
}
}
}
}
}
Aggregations