Search in sources :

Example 6 with StringReference

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

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

the class SmalideaMethodTest method testSmalideaMethod.

public void testSmalideaMethod() {
    String text = ".class public Lmy/pkg/blah; .super Ljava/lang/Object;\n" + ".method public someMethodName(I)I\n" + "    .registers 4\n" + "    .param p1, \"edge\"    # I\n" + "    goto :here  #0: 10t\n" + "    :here\n" + "    return-void  #1: 21c\n" + "    const/4 v0, 1234 #2: 11n\n" + "    monitor-enter v1, #3: 11x\n" + "    move v1, v0 #4: 12x\n" + "    goto/16 :here #5: 20t\n" + "    sget v0, La/b/c;->blah:I #6: 21c\n" + "    const/high16 v0, 0x12340000 #7: 21ih\n" + "    const-wide/high16 v0, 0x1234000000000000L #8: 21lh\n" + "    const-wide/16 v0, 1234 #9: 21s\n" + "    if-eqz v0, :here #10: 21t\n" + "    add-int/lit8 v0, v1, 123 #11: 22b\n" + "    iget v1, v2, Labc;->blort:Z #12: 22c\n" + "    add-int/lit16 v0, v1, 1234 #13: 22s\n" + "    if-eq v0, v1, :here #14: 22t\n" + "    move/from16 v0, v1 #15: 22x\n" + "    cmpl-float v0, v1, v2 #16: 23x\n" + "    goto/32 :here #17: 30t\n" + "    const-string/jumbo v0, \"abcd\" #18: 31c\n" + "    const v0, 1234 #19: 31i\n" + "    move/16 v0, v1 #20: 32x\n" + "    invoke-virtual {v0, v1, v2, v3, v4}, Lblah;->blort(IIII)I #21: 35c\n" + "    invoke-virtual/range {v0..v4}, Lblah;->blort(IIII)I #22: 3rc\n" + "    const-wide v0, 0x1234567890L #23: 51i\n" + ".end method";
    SmaliFile file = (SmaliFile) myFixture.addFileToProject("my/pkg/blah.smali", text);
    SmaliClass smaliClass = file.getPsiClass();
    SmaliMethod smaliMethod = smaliClass.getMethods()[0];
    SmalideaMethod method = new SmalideaMethod(smaliMethod);
    Assert.assertEquals("Lmy/pkg/blah;", method.getDefiningClass());
    Assert.assertEquals("someMethodName", method.getName());
    Assert.assertEquals("I", method.getReturnType());
    List<? extends CharSequence> parameterTypes = method.getParameterTypes();
    Assert.assertEquals(1, parameterTypes.size());
    Assert.assertEquals("I", parameterTypes.get(0));
    List<? extends MethodParameter> parameters = method.getParameters();
    Assert.assertEquals(1, parameters.size());
    Assert.assertEquals("I", parameters.get(0).getType());
    Assert.assertEquals("edge", parameters.get(0).getName());
    Assert.assertEquals(AccessFlags.PUBLIC.getValue(), method.getAccessFlags());
    MethodImplementation impl = method.getImplementation();
    Assert.assertNotNull(impl);
    Assert.assertEquals(4, impl.getRegisterCount());
    List<? extends Instruction> instructions = Lists.newArrayList(impl.getInstructions());
    {
        Instruction10t instruction = (Instruction10t) instructions.get(0);
        Assert.assertEquals(Opcode.GOTO, instruction.getOpcode());
        Assert.assertEquals(1, instruction.getCodeOffset());
    }
    {
        Instruction10x instruction = (Instruction10x) instructions.get(1);
        Assert.assertEquals(Opcode.RETURN_VOID, instruction.getOpcode());
    }
    {
        Instruction11n instruction = (Instruction11n) instructions.get(2);
        Assert.assertEquals(Opcode.CONST_4, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(1234, instruction.getNarrowLiteral());
    }
    {
        Instruction11x instruction = (Instruction11x) instructions.get(3);
        Assert.assertEquals(Opcode.MONITOR_ENTER, instruction.getOpcode());
        Assert.assertEquals(1, instruction.getRegisterA());
    }
    {
        Instruction12x instruction = (Instruction12x) instructions.get(4);
        Assert.assertEquals(Opcode.MOVE, instruction.getOpcode());
        Assert.assertEquals(1, instruction.getRegisterA());
        Assert.assertEquals(0, instruction.getRegisterB());
    }
    {
        Instruction20t instruction = (Instruction20t) instructions.get(5);
        Assert.assertEquals(Opcode.GOTO_16, instruction.getOpcode());
        Assert.assertEquals(-4, instruction.getCodeOffset());
    }
    {
        Instruction21c instruction = (Instruction21c) instructions.get(6);
        Assert.assertEquals(Opcode.SGET, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals("La/b/c;->blah:I", ReferenceUtil.getFieldDescriptor((FieldReference) instruction.getReference()));
    }
    {
        Instruction21ih instruction = (Instruction21ih) instructions.get(7);
        Assert.assertEquals(Opcode.CONST_HIGH16, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(0x1234, instruction.getHatLiteral());
        Assert.assertEquals(0x12340000, instruction.getNarrowLiteral());
        Assert.assertEquals(0x12340000, instruction.getWideLiteral());
    }
    {
        Instruction21lh instruction = (Instruction21lh) instructions.get(8);
        Assert.assertEquals(Opcode.CONST_WIDE_HIGH16, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(0x1234, instruction.getHatLiteral());
        Assert.assertEquals(0x1234000000000000L, instruction.getWideLiteral());
    }
    {
        Instruction21s instruction = (Instruction21s) instructions.get(9);
        Assert.assertEquals(Opcode.CONST_WIDE_16, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(1234, instruction.getWideLiteral());
    }
    {
        Instruction21t instruction = (Instruction21t) instructions.get(10);
        Assert.assertEquals(Opcode.IF_EQZ, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(-14, instruction.getCodeOffset());
    }
    {
        Instruction22b instruction = (Instruction22b) instructions.get(11);
        Assert.assertEquals(Opcode.ADD_INT_LIT8, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(1, instruction.getRegisterB());
        Assert.assertEquals(123, instruction.getNarrowLiteral());
    }
    {
        Instruction22c instruction = (Instruction22c) instructions.get(12);
        Assert.assertEquals(Opcode.IGET, instruction.getOpcode());
        Assert.assertEquals(1, instruction.getRegisterA());
        Assert.assertEquals(2, instruction.getRegisterB());
        Assert.assertEquals("Labc;->blort:Z", ReferenceUtil.getFieldDescriptor((FieldReference) instruction.getReference()));
    }
    {
        Instruction22s instruction = (Instruction22s) instructions.get(13);
        Assert.assertEquals(Opcode.ADD_INT_LIT16, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(1, instruction.getRegisterB());
        Assert.assertEquals(1234, instruction.getNarrowLiteral());
    }
    {
        Instruction22t instruction = (Instruction22t) instructions.get(14);
        Assert.assertEquals(Opcode.IF_EQ, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(1, instruction.getRegisterB());
        Assert.assertEquals(-22, instruction.getCodeOffset());
    }
    {
        Instruction22x instruction = (Instruction22x) instructions.get(15);
        Assert.assertEquals(Opcode.MOVE_FROM16, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(1, instruction.getRegisterB());
    }
    {
        Instruction23x instruction = (Instruction23x) instructions.get(16);
        Assert.assertEquals(Opcode.CMPL_FLOAT, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(1, instruction.getRegisterB());
        Assert.assertEquals(2, instruction.getRegisterC());
    }
    {
        Instruction30t instruction = (Instruction30t) instructions.get(17);
        Assert.assertEquals(Opcode.GOTO_32, instruction.getOpcode());
        Assert.assertEquals(-28, instruction.getCodeOffset());
    }
    {
        Instruction31c instruction = (Instruction31c) instructions.get(18);
        Assert.assertEquals(Opcode.CONST_STRING_JUMBO, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals("abcd", ((StringReference) instruction.getReference()).getString());
    }
    {
        Instruction31i instruction = (Instruction31i) instructions.get(19);
        Assert.assertEquals(Opcode.CONST, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(1234, instruction.getNarrowLiteral());
    }
    {
        Instruction32x instruction = (Instruction32x) instructions.get(20);
        Assert.assertEquals(Opcode.MOVE_16, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(1, instruction.getRegisterB());
    }
    {
        Instruction35c instruction = (Instruction35c) instructions.get(21);
        Assert.assertEquals(Opcode.INVOKE_VIRTUAL, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterC());
        Assert.assertEquals(1, instruction.getRegisterD());
        Assert.assertEquals(2, instruction.getRegisterE());
        Assert.assertEquals(3, instruction.getRegisterF());
        Assert.assertEquals(4, instruction.getRegisterG());
        Assert.assertEquals("Lblah;->blort(IIII)I", ReferenceUtil.getReferenceString(instruction.getReference()));
    }
    {
        Instruction3rc instruction = (Instruction3rc) instructions.get(22);
        Assert.assertEquals(Opcode.INVOKE_VIRTUAL_RANGE, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getStartRegister());
        Assert.assertEquals(5, instruction.getRegisterCount());
        Assert.assertEquals("Lblah;->blort(IIII)I", ReferenceUtil.getReferenceString(instruction.getReference()));
    }
    {
        Instruction51l instruction = (Instruction51l) instructions.get(23);
        Assert.assertEquals(Opcode.CONST_WIDE, instruction.getOpcode());
        Assert.assertEquals(0, instruction.getRegisterA());
        Assert.assertEquals(0x1234567890L, instruction.getWideLiteral());
    }
}
Also used : SmaliFile(org.jf.smalidea.psi.impl.SmaliFile) MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) SmaliClass(org.jf.smalidea.psi.impl.SmaliClass) SmaliMethod(org.jf.smalidea.psi.impl.SmaliMethod) StringReference(org.jf.dexlib2.iface.reference.StringReference)

Example 8 with StringReference

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

the class ClassPool method internCode.

private void internCode(@Nonnull Method method) {
    // this also handles parameter names, which aren't directly tied to the MethodImplementation, even though the debug items are
    boolean hasInstruction = false;
    MethodImplementation methodImpl = method.getImplementation();
    if (methodImpl != null) {
        for (Instruction instruction : methodImpl.getInstructions()) {
            hasInstruction = true;
            if (instruction instanceof ReferenceInstruction) {
                Reference reference = ((ReferenceInstruction) instruction).getReference();
                switch(instruction.getOpcode().referenceType) {
                    case ReferenceType.STRING:
                        dexPool.stringSection.intern((StringReference) reference);
                        break;
                    case ReferenceType.TYPE:
                        dexPool.typeSection.intern(((TypeReference) reference).getType());
                        break;
                    case ReferenceType.FIELD:
                        dexPool.fieldSection.intern((FieldReference) reference);
                        break;
                    case ReferenceType.METHOD:
                        dexPool.methodSection.intern((MethodReference) reference);
                        break;
                    case ReferenceType.CALL_SITE:
                        dexPool.callSiteSection.intern((CallSiteReference) reference);
                        break;
                    default:
                        throw new ExceptionWithContext("Unrecognized reference type: %d", instruction.getOpcode().referenceType);
                }
            }
        }
        List<? extends TryBlock> tryBlocks = methodImpl.getTryBlocks();
        if (!hasInstruction && tryBlocks.size() > 0) {
            throw new ExceptionWithContext("Method %s has no instructions, but has try blocks.", method);
        }
        for (TryBlock<? extends ExceptionHandler> tryBlock : methodImpl.getTryBlocks()) {
            for (ExceptionHandler handler : tryBlock.getExceptionHandlers()) {
                dexPool.typeSection.internNullable(handler.getExceptionType());
            }
        }
    }
}
Also used : MutableMethodImplementation(org.jf.dexlib2.builder.MutableMethodImplementation) ExceptionWithContext(org.jf.util.ExceptionWithContext) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction)

Example 9 with StringReference

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

the class ReferenceUtil method getReferenceString.

@Nullable
public static String getReferenceString(@Nonnull Reference reference, @Nullable String containingClass) {
    if (reference instanceof StringReference) {
        return String.format("\"%s\"", StringUtils.escapeString(((StringReference) reference).getString()));
    }
    if (reference instanceof TypeReference) {
        // TypeGenUtil.newType(((TypeReference)reference).getType());
        String clazz = ((TypeReference) reference).getType();
        return clazz;
    }
    if (reference instanceof FieldReference) {
        FieldReference fieldReference = (FieldReference) reference;
        boolean useImplicitReference = fieldReference.getDefiningClass().equals(containingClass);
        return getFieldDescriptor((FieldReference) reference, useImplicitReference);
    }
    if (reference instanceof MethodReference) {
        MethodReference methodReference = (MethodReference) reference;
        boolean useImplicitReference = methodReference.getDefiningClass().equals(containingClass);
        return getMethodDescriptor((MethodReference) reference, useImplicitReference);
    }
    return null;
}
Also used : FieldReference(org.jf.dexlib2.iface.reference.FieldReference) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) TypeReference(org.jf.dexlib2.iface.reference.TypeReference) StringReference(org.jf.dexlib2.iface.reference.StringReference) Nullable(javax.annotation.Nullable)

Aggregations

StringReference (org.jf.dexlib2.iface.reference.StringReference)7 ReferenceInstruction (org.jf.dexlib2.iface.instruction.ReferenceInstruction)4 Instruction (org.jf.dexlib2.iface.instruction.Instruction)3 ImmutableStringReference (org.jf.dexlib2.immutable.reference.ImmutableStringReference)3 Opcode (org.jf.dexlib2.Opcode)2 BuilderInstruction21c (org.jf.dexlib2.builder.instruction.BuilderInstruction21c)2 DexBackedDexFile (org.jf.dexlib2.dexbacked.DexBackedDexFile)2 Instruction21c (org.jf.dexlib2.iface.instruction.formats.Instruction21c)2 FieldReference (org.jf.dexlib2.iface.reference.FieldReference)2 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)2 TypeReference (org.jf.dexlib2.iface.reference.TypeReference)2 ImmutableTypeReference (org.jf.dexlib2.immutable.reference.ImmutableTypeReference)2 DexBuilder (org.jf.dexlib2.writer.builder.DexBuilder)2 MemoryDataStore (org.jf.dexlib2.writer.io.MemoryDataStore)2 Test (org.junit.Test)2 ArrayList (java.util.ArrayList)1 Nonnull (javax.annotation.Nonnull)1 Nullable (javax.annotation.Nullable)1 MethodImplementationBuilder (org.jf.dexlib2.builder.MethodImplementationBuilder)1 MutableMethodImplementation (org.jf.dexlib2.builder.MutableMethodImplementation)1