ThexXTURBOXx / dex2jar

Tools to work with android .dex and java .class files
Apache License 2.0
234 stars 59 forks source link

Come and have a look #28

Closed Saint-Theana closed 2 years ago

Saint-Theana commented 2 years ago

At file dex-translator/src/main/java/com/googlecode/d2j/converter/J2IRConverter.java line 562: case T_DOUBLE: return b(1, Exprs.nNewArray("D", local)); case T_LONG: return b(1, Exprs.nNewArray("D", local));

Saint-Theana commented 2 years ago

this code caused a very strange problem,and I spent some hours to solve that,I wonder no one else is using j2ir?

ThexXTURBOXx commented 2 years ago

Hello, if you change

case T_LONG:
return b(1, Exprs.nNewArray("D", local));

to

case T_LONG:
return b(1, Exprs.nNewArray("L", local));

does it work for you?

Saint-Theana commented 2 years ago

Hello, if you change

case T_LONG:
return b(1, Exprs.nNewArray("D", local));

to

case T_LONG:
return b(1, Exprs.nNewArray("L", local));

does it work for you?

Type long in jvm bytecode is "J",not "L". "L" stands for Object like "Ljava/lang/String;"

ThexXTURBOXx commented 2 years ago

Ah yes, of course. Was in a bit of a hurry when I wrote that. Did everything work fine with a J then for you?

Saint-Theana commented 2 years ago

And by the way,J2IRConverter is outdated,it doesnot support some high level jvm feature like invoke-dynamic,wich has already been implemented in Dex2IR. So I assume that the original author of dex2jar put J2IR in a low priority. here is some code I implemented myself for J2IR to process newMultiDimensionArray and invoke-dynamic. you can add then this repo as you like.

//IR2JConverter.java line 766:method naryOperation
            @Override
            public JvmValue naryOperation(AbstractInsnNode insn, List<? extends JvmValue> xvalues) throws AnalyzerException {
                com.googlecode.dex2jar.ir.expr.Value values[] = new com.googlecode.dex2jar.ir.expr.Value[xvalues.size()];
                for (int i = 0; i < xvalues.size(); i++) {
                    values[i] = getLocal(xvalues.get(i));

                }
                if (insn.getOpcode() == MULTIANEWARRAY) {
                    MultiANewArrayInsnNode multi =(MultiANewArrayInsnNode) insn;

                    NewMutiArrayExpr n=Exprs.nNewMutiArray(multi.desc.replaceAll("\\[+", ""), multi.dims, values);

                    return b(Type.getType(multi.desc).getSize(), n);

                } else if(insn.getOpcode()==INVOKEDYNAMIC){
                    InvokeDynamicInsnNode mi=(InvokeDynamicInsnNode) insn;
                    Handle bsm=mi.bsm;
                    Type[] a=Type.getArgumentTypes(bsm.getDesc());
                    String[] params=new String[a.length];
                    for(int i=0;i<a.length;i+=1){
                        params[i]=a[i].getDescriptor();
                    }
                    Method method=new Method("L"+bsm.getOwner()+";",bsm.getName(),params,Type.getReturnType(bsm.getDesc()).getDescriptor());
                    MethodHandle mh=new MethodHandle(MethodHandle.getTypeFromAsmOpcode(bsm.getTag()),method);
                    Type[] t=Type.getArgumentTypes(mi.desc);
                    String[] paramst=new String[t.length];
                    for(int i=0;i<t.length;i+=1){
                        paramst[i]=t[i].getDescriptor();
                    }
                    InvokeCustomExpr d=Exprs.nInvokeCustom(values, mi.name, new Proto(paramst, Type.getReturnType(mi.desc).getDescriptor()), mh, mi.bsmArgs);
                    return b(Type.getReturnType(mi.desc).getSize(), d);
                }
         else
         {
                    MethodInsnNode mi = (MethodInsnNode) insn;
                    com.googlecode.dex2jar.ir.expr.Value v = null;
                    String ret = Type.getReturnType(mi.desc).getDescriptor();
                    String owner = "L" + mi.owner + ";";
                    String ps[] = toDescArray(Type.getArgumentTypes(mi.desc));
                    switch (insn.getOpcode()) {
                        case INVOKEVIRTUAL:
                            v = Exprs.nInvokeVirtual(values, owner, mi.name, ps, ret);
                            break;
                        case INVOKESPECIAL:
                            v = Exprs.nInvokeSpecial(values, owner, mi.name, ps, ret);
                            break;
                        case INVOKESTATIC:
                            v = Exprs.nInvokeStatic(values, owner, mi.name, ps, ret);
                            break;
                        case INVOKEINTERFACE:
                            v = Exprs.nInvokeInterface(values, owner, mi.name, ps, ret);
                            break;
                        case INVOKEDYNAMIC:
                            throw new UnsupportedOperationException("Not supported yet.");
                    }
                    if ("V".equals(ret)) {
                        emit(Stmts.nVoidInvoke(v));
                        return null;
                    } else {
                        return b(Type.getReturnType(mi.desc).getSize(), v);
                    }
                }
            }
public static int getTypeFromAsmOpcode(int opcode)
    {
        switch (opcode)
        {
            case Opcodes.H_GETFIELD:
                return INSTANCE_GET;
            case Opcodes.H_GETSTATIC:
                return STATIC_GET;
            case Opcodes.H_PUTFIELD:
                return INSTANCE_PUT;
            case Opcodes.H_PUTSTATIC:
                return STATIC_PUT;

            case Opcodes.H_INVOKEVIRTUAL:
                return INVOKE_INSTANCE;//?

            case Opcodes.H_INVOKESTATIC:
                return INVOKE_STATIC;

            case Opcodes.H_INVOKESPECIAL:
                return INVOKE_DIRECT;//?

            case Opcodes.H_NEWINVOKESPECIAL:
                return INVOKE_CONSTRUCTOR;
            case Opcodes.H_INVOKEINTERFACE:
                return INVOKE_INTERFACE;
        }
        throw new RuntimeException("not supported");
    }

I dont know if those code would be a help for anyone,but still,good luck.

Saint-Theana commented 2 years ago

yeah,it was obviously an erro when "J" misstaken with "D",when I replaced "D" with "J",it worked.

ThexXTURBOXx commented 2 years ago

Thanks for your code fragments! I have added a slightly modified version of them to the current codebase. Feel free to try v57!