private SFormsFastMapDirect CreateFirstMap(StructMethod mt, RootStatement root) { bool thisvar = !mt.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int paramcount = [email protected] + (thisvar ? 1 : 0); int varindex = 0; SFormsFastMapDirect map = new SFormsFastMapDirect(); for (int i = 0; i < paramcount; i++) { int version = GetNextFreeVersion(varindex, root); // == 1 FastSparseSetFactory <int> .FastSparseSet <int> set = factory.SpawnEmptySet(); set.Add(version); map.Put(varindex, set); ssuversions.CreateNode(new VarVersionPair(varindex, version)); if (thisvar) { if (i == 0) { varindex++; } else { varindex += md.@params[i - 1].stackSize; } } else { varindex += md.@params[i].stackSize; } } return(map); }
public static void ClearEnum(ClassWrapper wrapper) { StructClass cl = wrapper.GetClassStruct(); // hide values/valueOf methods and super() invocations foreach (MethodWrapper method in wrapper.GetMethods()) { StructMethod mt = method.methodStruct; string name = mt.GetName(); string descriptor = mt.GetDescriptor(); if ("values".Equals(name)) { if (descriptor.Equals("()[L" + cl.qualifiedName + ";")) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(name, descriptor)); } } else if ("valueOf".Equals(name)) { if (descriptor.Equals("(Ljava/lang/String;)L" + cl.qualifiedName + ";")) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(name, descriptor)); } } else if (ICodeConstants.Init_Name.Equals(name)) { Statement firstData = Statements.FindFirstData(method.root); if (firstData != null && !(firstData.GetExprents().Count == 0)) { Exprent exprent = firstData.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Invocation) { InvocationExprent invExpr = (InvocationExprent)exprent; if (Statements.IsInvocationInitConstructor(invExpr, method, wrapper, false)) { firstData.GetExprents().RemoveAtReturningValue(0); } } } } } // hide synthetic fields of enum and it's constants foreach (StructField fd in cl.GetFields()) { string descriptor = fd.GetDescriptor(); if (fd.IsSynthetic() && descriptor.Equals("[L" + cl.qualifiedName + ";")) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(fd.GetName(), descriptor )); } } }
private static void MapClassMethods(ClassesProcessor.ClassNode node, Dictionary < ClassWrapper, MethodWrapper> map) { bool noSynthFlag = DecompilerContext.GetOption(IFernflowerPreferences.Synthetic_Not_Set ); ClassWrapper wrapper = node.GetWrapper(); foreach (MethodWrapper method in wrapper.GetMethods()) { StructMethod mt = method.methodStruct; if ((noSynthFlag || mt.IsSynthetic()) && mt.GetDescriptor().Equals("(Ljava/lang/String;)Ljava/lang/Class;" ) && mt.HasModifier(ICodeConstants.Acc_Static)) { RootStatement root = method.root; if (root != null && root.GetFirst().type == Statement.Type_Trycatch) { CatchStatement cst = (CatchStatement)root.GetFirst(); if (cst.GetStats().Count == 2 && cst.GetFirst().type == Statement.Type_Basicblock && cst.GetStats()[1].type == Statement.Type_Basicblock && cst.GetVars()[0].GetVarType ().Equals(new VarType(ICodeConstants.Type_Object, 0, "java/lang/ClassNotFoundException" ))) { BasicBlockStatement body = (BasicBlockStatement)cst.GetFirst(); BasicBlockStatement handler = (BasicBlockStatement)cst.GetStats()[1]; if (body.GetExprents().Count == 1 && handler.GetExprents().Count == 1) { if (Body_Expr.Equals(body.GetExprents()[0]) && Handler_Expr.Equals(handler.GetExprents ()[0])) { Sharpen.Collections.Put(map, wrapper, method); break; } } } } } } // iterate nested classes foreach (ClassesProcessor.ClassNode nd in node.nested) { MapClassMethods(nd, map); } }
public static DataPoint GetInitialDataPoint(StructMethod mt) { DataPoint point = new DataPoint(); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int k = 0; if (!mt.HasModifier(ICodeConstants.Acc_Static)) { point.SetVariable(k++, new VarType(ICodeConstants.Type_Object, 0, null)); } for (int i = 0; i < [email protected]; i++) { VarType var = md.@params[i]; point.SetVariable(k++, var); if (var.stackSize == 2) { point.SetVariable(k++, new VarType(ICodeConstants.Type_Group2empty)); } } return(point); }
public virtual byte[] LoadBytecode(StructMethod mt, int codeFullLength) { string className = mt.GetClassStruct().qualifiedName; try { using (DataInputFullStream @in = GetClassStream(className)) { if (@in != null) { @in.Discard(8); ConstantPool pool = mt.GetClassStruct().GetPool(); if (pool == null) { pool = new ConstantPool(@in); } else { ConstantPool.SkipPool(@in); } @in.Discard(6); // interfaces @in.Discard(@in.ReadUnsignedShort() * 2); // fields int size = @in.ReadUnsignedShort(); for (int i = 0; i < size; i++) { @in.Discard(6); SkipAttributes(@in); } // methods size = @in.ReadUnsignedShort(); for (int i = 0; i < size; i++) { @in.Discard(2); int nameIndex = @in.ReadUnsignedShort(); int descriptorIndex = @in.ReadUnsignedShort(); string[] values = pool.GetClassElement(ConstantPool.Method, className, nameIndex, descriptorIndex); if (!mt.GetName().Equals(values[0]) || !mt.GetDescriptor().Equals(values[1])) { SkipAttributes(@in); continue; } int attrSize = @in.ReadUnsignedShort(); for (int j = 0; j < attrSize; j++) { int attrNameIndex = @in.ReadUnsignedShort(); string attrName = pool.GetPrimitiveConstant(attrNameIndex).GetString(); if (!StructGeneralAttribute.Attribute_Code.GetName().Equals(attrName)) { @in.Discard(@in.ReadInt()); continue; } @in.Discard(12); return(@in.Read(codeFullLength)); } break; } } return(null); } } catch (IOException ex) { throw; } }
public static void ProcessClassReferences(ClassesProcessor.ClassNode node) { // find the synthetic method Class class$(String) if present Dictionary <ClassWrapper, MethodWrapper> mapClassMeths = new Dictionary <ClassWrapper , MethodWrapper>(); MapClassMethods(node, mapClassMeths); if ((mapClassMeths.Count == 0)) { return; } HashSet <ClassWrapper> setFound = new HashSet <ClassWrapper>(); ProcessClassRec(node, mapClassMeths, setFound); if (!(setFound.Count == 0)) { foreach (ClassWrapper wrp in setFound) { StructMethod mt = mapClassMeths.GetOrNull(wrp).methodStruct; wrp.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(mt.GetName(), mt.GetDescriptor ())); } } }
private void ComputeMethodType(ClassesProcessor.ClassNode node, MethodWrapper method ) { NestedMemberAccess.MethodAccess type = NestedMemberAccess.MethodAccess.Normal; if (method.root != null) { DirectGraph graph = method.GetOrBuildGraph(); StructMethod mt = method.methodStruct; if ((noSynthFlag || mt.IsSynthetic()) && mt.HasModifier(ICodeConstants.Acc_Static )) { if (graph.nodes.Count == 2) { // incl. dummy exit node if (graph.first.exprents.Count == 1) { Exprent exprent = graph.first.exprents[0]; MethodDescriptor mtdesc = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int parcount = [email protected]; Exprent exprCore = exprent; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)exprent; if (exexpr.GetExitType() == ExitExprent.Exit_Return && exexpr.GetValue() != null) { exprCore = exexpr.GetValue(); } } switch (exprCore.type) { case Exprent.Exprent_Field: { FieldExprent fexpr = (FieldExprent)exprCore; if ((parcount == 1 && !fexpr.IsStatic()) || (parcount == 0 && fexpr.IsStatic())) { if (fexpr.GetClassname().Equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpr.IsStatic() || (fexpr.GetInstance().type == Exprent.Exprent_Var && ((VarExprent )fexpr.GetInstance()).GetIndex() == 0)) { type = NestedMemberAccess.MethodAccess.Field_Get; } } } break; } case Exprent.Exprent_Var: { // qualified this if (parcount == 1) { // this or final variable if (((VarExprent)exprCore).GetIndex() != 0) { type = NestedMemberAccess.MethodAccess.Field_Get; } } break; } case Exprent.Exprent_Function: { // for now detect only increment/decrement FunctionExprent functionExprent = (FunctionExprent)exprCore; if (functionExprent.GetFuncType() >= FunctionExprent.Function_Imm && functionExprent .GetFuncType() <= FunctionExprent.Function_Ppi) { if (functionExprent.GetLstOperands()[0].type == Exprent.Exprent_Field) { type = NestedMemberAccess.MethodAccess.Function; } } break; } case Exprent.Exprent_Invocation: { type = NestedMemberAccess.MethodAccess.Method; break; } case Exprent.Exprent_Assignment: { AssignmentExprent asexpr = (AssignmentExprent)exprCore; if (asexpr.GetLeft().type == Exprent.Exprent_Field && asexpr.GetRight().type == Exprent .Exprent_Var) { FieldExprent fexpras = (FieldExprent)asexpr.GetLeft(); if ((parcount == 2 && !fexpras.IsStatic()) || (parcount == 1 && fexpras.IsStatic( ))) { if (fexpras.GetClassname().Equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpras.IsStatic() || (fexpras.GetInstance().type == Exprent.Exprent_Var && ( (VarExprent)fexpras.GetInstance()).GetIndex() == 0)) { if (((VarExprent)asexpr.GetRight()).GetIndex() == parcount - 1) { type = NestedMemberAccess.MethodAccess.Field_Set; } } } } } break; } } if (type == NestedMemberAccess.MethodAccess.Method) { // FIXME: check for private flag of the method type = NestedMemberAccess.MethodAccess.Normal; InvocationExprent invexpr = (InvocationExprent)exprCore; bool isStatic = invexpr.IsStatic(); if ((isStatic && invexpr.GetLstParameters().Count == parcount) || (!isStatic && invexpr .GetInstance().type == Exprent.Exprent_Var && ((VarExprent)invexpr.GetInstance() ).GetIndex() == 0 && invexpr.GetLstParameters().Count == parcount - 1)) { bool equalpars = true; int index = isStatic ? 0 : 1; for (int i = 0; i < invexpr.GetLstParameters().Count; i++) { Exprent parexpr = invexpr.GetLstParameters()[i]; if (parexpr.type != Exprent.Exprent_Var || ((VarExprent)parexpr).GetIndex() != index) { equalpars = false; break; } index += mtdesc.@params[i + (isStatic ? 0 : 1)].stackSize; } if (equalpars) { type = NestedMemberAccess.MethodAccess.Method; } } } } else if (graph.first.exprents.Count == 2) { Exprent exprentFirst = graph.first.exprents[0]; Exprent exprentSecond = graph.first.exprents[1]; if (exprentFirst.type == Exprent.Exprent_Assignment && exprentSecond.type == Exprent .Exprent_Exit) { MethodDescriptor mtdesc = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int parcount = [email protected]; AssignmentExprent asexpr = (AssignmentExprent)exprentFirst; if (asexpr.GetLeft().type == Exprent.Exprent_Field && asexpr.GetRight().type == Exprent .Exprent_Var) { FieldExprent fexpras = (FieldExprent)asexpr.GetLeft(); if ((parcount == 2 && !fexpras.IsStatic()) || (parcount == 1 && fexpras.IsStatic( ))) { if (fexpras.GetClassname().Equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpras.IsStatic() || (fexpras.GetInstance().type == Exprent.Exprent_Var && ( (VarExprent)fexpras.GetInstance()).GetIndex() == 0)) { if (((VarExprent)asexpr.GetRight()).GetIndex() == parcount - 1) { ExitExprent exexpr = (ExitExprent)exprentSecond; if (exexpr.GetExitType() == ExitExprent.Exit_Return && exexpr.GetValue() != null) { if (exexpr.GetValue().type == Exprent.Exprent_Var && ((VarExprent)asexpr.GetRight ()).GetIndex() == parcount - 1) { type = NestedMemberAccess.MethodAccess.Field_Set; } } } } } } } } } } } } if (type != NestedMemberAccess.MethodAccess.Normal) { Sharpen.Collections.Put(mapMethodType, method, type); } else { Sharpen.Collections.Remove(mapMethodType, method); } }
private static bool FindAndRemoveParameterCheck(Statement stat, StructMethod mt) { Statement st = stat.GetFirst(); while (st.type == Statement.Type_Sequence) { st = st.GetFirst(); } if (st.type == Statement.Type_If) { IfStatement ifstat = (IfStatement)st; Statement ifbranch = ifstat.GetIfstat(); Exprent if_condition = ifstat.GetHeadexprent().GetCondition(); bool is_notnull_check = false; // TODO: FUNCTION_NE also possible if reversed order (in theory) if (ifbranch != null && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent )if_condition).GetFuncType() == FunctionExprent.Function_Eq && ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents ()[0].type == Exprent.Exprent_Exit) { FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order if (first_param.type == Exprent.Exprent_Var) { VarExprent var = (VarExprent)first_param; bool thisvar = !mt.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); // parameter annotations StructAnnotationParameterAttribute param_annotations = mt.GetAttribute(StructGeneralAttribute .Attribute_Runtime_Invisible_Parameter_Annotations); if (param_annotations != null) { List <List <AnnotationExprent> > param_annotations_lists = param_annotations.GetParamAnnotations (); int method_param_number = [email protected]; int index = thisvar ? 1 : 0; for (int i = 0; i < method_param_number; i++) { if (index == var.GetIndex()) { if (param_annotations_lists.Count >= method_param_number - i) { int shift = method_param_number - param_annotations_lists.Count; // NOTE: workaround for compiler bug, count annotations starting with the last parameter List <AnnotationExprent> annotations = param_annotations_lists[i - shift]; foreach (AnnotationExprent ann in annotations) { if (ann.GetClassName().Equals("org/jetbrains/annotations/NotNull")) { is_notnull_check = true; break; } } } break; } index += md.@params[i].stackSize; } } } } } if (!is_notnull_check) { return(false); } RemoveParameterCheck(stat); return(true); } return(false); }
public VarDefinitionHelper(Statement root, StructMethod mt, VarProcessor varproc) { // statement.id, defined vars mapVarDefStatements = new Dictionary <int, Statement>(); mapStatementVars = new Dictionary <int, HashSet <int> >(); implDefVars = new HashSet <int>(); this.varproc = varproc; VarNamesCollector vc = varproc.GetVarNamesCollector(); bool thisvar = !mt.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int paramcount = 0; if (thisvar) { paramcount = 1; } paramcount += [email protected]; // method parameters are implicitly defined int varindex = 0; for (int i = 0; i < paramcount; i++) { implDefVars.Add(varindex); varproc.SetVarName(new VarVersionPair(varindex, 0), vc.GetFreeName(varindex)); if (thisvar) { if (i == 0) { varindex++; } else { varindex += md.@params[i - 1].stackSize; } } else { varindex += md.@params[i].stackSize; } } if (thisvar) { StructClass current_class = (StructClass)DecompilerContext.GetProperty(DecompilerContext .Current_Class); Sharpen.Collections.Put(varproc.GetThisVars(), new VarVersionPair(0, 0), current_class .qualifiedName); varproc.SetVarName(new VarVersionPair(0, 0), "this"); vc.AddName("this"); } // catch variables are implicitly defined LinkedList <Statement> stack = new LinkedList <Statement>(); stack.AddLast(root); while (!(stack.Count == 0)) { Statement st = Sharpen.Collections.RemoveFirst(stack); List <VarExprent> lstVars = null; if (st.type == Statement.Type_Catchall) { lstVars = ((CatchAllStatement)st).GetVars(); } else if (st.type == Statement.Type_Trycatch) { lstVars = ((CatchStatement)st).GetVars(); } if (lstVars != null) { foreach (VarExprent var in lstVars) { implDefVars.Add(var.GetIndex()); varproc.SetVarName(new VarVersionPair(var), vc.GetFreeName(var.GetIndex())); var.SetDefinition(true); } } Sharpen.Collections.AddAll(stack, st.GetStats()); } InitStatement(root); }
private void RenameClassIdentifiers(StructClass cl, Dictionary <string, string> names ) { // all classes are already renamed string classOldFullName = cl.qualifiedName; string classNewFullName = interceptor.GetName(classOldFullName); if (classNewFullName == null) { classNewFullName = classOldFullName; } // methods HashSet <string> setMethodNames = new HashSet <string>(); foreach (StructMethod md in cl.GetMethods()) { setMethodNames.Add(md.GetName()); } VBStyleCollection <StructMethod, string> methods = cl.GetMethods(); for (int i = 0; i < methods.Count; i++) { StructMethod mt = methods[i]; string key = methods.GetKey(i); bool isPrivate = mt.HasModifier(ICodeConstants.Acc_Private); string name = mt.GetName(); if (!cl.IsOwn() || mt.HasModifier(ICodeConstants.Acc_Native)) { // external and native methods must not be renamed if (!isPrivate) { Sharpen.Collections.Put(names, key, name); } } else if (helper.ToBeRenamed(IIdentifierRenamer.Type.Element_Method, classOldFullName , name, mt.GetDescriptor())) { if (isPrivate || !names.ContainsKey(key)) { do { name = helper.GetNextMethodName(classOldFullName, name, mt.GetDescriptor()); }while (setMethodNames.Contains(name)); if (!isPrivate) { Sharpen.Collections.Put(names, key, name); } } else { name = names.GetOrNull(key); } interceptor.AddName(classOldFullName + " " + mt.GetName() + " " + mt.GetDescriptor (), classNewFullName + " " + name + " " + BuildNewDescriptor(false, mt.GetDescriptor ())); } } // external fields are not being renamed if (!cl.IsOwn()) { return; } // fields // FIXME: should overloaded fields become the same name? HashSet <string> setFieldNames = new HashSet <string>(); foreach (StructField fd in cl.GetFields()) { setFieldNames.Add(fd.GetName()); } foreach (StructField fd in cl.GetFields()) { if (helper.ToBeRenamed(IIdentifierRenamer.Type.Element_Field, classOldFullName, fd .GetName(), fd.GetDescriptor())) { string newName; do { newName = helper.GetNextFieldName(classOldFullName, fd.GetName(), fd.GetDescriptor ()); }while (setFieldNames.Contains(newName)); interceptor.AddName(classOldFullName + " " + fd.GetName() + " " + fd.GetDescriptor (), classNewFullName + " " + newName + " " + BuildNewDescriptor(true, fd.GetDescriptor ())); } } }
private BitSet GetAmbiguousParameters() { StructClass cl = DecompilerContext.GetStructContext().GetClass(classname); if (cl == null) { return(Empty_Bit_Set); } // check number of matches List <MethodDescriptor> matches = new List <MethodDescriptor>(); foreach (StructMethod mt in cl.GetMethods()) { if (name.Equals(mt.GetName())) { MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); if ([email protected] == [email protected]) { for (int i = 0; i < [email protected]; i++) { if (md.@params[i].typeFamily != descriptor.@params[i].typeFamily) { goto nextMethod_continue; } } matches.Add(md); } } } nextMethod_break :; nextMethod_continue : if (matches.Count == 1) { return(Empty_Bit_Set); } // check if a call is unambiguous StructMethod mt_1 = cl.GetMethod(InterpreterUtil.MakeUniqueKey(name, stringDescriptor )); if (mt_1 != null) { MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt_1.GetDescriptor()); if ([email protected] == lstParameters.Count) { bool exact = true; for (int i = 0; i < [email protected]; i++) { if (!md.@params[i].Equals(lstParameters[i].GetExprType())) { exact = false; break; } } if (exact) { return(Empty_Bit_Set); } } } // mark parameters BitSet ambiguous = new BitSet([email protected]); for (int i = 0; i < [email protected]; i++) { VarType paramType = descriptor.@params[i]; foreach (MethodDescriptor md in matches) { if (!paramType.Equals(md.@params[i])) { ambiguous.Set(i); break; } } } return(ambiguous); }