Search in sources :

Example 1 with DebugItem

use of org.jf.dexlib2.iface.debug.DebugItem in project smali by JesusFreke.

the class SmalideaMethod method getImplementation.

@Nullable
@Override
public MethodImplementation getImplementation() {
    if (psiMethod instanceof SmaliMethod) {
        final SmaliMethod smaliMethod = (SmaliMethod) this.psiMethod;
        List<SmaliInstruction> instructions = smaliMethod.getInstructions();
        if (instructions.size() == 0) {
            return null;
        }
        // TODO: cache this?
        return new MethodImplementation() {

            @Override
            public int getRegisterCount() {
                return smaliMethod.getRegisterCount();
            }

            @Nonnull
            @Override
            public Iterable<? extends Instruction> getInstructions() {
                return Lists.transform(smaliMethod.getInstructions(), new Function<SmaliInstruction, Instruction>() {

                    @Override
                    public Instruction apply(SmaliInstruction smaliInstruction) {
                        return SmalideaInstruction.of(smaliInstruction);
                    }
                });
            }

            @Nonnull
            @Override
            public List<? extends TryBlock<? extends ExceptionHandler>> getTryBlocks() {
                return Lists.transform(smaliMethod.getCatchStatements(), new Function<SmaliCatchStatement, TryBlock<? extends ExceptionHandler>>() {

                    @Override
                    public TryBlock<? extends ExceptionHandler> apply(SmaliCatchStatement smaliCatchStatement) {
                        assert smaliCatchStatement != null;
                        return new SmalideaTryBlock(smaliCatchStatement);
                    }
                });
            }

            @Nonnull
            @Override
            public Iterable<? extends DebugItem> getDebugItems() {
                // TODO: implement this
                return ImmutableList.of();
            }
        };
    }
    return null;
}
Also used : SmaliMethod(org.jf.smalidea.psi.impl.SmaliMethod) SmaliCatchStatement(org.jf.smalidea.psi.impl.SmaliCatchStatement) SmaliInstruction(org.jf.smalidea.psi.impl.SmaliInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) SmaliInstruction(org.jf.smalidea.psi.impl.SmaliInstruction) SmalideaInstruction(org.jf.smalidea.dexlib.instruction.SmalideaInstruction) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with DebugItem

use of org.jf.dexlib2.iface.debug.DebugItem in project smali by JesusFreke.

the class DexWriter method writeDebugAndCodeItems.

private void writeDebugAndCodeItems(@Nonnull DexDataWriter offsetWriter, @Nonnull DeferredOutputStream temp) throws IOException {
    ByteArrayOutputStream ehBuf = new ByteArrayOutputStream();
    debugSectionOffset = offsetWriter.getPosition();
    DebugWriter<StringKey, TypeKey> debugWriter = new DebugWriter<StringKey, TypeKey>(stringSection, typeSection, offsetWriter);
    DexDataWriter codeWriter = new DexDataWriter(temp, 0);
    List<CodeItemOffset<MethodKey>> codeOffsets = Lists.newArrayList();
    for (ClassKey classKey : classSection.getSortedClasses()) {
        Collection<? extends MethodKey> directMethods = classSection.getSortedDirectMethods(classKey);
        Collection<? extends MethodKey> virtualMethods = classSection.getSortedVirtualMethods(classKey);
        Iterable<MethodKey> methods = Iterables.concat(directMethods, virtualMethods);
        for (MethodKey methodKey : methods) {
            List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks = classSection.getTryBlocks(methodKey);
            Iterable<? extends Instruction> instructions = classSection.getInstructions(methodKey);
            Iterable<? extends DebugItem> debugItems = classSection.getDebugItems(methodKey);
            if (instructions != null && stringSection.hasJumboIndexes()) {
                boolean needsFix = false;
                for (Instruction instruction : instructions) {
                    if (instruction.getOpcode() == Opcode.CONST_STRING) {
                        if (stringSection.getItemIndex((StringRef) ((ReferenceInstruction) instruction).getReference()) >= 65536) {
                            needsFix = true;
                            break;
                        }
                    }
                }
                if (needsFix) {
                    MutableMethodImplementation mutableMethodImplementation = classSection.makeMutableMethodImplementation(methodKey);
                    fixInstructions(mutableMethodImplementation);
                    instructions = mutableMethodImplementation.getInstructions();
                    tryBlocks = mutableMethodImplementation.getTryBlocks();
                    debugItems = mutableMethodImplementation.getDebugItems();
                }
            }
            int debugItemOffset = writeDebugItem(offsetWriter, debugWriter, classSection.getParameterNames(methodKey), debugItems);
            int codeItemOffset;
            try {
                codeItemOffset = writeCodeItem(codeWriter, ehBuf, methodKey, tryBlocks, instructions, debugItemOffset);
            } catch (RuntimeException ex) {
                throw new ExceptionWithContext(ex, "Exception occurred while writing code_item for method %s", methodSection.getMethodReference(methodKey));
            }
            if (codeItemOffset != -1) {
                codeOffsets.add(new CodeItemOffset<MethodKey>(methodKey, codeItemOffset));
            }
        }
    }
    offsetWriter.align();
    codeSectionOffset = offsetWriter.getPosition();
    codeWriter.close();
    temp.writeTo(offsetWriter);
    temp.close();
    for (CodeItemOffset<MethodKey> codeOffset : codeOffsets) {
        classSection.setCodeItemOffset(codeOffset.method, codeSectionOffset + codeOffset.codeOffset);
    }
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) OneRegisterInstruction(org.jf.dexlib2.iface.instruction.OneRegisterInstruction) VariableRegisterInstruction(org.jf.dexlib2.iface.instruction.VariableRegisterInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) ExceptionWithContext(org.jf.util.ExceptionWithContext) MutableMethodImplementation(org.jf.dexlib2.builder.MutableMethodImplementation)

