use of org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember in project atlas by alibaba.
the class MethodDefinition method addInstructionMethodItems.
private void addInstructionMethodItems(List<MethodItem> methodItems) {
int currentCodeAddress = 0;
for (int i = 0; i < effectiveInstructions.size(); i++) {
Instruction instruction = effectiveInstructions.get(i);
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction);
methodItems.add(methodItem);
if (i != effectiveInstructions.size() - 1) {
methodItems.add(new BlankMethodItem(currentCodeAddress));
}
if (classDef.options.codeOffsets) {
methodItems.add(new MethodItem(currentCodeAddress) {
@Override
public double getSortOrder() {
return -1000;
}
@Override
public boolean writeTo(IndentingWriter writer) throws IOException {
writer.write("#@");
writer.printUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
return true;
}
});
}
if (!classDef.options.accessorComments && (instruction instanceof ReferenceInstruction)) {
Opcode opcode = instruction.getOpcode();
if (opcode.referenceType == ReferenceType.METHOD) {
MethodReference methodReference = null;
try {
methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();
} catch (InvalidItemIndex ex) {
// just ignore it for now. We'll deal with it later, when processing the instructions
// themselves
}
if (methodReference != null && SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
AccessedMember accessedMember = classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
if (accessedMember != null) {
methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
}
}
}
}
currentCodeAddress += instruction.getCodeUnits();
}
}
use of org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember in project smali by JesusFreke.
the class MethodDefinition method addInstructionMethodItems.
private void addInstructionMethodItems(List<MethodItem> methodItems) {
int currentCodeAddress = 0;
for (int i = 0; i < effectiveInstructions.size(); i++) {
Instruction instruction = effectiveInstructions.get(i);
MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction);
methodItems.add(methodItem);
if (i != effectiveInstructions.size() - 1) {
methodItems.add(new BlankMethodItem(currentCodeAddress));
}
if (classDef.options.codeOffsets) {
methodItems.add(new MethodItem(currentCodeAddress) {
@Override
public double getSortOrder() {
return -1000;
}
@Override
public boolean writeTo(BaksmaliWriter writer) throws IOException {
writer.write("#@");
writer.writeUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
return true;
}
});
}
if (classDef.options.accessorComments && classDef.options.syntheticAccessorResolver != null && (instruction instanceof ReferenceInstruction)) {
Opcode opcode = instruction.getOpcode();
if (opcode.referenceType == ReferenceType.METHOD) {
MethodReference methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();
try {
methodReference.validateReference();
if (SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
AccessedMember accessedMember = classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
if (accessedMember != null) {
methodItems.add(new SyntheticAccessCommentMethodItem(classDef, accessedMember, currentCodeAddress));
}
}
} catch (Reference.InvalidReferenceException e) {
// Just ignore for now. We'll deal with it when processing the instruction
}
}
}
currentCodeAddress += instruction.getCodeUnits();
}
}
use of org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember in project smali by JesusFreke.
the class SyntheticAccessorResolver method getAccessedMember.
@Nullable
public AccessedMember getAccessedMember(@Nonnull MethodReference methodReference) {
AccessedMember accessedMember = resolvedAccessors.get(methodReference);
if (accessedMember != null) {
return accessedMember;
}
String type = methodReference.getDefiningClass();
ClassDef classDef = classDefMap.get(type);
if (classDef == null) {
return null;
}
Method matchedMethod = null;
MethodImplementation matchedMethodImpl = null;
for (Method method : classDef.getMethods()) {
MethodImplementation methodImpl = method.getImplementation();
if (methodImpl != null) {
if (methodReferenceEquals(method, methodReference)) {
matchedMethod = method;
matchedMethodImpl = methodImpl;
break;
}
}
}
if (matchedMethod == null) {
return null;
}
// A synthetic accessor will be marked synthetic
if (!AccessFlags.SYNTHETIC.isSet(matchedMethod.getAccessFlags())) {
return null;
}
List<Instruction> instructions = ImmutableList.copyOf(matchedMethodImpl.getInstructions());
int accessType = syntheticAccessorFSM.test(instructions);
if (accessType >= 0) {
AccessedMember member = new AccessedMember(accessType, ((ReferenceInstruction) instructions.get(0)).getReference());
resolvedAccessors.put(methodReference, member);
return member;
}
return null;
}
use of org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember in project smali by JesusFreke.
the class AccessorTest method testAccessors.
@Test
public void testAccessors() throws IOException {
URL url = AccessorTest.class.getClassLoader().getResource("accessorTest.dex");
Assert.assertNotNull(url);
DexFile f = DexFileFactory.loadDexFile(url.getFile(), Opcodes.getDefault());
SyntheticAccessorResolver sar = new SyntheticAccessorResolver(f.getOpcodes(), f.getClasses());
ClassDef accessorTypesClass = null;
ClassDef accessorsClass = null;
for (ClassDef classDef : f.getClasses()) {
String className = classDef.getType();
if (className.equals("Lorg/jf/dexlib2/AccessorTypes;")) {
accessorTypesClass = classDef;
} else if (className.equals("Lorg/jf/dexlib2/AccessorTypes$Accessors;")) {
accessorsClass = classDef;
}
}
Assert.assertNotNull(accessorTypesClass);
Assert.assertNotNull(accessorsClass);
for (Method method : accessorsClass.getMethods()) {
Matcher m = accessorMethodPattern.matcher(method.getName());
if (!m.matches()) {
continue;
}
String type = m.group(1);
String operation = m.group(2);
MethodImplementation methodImpl = method.getImplementation();
Assert.assertNotNull(methodImpl);
for (Instruction instruction : methodImpl.getInstructions()) {
Opcode opcode = instruction.getOpcode();
if (opcode == Opcode.INVOKE_STATIC || opcode == Opcode.INVOKE_STATIC_RANGE) {
MethodReference accessorMethod = (MethodReference) ((ReferenceInstruction) instruction).getReference();
SyntheticAccessorResolver.AccessedMember accessedMember = sar.getAccessedMember(accessorMethod);
Assert.assertNotNull(String.format("Could not resolve accessor for %s_%s", type, operation), accessedMember);
int operationType = operationTypes.get(operation);
Assert.assertEquals(operationType, accessedMember.accessedMemberType);
Assert.assertEquals(String.format("%s_val", type), ((FieldReference) accessedMember.accessedMember).getName());
}
}
}
}
Aggregations