use of org.jf.dexlib2 in project soot by Sable.
the class DexAnnotation method handleAnnotation.
/**
* @param annotations
* @return
*/
private List<Tag> handleAnnotation(Set<? extends org.jf.dexlib2.iface.Annotation> annotations, String classType) {
if (annotations == null || annotations.size() == 0)
return null;
List<Tag> tags = new ArrayList<Tag>();
// RUNTIME_VISIBLE,
VisibilityAnnotationTag[] vatg = new VisibilityAnnotationTag[3];
for (Annotation a : annotations) {
int v = getVisibility(a.getVisibility());
Tag t = null;
Type atype = DexType.toSoot(a.getType());
String atypes = atype.toString();
int eSize = a.getElements().size();
if (atypes.equals("dalvik.annotation.AnnotationDefault")) {
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation Default. Got " + eSize + " instead.");
// get element
AnnotationElem e = getElements(a.getElements()).get(0);
AnnotationTag adt = new AnnotationTag(a.getType());
adt.addElem(e);
if (vatg[v] == null)
vatg[v] = new VisibilityAnnotationTag(v);
vatg[v].addAnnotation(adt);
} else if (atypes.equals("dalvik.annotation.EnclosingClass")) {
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation EnclosingClass. Got " + eSize + " instead.");
for (AnnotationElement elem : a.getElements()) {
String outerClass = ((TypeEncodedValue) elem.getValue()).getValue();
outerClass = Util.dottedClassName(outerClass);
// repair it
if (outerClass.equals(clazz.getName())) {
if (outerClass.contains("$-")) {
/*
* This is a special case for generated lambda
* classes of jack and jill compiler. Generated
* lambda classes may contain '$' which do not
* indicate an inner/outer class separator if the
* '$' occurs after a inner class with a name
* starting with '-'. Thus we search for '$-' and
* anything after it including '-' is the inner
* classes name and anything before it is the outer
* classes name.
*/
outerClass = outerClass.substring(0, outerClass.indexOf("$-"));
} else if (outerClass.contains("$")) {
// remove everything after the last '$' including
// the last '$'
outerClass = outerClass.substring(0, outerClass.lastIndexOf("$"));
}
}
deps.typesToSignature.add(RefType.v(outerClass));
clazz.setOuterClass(SootResolver.v().makeClassRef(outerClass));
assert clazz.getOuterClass() != clazz;
}
// annotation.
continue;
} else if (atypes.equals("dalvik.annotation.EnclosingMethod")) {
// ignore the annotation
if (eSize == 0)
continue;
// If the pointer is ambiguous, we are in trouble
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation EnclosingMethod. Got " + eSize + " instead.");
AnnotationStringElem e = (AnnotationStringElem) getElements(a.getElements()).get(0);
String[] split1 = e.getValue().split("\\ \\|");
String classString = split1[0];
String methodString = split1[1];
String parameters = split1[2];
String returnType = split1[3];
String methodSigString = "(" + parameters + ")" + returnType;
t = new EnclosingMethodTag(classString, methodString, methodSigString);
String outerClass = classString.replace("/", ".");
deps.typesToSignature.add(RefType.v(outerClass));
clazz.setOuterClass(SootResolver.v().makeClassRef(outerClass));
assert clazz.getOuterClass() != clazz;
} else if (atypes.equals("dalvik.annotation.InnerClass")) {
// access flags of the inner class
int accessFlags = -1;
// name of the inner class
String name = null;
for (AnnotationElem ele : getElements(a.getElements())) {
if (ele instanceof AnnotationIntElem && ele.getName().equals("accessFlags"))
accessFlags = ((AnnotationIntElem) ele).getValue();
else if (ele instanceof AnnotationStringElem && ele.getName().equals("name"))
name = ((AnnotationStringElem) ele).getValue();
else
throw new RuntimeException("Unexpected inner class annotation element");
}
// outer class name
String outerClass;
if (clazz.hasOuterClass()) {
// If we have already set an outer class from some other
// annotation, we use that
// one.
outerClass = clazz.getOuterClass().getName();
} else if (classType.contains("$-")) {
/*
* This is a special case for generated lambda classes of
* jack and jill compiler. Generated lambda classes may
* contain '$' which do not indicate an inner/outer class
* separator if the '$' occurs after a inner class with a
* name starting with '-'. Thus we search for '$-' and
* anything after it including '-' is the inner classes name
* and anything before it is the outer classes name.
*/
outerClass = classType.substring(0, classType.indexOf("$-"));
if (Util.isByteCodeClassName(classType))
outerClass += ";";
} else if (classType.contains("$")) {
// remove everything after the last '$' including the last
// '$'
outerClass = classType.substring(0, classType.lastIndexOf("$")) + ";";
if (Util.isByteCodeClassName(classType))
outerClass += ";";
} else {
// Make sure that no funny business is going on if the
// annotation is broken and does not end in $nn.
outerClass = null;
}
Tag innerTag = new InnerClassTag(DexType.toSootICAT(classType), outerClass == null ? null : DexType.toSootICAT(outerClass), name, accessFlags);
tags.add(innerTag);
if (outerClass != null && !clazz.hasOuterClass()) {
String sootOuterClass = Util.dottedClassName(outerClass);
deps.typesToSignature.add(RefType.v(sootOuterClass));
clazz.setOuterClass(SootResolver.v().makeClassRef(sootOuterClass));
assert clazz.getOuterClass() != clazz;
}
continue;
} else if (atypes.equals("dalvik.annotation.MemberClasses")) {
AnnotationArrayElem e = (AnnotationArrayElem) getElements(a.getElements()).get(0);
for (AnnotationElem ae : e.getValues()) {
AnnotationClassElem c = (AnnotationClassElem) ae;
String innerClass = c.getDesc();
String outerClass;
String name;
if (innerClass.contains("$-")) {
/*
* This is a special case for generated lambda classes
* of jack and jill compiler. Generated lambda classes
* may contain '$' which do not indicate an inner/outer
* class separator if the '$' occurs after a inner class
* with a name starting with '-'. Thus we search for
* '$-' and anything after it including '-' is the inner
* classes name and anything before it is the outer
* classes name.
*/
int i = innerClass.indexOf("$-");
outerClass = innerClass.substring(0, i);
name = innerClass.substring(i + 2).replaceAll(";$", "");
} else if (innerClass.contains("$")) {
// remove everything after the last '$' including the
// last '$'
int i = innerClass.lastIndexOf("$");
outerClass = innerClass.substring(0, i);
name = innerClass.substring(i + 1).replaceAll(";$", "");
} else {
// Make sure that no funny business is going on if the
// annotation is broken and does not end in $nn.
outerClass = null;
name = null;
}
if (// anonymous or
name != null && name.matches("^\\d*$"))
// local inner
// classes
name = null;
// seems like this information is lost
int accessFlags = 0;
// during the .class -- dx --> .dex
// process.
Tag innerTag = new InnerClassTag(DexType.toSootICAT(innerClass), outerClass == null ? null : DexType.toSootICAT(outerClass), name, accessFlags);
tags.add(innerTag);
}
continue;
} else if (atypes.equals("dalvik.annotation.Signature")) {
if (eSize != 1)
throw new RuntimeException("error: expected 1 element for annotation Signature. Got " + eSize + " instead.");
AnnotationArrayElem e = (AnnotationArrayElem) getElements(a.getElements()).get(0);
String sig = "";
for (AnnotationElem ae : e.getValues()) {
AnnotationStringElem s = (AnnotationStringElem) ae;
sig += s.getValue();
}
t = new SignatureTag(sig);
} else if (atypes.equals("dalvik.annotation.Throws")) {
// this is handled in soot.dexpler.DexMethod
continue;
} else if (atypes.equals("java.lang.Deprecated")) {
if (eSize != 0)
throw new RuntimeException("error: expected 1 element for annotation Deprecated. Got " + eSize + " instead.");
t = new DeprecatedTag();
AnnotationTag adt = new AnnotationTag("Ljava/lang/Deprecated;");
if (vatg[v] == null)
vatg[v] = new VisibilityAnnotationTag(v);
vatg[v].addAnnotation(adt);
} else {
if (vatg[v] == null)
vatg[v] = new VisibilityAnnotationTag(v);
AnnotationTag tag = new AnnotationTag(a.getType());
for (AnnotationElem e : getElements(a.getElements())) tag.addElem(e);
vatg[v].addAnnotation(tag);
}
tags.add(t);
}
for (VisibilityAnnotationTag vat : vatg) if (vat != null)
tags.add(vat);
return tags;
}
use of org.jf.dexlib2 in project smali by JesusFreke.
the class DexPool method writeTo.
public static void writeTo(@Nonnull DexDataStore dataStore, @Nonnull org.jf.dexlib2.iface.DexFile input) throws IOException {
DexPool dexPool = new DexPool(input.getOpcodes());
for (ClassDef classDef : input.getClasses()) {
dexPool.internClass(classDef);
}
dexPool.writeTo(dataStore);
}
use of org.jf.dexlib2 in project atlas by alibaba.
the class InstructionMethodItem method writeTo.
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
Opcode opcode = instruction.getOpcode();
String verificationErrorName = null;
String referenceString = null;
String referenceString2 = null;
boolean commentOutInstruction = false;
if (instruction instanceof Instruction20bc) {
int verificationError = ((Instruction20bc) instruction).getVerificationError();
verificationErrorName = VerificationError.getVerificationErrorName(verificationError);
if (verificationErrorName == null) {
writer.write("#was invalid verification error type: ");
writer.printSignedIntAsDec(verificationError);
writer.write("\n");
verificationErrorName = "generic-error";
}
}
if (instruction instanceof ReferenceInstruction) {
ReferenceInstruction referenceInstruction = (ReferenceInstruction) instruction;
String classContext = null;
if (methodDef.classDef.options.implicitReferences) {
classContext = methodDef.method.getDefiningClass();
}
try {
Reference reference = referenceInstruction.getReference();
referenceString = org.jf.dexlib2.util.ReferenceUtil.getReferenceString(reference, classContext);
assert referenceString != null;
} catch (InvalidItemIndex ex) {
commentOutInstruction = true;
referenceString = writeInvalidItemIndex(ex, referenceInstruction.getReferenceType(), writer);
} catch (ReferenceType.InvalidReferenceTypeException ex) {
writer.write("#invalid reference type: ");
writer.printSignedIntAsDec(ex.getReferenceType());
commentOutInstruction = true;
referenceString = "invalid_reference";
}
if (instruction instanceof DualReferenceInstruction) {
DualReferenceInstruction dualReferenceInstruction = (DualReferenceInstruction) instruction;
try {
Reference reference2 = dualReferenceInstruction.getReference2();
referenceString2 = org.jf.dexlib2.util.ReferenceUtil.getReferenceString(reference2, classContext);
} catch (InvalidItemIndex ex) {
commentOutInstruction = true;
referenceString2 = writeInvalidItemIndex(ex, dualReferenceInstruction.getReferenceType2(), writer);
} catch (ReferenceType.InvalidReferenceTypeException ex) {
writer.write("#invalid reference type: ");
writer.printSignedIntAsDec(ex.getReferenceType());
commentOutInstruction = true;
referenceString2 = "invalid_reference";
}
}
}
if (instruction instanceof Instruction31t) {
boolean validPayload = true;
switch(instruction.getOpcode()) {
case PACKED_SWITCH:
int baseAddress = methodDef.getPackedSwitchBaseAddress(this.codeAddress + ((Instruction31t) instruction).getCodeOffset());
if (baseAddress == -1) {
validPayload = false;
}
break;
case SPARSE_SWITCH:
baseAddress = methodDef.getSparseSwitchBaseAddress(this.codeAddress + ((Instruction31t) instruction).getCodeOffset());
if (baseAddress == -1) {
validPayload = false;
}
break;
case FILL_ARRAY_DATA:
try {
methodDef.findPayloadOffset(this.codeAddress + ((Instruction31t) instruction).getCodeOffset(), Opcode.ARRAY_PAYLOAD);
} catch (org.jf.baksmali.Adaptors.MethodDefinition.InvalidSwitchPayload ex) {
validPayload = false;
}
break;
default:
throw new ExceptionWithContext("Invalid 31t opcode: %s", instruction.getOpcode());
}
if (!validPayload) {
writer.write("#invalid payload reference\n");
commentOutInstruction = true;
}
}
if (opcode.odexOnly()) {
if (!isAllowedOdex(opcode)) {
writer.write("#disallowed odex opcode\n");
commentOutInstruction = true;
}
}
if (commentOutInstruction) {
writer.write("#");
}
switch(instruction.getOpcode().format) {
case Format10t:
writeOpcode(writer);
writer.write(' ');
writeTargetLabel(writer);
break;
case Format10x:
if (instruction instanceof UnknownInstruction) {
writer.write("#unknown opcode: 0x");
writer.printUnsignedLongAsHex(((UnknownInstruction) instruction).getOriginalOpcode());
writer.write('\n');
}
writeOpcode(writer);
break;
case Format11n:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeLiteral(writer);
break;
case Format11x:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
break;
case Format12x:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
break;
case Format20bc:
writeOpcode(writer);
writer.write(' ');
writer.write(verificationErrorName);
writer.write(", ");
writer.write(referenceString);
break;
case Format20t:
case Format30t:
writeOpcode(writer);
writer.write(' ');
writeTargetLabel(writer);
break;
case Format21c:
case Format31c:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writer.write(referenceString);
break;
case Format21ih:
case Format21lh:
case Format21s:
case Format31i:
case Format51l:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeLiteral(writer);
if (instruction.getOpcode().setsWideRegister()) {
writeCommentIfLikelyDouble(writer);
} else {
boolean isResourceId = writeCommentIfResourceId(writer);
if (!isResourceId)
writeCommentIfLikelyFloat(writer);
}
break;
case Format21t:
case Format31t:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeTargetLabel(writer);
break;
case Format22b:
case Format22s:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writeLiteral(writer);
break;
case Format22c:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writer.write(referenceString);
break;
case Format22cs:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writeFieldOffset(writer);
break;
case Format22t:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writeTargetLabel(writer);
break;
case Format22x:
case Format32x:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
break;
case Format23x:
writeOpcode(writer);
writer.write(' ');
writeFirstRegister(writer);
writer.write(", ");
writeSecondRegister(writer);
writer.write(", ");
writeThirdRegister(writer);
break;
case Format35c:
writeOpcode(writer);
writer.write(' ');
writeInvokeRegisters(writer);
writer.write(", ");
writer.write(referenceString);
break;
case Format35mi:
writeOpcode(writer);
writer.write(' ');
writeInvokeRegisters(writer);
writer.write(", ");
writeInlineIndex(writer);
break;
case Format35ms:
writeOpcode(writer);
writer.write(' ');
writeInvokeRegisters(writer);
writer.write(", ");
writeVtableIndex(writer);
break;
case Format3rc:
writeOpcode(writer);
writer.write(' ');
writeInvokeRangeRegisters(writer);
writer.write(", ");
writer.write(referenceString);
break;
case Format3rmi:
writeOpcode(writer);
writer.write(' ');
writeInvokeRangeRegisters(writer);
writer.write(", ");
writeInlineIndex(writer);
break;
case Format3rms:
writeOpcode(writer);
writer.write(' ');
writeInvokeRangeRegisters(writer);
writer.write(", ");
writeVtableIndex(writer);
break;
case Format45cc:
writeOpcode(writer);
writer.write(' ');
writeInvokeRegisters(writer);
writer.write(", ");
writer.write(referenceString);
writer.write(", ");
writer.write(referenceString2);
break;
case Format4rcc:
writeOpcode(writer);
writer.write(' ');
writeInvokeRangeRegisters(writer);
writer.write(", ");
writer.write(referenceString);
writer.write(", ");
writer.write(referenceString2);
break;
default:
assert false;
return false;
}
if (commentOutInstruction) {
writer.write("\nnop");
}
return true;
}
use of org.jf.dexlib2 in project smali by JesusFreke.
the class DexWriter method writeDebugItem.
private int writeDebugItem(@Nonnull DexDataWriter writer, @Nonnull DebugWriter<StringKey, TypeKey> debugWriter, @Nullable Iterable<? extends StringKey> parameterNames, @Nullable Iterable<? extends DebugItem> debugItems) throws IOException {
int parameterCount = 0;
int lastNamedParameterIndex = -1;
if (parameterNames != null) {
parameterCount = Iterables.size(parameterNames);
int index = 0;
for (StringKey parameterName : parameterNames) {
if (parameterName != null) {
lastNamedParameterIndex = index;
}
index++;
}
}
if (lastNamedParameterIndex == -1 && (debugItems == null || Iterables.isEmpty(debugItems))) {
return NO_OFFSET;
}
numDebugInfoItems++;
int debugItemOffset = writer.getPosition();
int startingLineNumber = 0;
if (debugItems != null) {
for (org.jf.dexlib2.iface.debug.DebugItem debugItem : debugItems) {
if (debugItem instanceof LineNumber) {
startingLineNumber = ((LineNumber) debugItem).getLineNumber();
break;
}
}
}
writer.writeUleb128(startingLineNumber);
writer.writeUleb128(parameterCount);
if (parameterNames != null) {
int index = 0;
for (StringKey parameterName : parameterNames) {
if (index == parameterCount) {
break;
}
index++;
writer.writeUleb128(stringSection.getNullableItemIndex(parameterName) + 1);
}
}
if (debugItems != null) {
debugWriter.reset(startingLineNumber);
for (DebugItem debugItem : debugItems) {
classSection.writeDebugItem(debugWriter, debugItem);
}
}
// write an END_SEQUENCE opcode, to end the debug item
writer.write(0);
return debugItemOffset;
}
use of org.jf.dexlib2 in project smali by JesusFreke.
the class DexPool method writeTo.
public static void writeTo(@Nonnull String path, @Nonnull org.jf.dexlib2.iface.DexFile input) throws IOException {
DexPool dexPool = new DexPool(input.getOpcodes());
for (ClassDef classDef : input.getClasses()) {
dexPool.internClass(classDef);
}
dexPool.writeTo(new FileDataStore(new File(path)));
}
Aggregations