Example 3 with DebugItem

use of org.jf.dexlib2.iface.debug.DebugItem in project smali by JesusFreke.

the class FixOffsetsTest method testFixOffsets.

@Test
public void testFixOffsets() {
    MethodImplementationBuilder builder = new MethodImplementationBuilder(1);
    Label firstGotoTarget = builder.getLabel("firstGotoTarget");
    builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, firstGotoTarget));
    builder.addLineNumber(1);
    for (int i = 0; i < 250; i++) {
        builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
    }
    builder.addLabel("tryStart");
    builder.addLineNumber(2);
    for (int i = 0; i < 250; i++) {
        builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
    }
    builder.addLineNumber(3);
    Label secondGotoTarget = builder.getLabel("secondGotoTarget");
    builder.addInstruction(new BuilderInstruction10t(Opcode.GOTO, secondGotoTarget));
    builder.addLineNumber(4);
    builder.addLabel("handler");
    for (int i = 0; i < 500; i++) {
        builder.addInstruction(new BuilderInstruction10x(Opcode.NOP));
    }
    builder.addLineNumber(5);
    builder.addLabel("tryEnd");
    builder.addLabel("firstGotoTarget");
    builder.addLabel("secondGotoTarget");
    builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
    Label tryStart = builder.getLabel("tryStart");
    Label tryEnd = builder.getLabel("tryEnd");
    Label handler = builder.getLabel("handler");
    builder.addCatch(tryStart, tryEnd, handler);
    MethodImplementation impl = builder.getMethodImplementation();
    List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions());
    Assert.assertEquals(1003, instructions.size());
    Assert.assertEquals(Opcode.GOTO_16, instructions.get(0).getOpcode());
    Assert.assertEquals(1004, ((OffsetInstruction) instructions.get(0)).getCodeOffset());
    Assert.assertEquals(Opcode.GOTO_16, instructions.get(501).getOpcode());
    Assert.assertEquals(502, ((OffsetInstruction) instructions.get(501)).getCodeOffset());
    List<? extends TryBlock<? extends ExceptionHandler>> exceptionHandlers = impl.getTryBlocks();
    Assert.assertEquals(1, exceptionHandlers.size());
    Assert.assertEquals(252, exceptionHandlers.get(0).getStartCodeAddress());
    Assert.assertEquals(752, exceptionHandlers.get(0).getCodeUnitCount());
    Assert.assertEquals(1, exceptionHandlers.get(0).getExceptionHandlers().size());
    ExceptionHandler exceptionHandler = exceptionHandlers.get(0).getExceptionHandlers().get(0);
    Assert.assertEquals(504, exceptionHandler.getHandlerCodeAddress());
    List<DebugItem> debugItems = Lists.newArrayList(impl.getDebugItems());
    Assert.assertEquals(5, debugItems.size());
    Assert.assertEquals(1, ((LineNumber) debugItems.get(0)).getLineNumber());
    Assert.assertEquals(2, debugItems.get(0).getCodeAddress());
    Assert.assertEquals(2, ((LineNumber) debugItems.get(1)).getLineNumber());
    Assert.assertEquals(252, debugItems.get(1).getCodeAddress());
    Assert.assertEquals(3, ((LineNumber) debugItems.get(2)).getLineNumber());
    Assert.assertEquals(502, debugItems.get(2).getCodeAddress());
    Assert.assertEquals(4, ((LineNumber) debugItems.get(3)).getLineNumber());
    Assert.assertEquals(504, debugItems.get(3).getCodeAddress());
    Assert.assertEquals(5, ((LineNumber) debugItems.get(4)).getLineNumber());
    Assert.assertEquals(1004, debugItems.get(4).getCodeAddress());
}
Also used : MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) ExceptionHandler(org.jf.dexlib2.iface.ExceptionHandler) BuilderInstruction10x(org.jf.dexlib2.builder.instruction.BuilderInstruction10x) BuilderInstruction10t(org.jf.dexlib2.builder.instruction.BuilderInstruction10t) DebugItem(org.jf.dexlib2.iface.debug.DebugItem) Test(org.junit.Test)

