Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix handling of Annotations in Dex code & UnconditionalBranchFolder #2068

Merged
merged 6 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions src/main/java/soot/dexpler/DexAnnotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand Down Expand Up @@ -113,6 +115,18 @@ public class DexAnnotation {
private final SootClass clazz;
private final Dependencies deps;

protected static Set<String> isHandled = new HashSet<>();

static {
isHandled.add(SootToDexUtils.getDexClassName(DALVIK_ANNOTATION_DEFAULT));
isHandled.add(SootToDexUtils.getDexClassName(DALVIK_ANNOTATION_SIGNATURE));
isHandled.add(SootToDexUtils.getDexClassName(DALVIK_ANNOTATION_MEMBERCLASSES));
isHandled.add(SootToDexUtils.getDexClassName(DALVIK_ANNOTATION_INNERCLASS));
isHandled.add(SootToDexUtils.getDexClassName(DALVIK_ANNOTATION_ENCLOSINGMETHOD));
isHandled.add(SootToDexUtils.getDexClassName(DALVIK_ANNOTATION_ENCLOSINGCLASS));
isHandled.add(SootToDexUtils.getDexClassName(JAVA_DEPRECATED));
}

public DexAnnotation(SootClass clazz, Dependencies deps) {
this.clazz = clazz;
this.deps = deps;
Expand Down Expand Up @@ -161,8 +175,11 @@ public void handleClassAnnotation(ClassDef classDef) {
// to methods through the creation of new
// AnnotationDefaultTag.
VisibilityAnnotationTag vt = (VisibilityAnnotationTag) t;
for (AnnotationTag a : vt.getAnnotations()) {
Iterator<AnnotationTag> it = vt.getAnnotations().iterator();
while (it.hasNext()) {
AnnotationTag a = it.next();
if (a.getType().equals("Ldalvik/annotation/AnnotationDefault;")) {
it.remove();
for (AnnotationElem ae : a.getElems()) {
if (ae instanceof AnnotationAnnotationElem) {
AnnotationAnnotationElem aae = (AnnotationAnnotationElem) ae;
Expand Down Expand Up @@ -228,8 +245,19 @@ public void handleClassAnnotation(ClassDef classDef) {
}
}
}
if (!(vt.getVisibility() == AnnotationConstants.RUNTIME_INVISIBLE)) {
if (vt.getVisibility() == AnnotationConstants.RUNTIME_INVISIBLE) {
clazz.addTag(vt);
} else {
// filter out the tags we handle explicitly
VisibilityAnnotationTag vbCopy = new VisibilityAnnotationTag(vt.getVisibility());
for (AnnotationTag tf : vt.getAnnotations()) {
if (!isHandled(tf)) {
vbCopy.addAnnotation(tf);
}
}
if (vbCopy.getAnnotations() != null && !vbCopy.getAnnotations().isEmpty()) {
clazz.addTag(vbCopy);
}
}
} else {
clazz.addTag(t);
Expand All @@ -238,6 +266,10 @@ public void handleClassAnnotation(ClassDef classDef) {
}
}

private boolean isHandled(AnnotationTag tf) {
return isHandled.contains(tf.getType());
}

private Type getSootType(AnnotationElem e) {
Type annotationType;
switch (e.getKind()) {
Expand Down
34 changes: 34 additions & 0 deletions src/main/java/soot/jimple/BranchableStmt.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package soot.jimple;

/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 1999 Raja Vallee-Rai
* %%
* 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.Unit;
import soot.UnitBox;

public interface BranchableStmt extends Stmt {
public Unit getTarget();

public void setTarget(Unit target);

public UnitBox getTargetBox();
}
2 changes: 1 addition & 1 deletion src/main/java/soot/jimple/GotoStmt.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import soot.Unit;
import soot.UnitBox;

public interface GotoStmt extends Stmt {
public interface GotoStmt extends BranchableStmt {
public Unit getTarget();

public void setTarget(Unit target);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/soot/jimple/internal/JIfStmt.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import soot.baf.Baf;
import soot.jimple.AbstractJimpleValueSwitch;
import soot.jimple.BinopExpr;
import soot.jimple.BranchableStmt;
import soot.jimple.ConvertToBaf;
import soot.jimple.EqExpr;
import soot.jimple.GeExpr;
Expand All @@ -50,7 +51,7 @@
import soot.jimple.StmtSwitch;
import soot.util.Switch;

public class JIfStmt extends AbstractStmt implements IfStmt {
public class JIfStmt extends AbstractStmt implements IfStmt, BranchableStmt {

protected final ValueBox conditionBox;
protected final UnitBox targetBox;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import soot.Unit;
import soot.UnitBox;
import soot.Value;
import soot.jimple.BranchableStmt;
import soot.jimple.ConditionExpr;
import soot.jimple.GotoStmt;
import soot.jimple.IfStmt;
Expand Down Expand Up @@ -213,6 +214,37 @@ public Result transform() {
succAsGoto.setTarget(ifTarget);
stmtAsIfStmt.setTarget(gotoTarget);
ifTarget = gotoTarget;
// We need to check whether anyone has a goto to the "goto X", because this no has to also go
// to Y

// If we wouldn't do that, we would e.g. go from
// if $i0 == 6 goto label04;
// label03:
// goto label21;
// ...
// goto label3;

// to
// if $i0 != 6 goto label21;
// label03:
// goto label04;
// label04:
// ...
// goto label03;
// this would alter the semantics, since the previous go-tos now go to the other branch!
if (!succAsGoto.getBoxesPointingToThis().isEmpty()) {
// we cannot simply use getBoxesPointingToThis, because we do not want to update
// trap references
for (Unit i : units) {
if (i instanceof BranchableStmt) {
BranchableStmt b = (BranchableStmt) i;
if (b.getTarget() == succAsGoto) {
b.setTarget(gotoTarget);
}
}
}
}

// NOTE: No need to remove the goto [successor] because it
// is processed by the next iteration of the main loop.
// NOTE: Nothing is removed here, it is a simple refactoring.
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/soot/toDex/DexPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -496,9 +496,9 @@ private EncodedValue buildEncodedValueForAnnotation(AnnotationElem elem) {
Collection<AnnotationElem> elems = e.getValue().getElems();
if (!elems.isEmpty()) {
elements = new ArrayList<AnnotationElement>();
Set<String> alreadyWritten = new HashSet<String>();
Set<AnnotationElem> alreadyWritten = new HashSet<AnnotationElem>();
for (AnnotationElem ae : elems) {
if (!alreadyWritten.add(ae.getName())) {
if (!alreadyWritten.add(ae)) {
throw new DexPrinterException("Duplicate annotation attribute: " + ae.getName());
}
elements.add(new ImmutableAnnotationElement(ae.getName(), buildEncodedValueForAnnotation(ae)));
Expand Down Expand Up @@ -670,7 +670,7 @@ protected void addClassDefinition(ClassDef classDef) {
}
}

private Set<Annotation> buildClassAnnotations(SootClass c) {
protected Set<Annotation> buildClassAnnotations(SootClass c) {
Set<String> skipList = new HashSet<String>();
Set<Annotation> annotations = buildCommonAnnotations(c, skipList);

Expand Down Expand Up @@ -855,7 +855,7 @@ private Set<Annotation> buildCommonAnnotations(AbstractHost host, Set<String> sk
return annotations;
}

private List<ImmutableAnnotation> buildVisibilityAnnotationTag(VisibilityAnnotationTag t, Set<String> skipList) {
protected List<ImmutableAnnotation> buildVisibilityAnnotationTag(VisibilityAnnotationTag t, Set<String> skipList) {
if (t.getAnnotations() == null) {
return Collections.emptyList();
}
Expand Down
Loading