Skip to content

Commit

Permalink
Merge pull request #2072 from MarcMil/fix-dex-annotations
Browse files Browse the repository at this point in the history
Dalvik import/export: Save special type (direct/super) as tag
  • Loading branch information
StevenArzt authored Apr 25, 2024
2 parents a949734 + 0de6c3e commit 7e7ac53
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/main/java/soot/dexpler/DexAnnotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ public void handleClassAnnotation(ClassDef classDef) {
// to methods through the creation of new
// AnnotationDefaultTag.
VisibilityAnnotationTag vt = (VisibilityAnnotationTag) t;
if (!vt.hasAnnotations()) {
continue;
}
Iterator<AnnotationTag> it = vt.getAnnotations().iterator();
while (it.hasNext()) {
AnnotationTag a = it.next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,10 @@ public static DexlibAbstractInstruction fromOpcode(Opcode op, Instruction instru

case INVOKE_DIRECT:
case INVOKE_DIRECT_RANGE:
return new InvokeSpecialDirectInstruction(instruction, codeAddress);
case INVOKE_SUPER:
case INVOKE_SUPER_RANGE:
return new InvokeSpecialInstruction(instruction, codeAddress);
return new InvokeSpecialSuperInstruction(instruction, codeAddress);

case INVOKE_STATIC:
case INVOKE_STATIC_RANGE:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package soot.dexpler.instructions;

/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2012 Michael Markert, Frank Hartmann
*
* (c) 2012 University of Luxembourg - Interdisciplinary Centre for
* Security Reliability and Trust (SnT) - All rights reserved
* Alexandre Bartel
*
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/

import org.jf.dexlib2.iface.instruction.Instruction;

import soot.dexpler.DexBody;
import soot.dexpler.tags.SpecialInvokeTypeTag;
import soot.dexpler.tags.SpecialInvokeTypeTag.Type;

public class InvokeSpecialDirectInstruction extends InvokeSpecialInstruction {

public InvokeSpecialDirectInstruction(Instruction instruction, int codeAdress) {
super(instruction, codeAdress);
}

@Override
public void finalize(DexBody body, DexlibAbstractInstruction successor) {
super.finalize(body, successor);
getUnit().addTag(new SpecialInvokeTypeTag(Type.DIRECT));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.jf.dexlib2.iface.instruction.Instruction;

import soot.dexpler.DexBody;
import soot.jimple.InvokeExpr;

public class InvokeSpecialInstruction extends MethodInvocationInstruction {

Expand All @@ -41,4 +42,8 @@ public void jimplify(DexBody body) {
jimplifySpecial(body);
}

public InvokeExpr getJimplifiedInvoke() {
return invocation;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package soot.dexpler.instructions;

/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 2012 Michael Markert, Frank Hartmann
*
* (c) 2012 University of Luxembourg - Interdisciplinary Centre for
* Security Reliability and Trust (SnT) - All rights reserved
* Alexandre Bartel
*
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/

import org.jf.dexlib2.iface.instruction.Instruction;

import soot.dexpler.DexBody;
import soot.dexpler.tags.SpecialInvokeTypeTag;
import soot.dexpler.tags.SpecialInvokeTypeTag.Type;

public class InvokeSpecialSuperInstruction extends InvokeSpecialInstruction {

public InvokeSpecialSuperInstruction(Instruction instruction, int codeAdress) {
super(instruction, codeAdress);
}

@Override
public void finalize(DexBody body, DexlibAbstractInstruction successor) {
super.finalize(body, successor);
getUnit().addTag(new SpecialInvokeTypeTag(Type.SUPER));
}
}
85 changes: 85 additions & 0 deletions src/main/java/soot/dexpler/tags/SpecialInvokeTypeTag.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// (c) 2012 University of Luxembourg - Interdisciplinary Centre for
// Security Reliability and Trust (SnT) - All rights reserved
//
// Author: Alexandre Bartel
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2.1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

package soot.dexpler.tags;

/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 2018 Raja Vallée-Rai and others
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-2.1.html>.
* #L%
*/

import soot.tagkit.Tag;

/**
* Dalvik distinguishes between different type of special invocations, while soot does not. Soot tries to infer the proper
* type upon writing out dex code, but fails sometimes in presence of obfuscated code or due to the Kotlin compiler. We try
* to be as close to the original as possible
*
* @author Marc Miltenberger
*/
public class SpecialInvokeTypeTag implements Tag {

public static final String NAME = "SpecialInvokeTypeTag";

public static enum Type {
UNKNOWN, DIRECT, SUPER;
}

private final Type type;

public SpecialInvokeTypeTag() {
type = Type.UNKNOWN;
}

public SpecialInvokeTypeTag(Type type) {
this.type = type;
}

public Type getType() {
return type;
}

@Override
public String getName() {
return NAME;
}

@Override
public byte[] getValue() {
return new byte[1];
}
}
20 changes: 19 additions & 1 deletion src/main/java/soot/toDex/ExprVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import soot.SootMethod;
import soot.Type;
import soot.Value;
import soot.dexpler.tags.SpecialInvokeTypeTag;
import soot.jimple.AddExpr;
import soot.jimple.AndExpr;
import soot.jimple.CastExpr;
Expand Down Expand Up @@ -99,7 +100,6 @@
import soot.toDex.instructions.Insn3rc;
import soot.toDex.instructions.InsnWithOffset;
import soot.util.NumberedString;
import soot.util.Switchable;

/**
* A visitor that builds a list of instructions from the Jimple expressions it visits.<br>
Expand Down Expand Up @@ -162,6 +162,24 @@ public void caseSpecialInvokeExpr(SpecialInvokeExpr sie) {
MethodReference method = DexPrinter.toMethodReference(sie.getMethodRef());
List<Register> arguments = getInstanceInvokeArgumentRegs(sie);
lastInvokeInstructionPosition = stmtV.getInstructionCount();
SpecialInvokeTypeTag tg = (SpecialInvokeTypeTag) origStmt.getTag(SpecialInvokeTypeTag.NAME);
if (tg != null) {
// eliminate the guesswork...
switch (tg.getType()) {
case DIRECT:
stmtV.addInsn(buildInvokeInsn("INVOKE_DIRECT", method, arguments), origStmt);
return;
case SUPER:
stmtV.addInsn(buildInvokeInsn("INVOKE_SUPER", method, arguments), origStmt);
return;
case UNKNOWN:
// well... revert to original algorithm
break;
default:
throw new RuntimeException("Unsupported special invoke type: " + tg.getType());

}
}
if (isCallToConstructor(sie) || isCallToPrivate(sie)) {
stmtV.addInsn(buildInvokeInsn("INVOKE_DIRECT", method, arguments), origStmt);
} else if (isCallToSuper(sie)) {
Expand Down

0 comments on commit 7e7ac53

Please sign in to comment.