Example 4 with DebugItem

use of org.jf.dexlib2.iface.debug.DebugItem in project smali by JesusFreke.

the class JumboStringConversionTest method testJumboStringConversion_NonMethodBuilder.

@Test
public void testJumboStringConversion_NonMethodBuilder() throws IOException {
    DexBuilder dexBuilder = new DexBuilder(Opcodes.getDefault());
    final List<Instruction> instructions = Lists.newArrayList();
    for (int i = 0; i < 66000; i++) {
        final StringReference ref = dexBuilder.internStringReference(String.format("%08d", i));
        instructions.add(new Instruction21c() {

            @Override
            public int getRegisterA() {
                return 0;
            }

            @Nonnull
            @Override
            public Reference getReference() {
                return ref;
            }

            @Override
            public int getReferenceType() {
                return ReferenceType.STRING;
            }

            @Override
            public Opcode getOpcode() {
                return Opcode.CONST_STRING;
            }

            @Override
            public int getCodeUnits() {
                return getOpcode().format.size / 2;
            }
        });
    }
    instructions.add(new ImmutableInstruction10x(Opcode.RETURN_VOID));
    MethodImplementation methodImpl = new MethodImplementation() {

        @Override
        public int getRegisterCount() {
            return 1;
        }

        @Nonnull
        @Override
        public Iterable<? extends Instruction> getInstructions() {
            return instructions;
        }

        @Nonnull
        @Override
        public List<? extends TryBlock<? extends ExceptionHandler>> getTryBlocks() {
            return ImmutableList.of();
        }

        @Nonnull
        @Override
        public Iterable<? extends DebugItem> getDebugItems() {
            return ImmutableList.of();
        }
    };
    dexBuilder.internClassDef("Ltest;", 0, "Ljava/lang/Object;", null, null, ImmutableSet.<Annotation>of(), null, ImmutableList.of(dexBuilder.internMethod("Ltest;", "test", null, "V", 0, ImmutableSet.<Annotation>of(), ImmutableSet.of(), methodImpl)));
    MemoryDataStore dexStore = new MemoryDataStore();
    dexBuilder.writeTo(dexStore);
    DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dexStore.getBuffer());
    ClassDef classDef = Iterables.getFirst(dexFile.getClasses(), null);
    Assert.assertNotNull(classDef);
    Method method = Iterables.getFirst(classDef.getMethods(), null);
    Assert.assertNotNull(method);
    MethodImplementation impl = method.getImplementation();
    Assert.assertNotNull(impl);
    List<? extends Instruction> actualInstructions = Lists.newArrayList(impl.getInstructions());
    Assert.assertEquals(66001, actualInstructions.size());
    for (int i = 0; i < 65536; i++) {
        Assert.assertEquals(Opcode.CONST_STRING, actualInstructions.get(i).getOpcode());
        Assert.assertEquals(String.format("%08d", i), ((StringReference) ((ReferenceInstruction) actualInstructions.get(i)).getReference()).getString());
    }
    for (int i = 65536; i < 66000; i++) {
        Assert.assertEquals(Opcode.CONST_STRING_JUMBO, actualInstructions.get(i).getOpcode());
        Assert.assertEquals(String.format("%08d", i), ((StringReference) ((ReferenceInstruction) actualInstructions.get(i)).getReference()).getString());
    }
    Assert.assertEquals(Opcode.RETURN_VOID, actualInstructions.get(66000).getOpcode());
}
Also used : BuilderInstruction21c(org.jf.dexlib2.builder.instruction.BuilderInstruction21c) Instruction21c(org.jf.dexlib2.iface.instruction.formats.Instruction21c) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) Nonnull(javax.annotation.Nonnull) Reference(org.jf.dexlib2.iface.reference.Reference) StringReference(org.jf.dexlib2.iface.reference.StringReference) MemoryDataStore(org.jf.dexlib2.writer.io.MemoryDataStore) Opcode(org.jf.dexlib2.Opcode) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) StringReference(org.jf.dexlib2.iface.reference.StringReference) ImmutableInstruction10x(org.jf.dexlib2.immutable.instruction.ImmutableInstruction10x) DexBuilder(org.jf.dexlib2.writer.builder.DexBuilder) Test(org.junit.Test)

