Search in sources :

Example 1 with ExceptionHandler

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

the class MethodDefinition method addTries.

private void addTries(List<MethodItem> methodItems) {
    List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks = methodImpl.getTryBlocks();
    if (tryBlocks.size() == 0) {
        return;
    }
    int lastInstructionAddress = instructionOffsetMap.getInstructionCodeOffset(instructions.size() - 1);
    int codeSize = lastInstructionAddress + instructions.get(instructions.size() - 1).getCodeUnits();
    for (TryBlock<? extends ExceptionHandler> tryBlock : tryBlocks) {
        int startAddress = tryBlock.getStartCodeAddress();
        int endAddress = startAddress + tryBlock.getCodeUnitCount();
        if (startAddress >= codeSize) {
            throw new RuntimeException(String.format("Try start offset %d is past the end of the code block.", startAddress));
        }
        // Note: not >=. endAddress == codeSize is valid, when the try covers the last instruction
        if (endAddress > codeSize) {
            throw new RuntimeException(String.format("Try end offset %d is past the end of the code block.", endAddress));
        }
        /**
             * The end address points to the address immediately after the end of the last
             * instruction that the try block covers. We want the .catch directive and end_try
             * label to be associated with the last covered instruction, so we need to get
             * the address for that instruction
             */
        int lastCoveredIndex = instructionOffsetMap.getInstructionIndexAtCodeOffset(endAddress - 1, false);
        int lastCoveredAddress = instructionOffsetMap.getInstructionCodeOffset(lastCoveredIndex);
        for (ExceptionHandler handler : tryBlock.getExceptionHandlers()) {
            int handlerAddress = handler.getHandlerCodeAddress();
            if (handlerAddress >= codeSize) {
                throw new ExceptionWithContext("Exception handler offset %d is past the end of the code block.", handlerAddress);
            }
            //use the address from the last covered instruction
            CatchMethodItem catchMethodItem = new CatchMethodItem(classDef.options, labelCache, lastCoveredAddress, handler.getExceptionType(), startAddress, endAddress, handlerAddress);
            methodItems.add(catchMethodItem);
        }
    }
}
Also used : ExceptionHandler(org.jf.dexlib2.iface.ExceptionHandler) ExceptionWithContext(org.jf.util.ExceptionWithContext)

Example 2 with ExceptionHandler

use of org.jf.dexlib2.iface.ExceptionHandler 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) 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 ExceptionHandler

use of org.jf.dexlib2.iface.ExceptionHandler 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 4 with ExceptionHandler

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

the class TryListBuilderTest method testOverlap_Before_Middle.

@Test
public void testOverlap_Before_Middle() {
    TryListBuilder tlb = new TryListBuilder();
    tlb.addHandler(5, 10, new ImmutableExceptionHandler("LException1;", 5));
    tlb.addHandler(0, 7, new ImmutableExceptionHandler("LException2;", 6));
    List<? extends TryBlock<? extends ExceptionHandler>> tryBlocks = tlb.getTryBlocks();
    List<? extends TryBlock> expected = ImmutableList.of(new ImmutableTryBlock(0, 5, ImmutableList.of(new ImmutableExceptionHandler("LException2;", 6))), new ImmutableTryBlock(5, 2, ImmutableList.of(new ImmutableExceptionHandler("LException1;", 5), new ImmutableExceptionHandler("LException2;", 6))), new ImmutableTryBlock(7, 3, ImmutableList.of(new ImmutableExceptionHandler("LException1;", 5))));
    Assert.assertEquals(expected, tryBlocks);
}
Also used : ImmutableTryBlock(org.jf.dexlib2.immutable.ImmutableTryBlock) ImmutableExceptionHandler(org.jf.dexlib2.immutable.ImmutableExceptionHandler) Test(org.junit.Test)

Example 5 with ExceptionHandler

use of org.jf.dexlib2.iface.ExceptionHandler 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(), methodImpl)));
    MemoryDataStore dexStore = new MemoryDataStore();
    dexBuilder.writeTo(dexStore);
    DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dexStore.getData());
    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)

Aggregations

Test (org.junit.Test)26 ImmutableExceptionHandler (org.jf.dexlib2.immutable.ImmutableExceptionHandler)24 ImmutableTryBlock (org.jf.dexlib2.immutable.ImmutableTryBlock)24 Instruction (org.jf.dexlib2.iface.instruction.Instruction)5 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)4 ExceptionWithContext (org.jf.util.ExceptionWithContext)4 ExceptionHandler (org.jf.dexlib2.iface.ExceptionHandler)3 Opcode (org.jf.dexlib2.Opcode)2 MutableMethodImplementation (org.jf.dexlib2.builder.MutableMethodImplementation)2 MethodImplementation (org.jf.dexlib2.iface.MethodImplementation)2 OneRegisterInstruction (org.jf.dexlib2.iface.instruction.OneRegisterInstruction)2 SmaliMethod (org.jf.smalidea.psi.impl.SmaliMethod)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 BitSet (java.util.BitSet)1 Nonnull (javax.annotation.Nonnull)1 Nullable (org.jetbrains.annotations.Nullable)1 BuilderInstruction10t (org.jf.dexlib2.builder.instruction.BuilderInstruction10t)1 BuilderInstruction10x (org.jf.dexlib2.builder.instruction.BuilderInstruction10x)1 BuilderInstruction21c (org.jf.dexlib2.builder.instruction.BuilderInstruction21c)1 DexBackedDexFile (org.jf.dexlib2.dexbacked.DexBackedDexFile)1