Example 5 with DebugItem

use of org.jf.dexlib2.iface.debug.DebugItem in project atlas by alibaba.

the class InsTructionsReIClassDef method reDebugItem.

@Override
protected Iterable<? extends DebugItem> reDebugItem(Iterable<? extends DebugItem> debugItems) {
    if (debugItems == null) {
        return null;
    }
    Iterator iterator = debugItems.iterator();
    final List<DebugItem> immableDebugItems = new ArrayList<DebugItem>();
    while (iterator.hasNext()) {
        DebugItem debugItem = (DebugItem) iterator.next();
        if (debugItem instanceof ImmutableStartLocal) {
            String newType = null;
            String type = ((ImmutableStartLocal) debugItem).getType();
            if (!basicType.containsKey(type)) {
                newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className, type.startsWith("["));
            } else
                newType = type;
            immableDebugItems.add(new ImmutableStartLocal(debugItem.getCodeAddress(), ((ImmutableStartLocal) debugItem).getRegister(), ((ImmutableStartLocal) debugItem).getName(), newType, ((ImmutableStartLocal) debugItem).getSignature()));
        } else if (debugItem instanceof ImmutableEndLocal) {
            String newType = null;
            String type = ((ImmutableEndLocal) debugItem).getType();
            if (!basicType.containsKey(type)) {
                newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className, type.startsWith("["));
            } else
                newType = type;
            immableDebugItems.add(new ImmutableEndLocal(debugItem.getCodeAddress(), ((ImmutableEndLocal) debugItem).getRegister(), ((ImmutableEndLocal) debugItem).getName(), newType, ((ImmutableEndLocal) debugItem).getSignature()));
        } else if (debugItem instanceof ImmutableRestartLocal) {
            String newType = null;
            String type = ((ImmutableRestartLocal) debugItem).getType();
            if (!basicType.containsKey(type)) {
                newType = DefineUtils.getDefineClassName(classProcessor.classProcess(DefineUtils.getDalvikClassName(type)).className, type.startsWith("["));
            } else
                newType = type;
            immableDebugItems.add(new ImmutableRestartLocal(debugItem.getCodeAddress(), ((ImmutableRestartLocal) debugItem).getRegister(), ((ImmutableRestartLocal) debugItem).getName(), newType, ((ImmutableRestartLocal) debugItem).getSignature()));
        } else
            immableDebugItems.add(debugItem);
    }
    return new Iterable<DebugItem>() {

        @Override
        public Iterator<DebugItem> iterator() {
            return immableDebugItems.iterator();
        }
    };
}
Also used : ImmutableStartLocal(org.jf.dexlib2.immutable.debug.ImmutableStartLocal) ImmutableRestartLocal(org.jf.dexlib2.immutable.debug.ImmutableRestartLocal) ImmutableEndLocal(org.jf.dexlib2.immutable.debug.ImmutableEndLocal) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) DebugItem(org.jf.dexlib2.iface.debug.DebugItem)

Aggregations

DebugItem (org.jf.dexlib2.iface.debug.DebugItem)3 Instruction (org.jf.dexlib2.iface.instruction.Instruction)3 Test (org.junit.Test)3 MutableMethodImplementation (org.jf.dexlib2.builder.MutableMethodImplementation)2 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)2 Instruction21c (org.jf.dexlib2.iface.instruction.formats.Instruction21c)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 StringWriter (java.io.StringWriter)1 ArrayList (java.util.ArrayList)1 Iterator (java.util.Iterator)1 Nonnull (javax.annotation.Nonnull)1 Nullable (org.jetbrains.annotations.Nullable)1 ClassDefinition (org.jf.baksmali.Adaptors.ClassDefinition)1 InstructionMethodItem (org.jf.baksmali.Adaptors.Format.InstructionMethodItem)1 MethodDefinition (org.jf.baksmali.Adaptors.MethodDefinition)1 RegisterFormatter (org.jf.baksmali.Adaptors.RegisterFormatter)1 BaksmaliWriter (org.jf.baksmali.formatter.BaksmaliWriter)1 org.jf.dexlib2 (org.jf.dexlib2)1 Opcode (org.jf.dexlib2.Opcode)1 BaseStringReference (org.jf.dexlib2.base.reference.BaseStringReference)1