private Exprent ProcessExprentRecursive(Exprent exprent) { bool replaced = true; while (replaced) { replaced = false; foreach (Exprent expr in exprent.GetAllExprents()) { Exprent retexpr = ProcessExprentRecursive(expr); if (retexpr != null) { exprent.ReplaceExprent(expr, retexpr); replaced = true; exprentReplaced = true; break; } } } if (exprent.type == Exprent.Exprent_Assignment) { AssignmentExprent @as = (AssignmentExprent)exprent; if (@as.GetRight().type == Exprent.Exprent_Function) { FunctionExprent func = (FunctionExprent)@as.GetRight(); VarType midlayer = null; if (func.GetFuncType() >= FunctionExprent.Function_I2l && func.GetFuncType() <= FunctionExprent .Function_I2s) { midlayer = func.GetSimpleCastType(); if (func.GetLstOperands()[0].type == Exprent.Exprent_Function) { func = (FunctionExprent)func.GetLstOperands()[0]; } else { return(null); } } if (func.GetFuncType() == FunctionExprent.Function_Add || func.GetFuncType() == FunctionExprent .Function_Sub) { Exprent econd = func.GetLstOperands()[0]; Exprent econst = func.GetLstOperands()[1]; if (econst.type != Exprent.Exprent_Const && econd.type == Exprent.Exprent_Const && func.GetFuncType() == FunctionExprent.Function_Add) { econd = econst; econst = func.GetLstOperands()[0]; } if (econst.type == Exprent.Exprent_Const && ((ConstExprent)econst).HasValueOne()) { Exprent left = @as.GetLeft(); VarType condtype = econd.GetExprType(); if (left.Equals(econd) && (midlayer == null || midlayer.Equals(condtype))) { FunctionExprent ret = new FunctionExprent(func.GetFuncType() == FunctionExprent.Function_Add ? FunctionExprent.Function_Ppi : FunctionExprent.Function_Mmi, econd, func.bytecode ); ret.SetImplicitType(condtype); exprentReplaced = true; return(ret); } } } } } return(null); }
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); }
private static Exprent IdentifySecondaryFunctions(Exprent exprent, bool statement_level , VarProcessor varProc) { if (exprent.type == Exprent.Exprent_Function) { FunctionExprent fexpr = (FunctionExprent)exprent; switch (fexpr.GetFuncType()) { case FunctionExprent.Function_Bool_Not: { Exprent retparam = PropagateBoolNot(fexpr); if (retparam != null) { return(retparam); } break; } case FunctionExprent.Function_Eq: case FunctionExprent.Function_Ne: case FunctionExprent.Function_Gt: case FunctionExprent.Function_Ge: case FunctionExprent.Function_Lt: case FunctionExprent.Function_Le: { Exprent expr1 = fexpr.GetLstOperands()[0]; Exprent expr2 = fexpr.GetLstOperands()[1]; if (expr1.type == Exprent.Exprent_Const) { expr2 = expr1; expr1 = fexpr.GetLstOperands()[1]; } if (expr1.type == Exprent.Exprent_Function && expr2.type == Exprent.Exprent_Const) { FunctionExprent funcexpr = (FunctionExprent)expr1; ConstExprent cexpr = (ConstExprent)expr2; int functype = funcexpr.GetFuncType(); if (functype == FunctionExprent.Function_Lcmp || functype == FunctionExprent.Function_Fcmpg || functype == FunctionExprent.Function_Fcmpl || functype == FunctionExprent.Function_Dcmpg || functype == FunctionExprent.Function_Dcmpl) { int desttype = -1; int?[] destcons = mapNumComparisons.GetOrNull(fexpr.GetFuncType()); if (destcons != null) { int index = cexpr.GetIntValue() + 1; if (index >= 0 && index <= 2) { int?destcon = destcons[index]; if (destcon != null) { desttype = destcon.Value; } } } if (desttype >= 0) { return(new FunctionExprent(desttype, funcexpr.GetLstOperands(), funcexpr.bytecode )); } } } break; } } } bool replaced = true; while (replaced) { replaced = false; foreach (Exprent expr in exprent.GetAllExprents()) { Exprent retexpr = IdentifySecondaryFunctions(expr, false, varProc); if (retexpr != null) { exprent.ReplaceExprent(expr, retexpr); replaced = true; break; } } } switch (exprent.type) { case Exprent.Exprent_Function: { FunctionExprent fexpr_1 = (FunctionExprent)exprent; List <Exprent> lstOperands = fexpr_1.GetLstOperands(); switch (fexpr_1.GetFuncType()) { case FunctionExprent.Function_Xor: { for (int i = 0; i < 2; i++) { Exprent operand = lstOperands[i]; VarType operandtype = operand.GetExprType(); if (operand.type == Exprent.Exprent_Const && operandtype.type != ICodeConstants.Type_Boolean) { ConstExprent cexpr = (ConstExprent)operand; long val; if (operandtype.type == ICodeConstants.Type_Long) { val = (long)cexpr.GetValue(); } else { val = (int)cexpr.GetValue(); } if (val == -1) { List <Exprent> lstBitNotOperand = new List <Exprent>(); lstBitNotOperand.Add(lstOperands[1 - i]); return(new FunctionExprent(FunctionExprent.Function_Bit_Not, lstBitNotOperand, fexpr_1 .bytecode)); } } } break; } case FunctionExprent.Function_Eq: case FunctionExprent.Function_Ne: { if (lstOperands[0].GetExprType().type == ICodeConstants.Type_Boolean && lstOperands [1].GetExprType().type == ICodeConstants.Type_Boolean) { for (int i = 0; i < 2; i++) { if (lstOperands[i].type == Exprent.Exprent_Const) { ConstExprent cexpr = (ConstExprent)lstOperands[i]; int val = (int)cexpr.GetValue(); if ((fexpr_1.GetFuncType() == FunctionExprent.Function_Eq && val == 1) || (fexpr_1 .GetFuncType() == FunctionExprent.Function_Ne && val == 0)) { return(lstOperands[1 - i]); } else { List <Exprent> lstNotOperand = new List <Exprent>(); lstNotOperand.Add(lstOperands[1 - i]); return(new FunctionExprent(FunctionExprent.Function_Bool_Not, lstNotOperand, fexpr_1 .bytecode)); } } } } break; } case FunctionExprent.Function_Bool_Not: { if (lstOperands[0].type == Exprent.Exprent_Const) { int val = ((ConstExprent)lstOperands[0]).GetIntValue(); if (val == 0) { return(new ConstExprent(VarType.Vartype_Boolean, 1, fexpr_1.bytecode)); } else { return(new ConstExprent(VarType.Vartype_Boolean, 0, fexpr_1.bytecode)); } } break; } case FunctionExprent.Function_Iif: { Exprent expr1_1 = lstOperands[1]; Exprent expr2_1 = lstOperands[2]; if (expr1_1.type == Exprent.Exprent_Const && expr2_1.type == Exprent.Exprent_Const) { ConstExprent cexpr1 = (ConstExprent)expr1_1; ConstExprent cexpr2 = (ConstExprent)expr2_1; if (cexpr1.GetExprType().type == ICodeConstants.Type_Boolean && cexpr2.GetExprType ().type == ICodeConstants.Type_Boolean) { if (cexpr1.GetIntValue() == 0 && cexpr2.GetIntValue() != 0) { return(new FunctionExprent(FunctionExprent.Function_Bool_Not, lstOperands[0], fexpr_1 .bytecode)); } else if (cexpr1.GetIntValue() != 0 && cexpr2.GetIntValue() == 0) { return(lstOperands[0]); } } } break; } case FunctionExprent.Function_Lcmp: case FunctionExprent.Function_Fcmpl: case FunctionExprent.Function_Fcmpg: case FunctionExprent.Function_Dcmpl: case FunctionExprent.Function_Dcmpg: { int var = DecompilerContext.GetCounterContainer().GetCounterAndIncrement(CounterContainer .Var_Counter); VarType type = lstOperands[0].GetExprType(); FunctionExprent iff = new FunctionExprent(FunctionExprent.Function_Iif, Sharpen.Arrays.AsList <Exprent> (new FunctionExprent(FunctionExprent.Function_Lt, Sharpen.Arrays.AsList <Exprent>(new VarExprent (var, type, varProc), ConstExprent.GetZeroConstant(type.type)), null), new ConstExprent (VarType.Vartype_Int, -1, null), new ConstExprent(VarType.Vartype_Int, 1, null)) , null); FunctionExprent head = new FunctionExprent(FunctionExprent.Function_Eq, Sharpen.Arrays.AsList <Exprent> (new AssignmentExprent(new VarExprent(var, type, varProc), new FunctionExprent(FunctionExprent .Function_Sub, Sharpen.Arrays.AsList(lstOperands[0], lstOperands[1]), null), null ), ConstExprent.GetZeroConstant(type.type)), null); varProc.SetVarType(new VarVersionPair(var, 0), type); return(new FunctionExprent(FunctionExprent.Function_Iif, Sharpen.Arrays.AsList <Exprent>(head , new ConstExprent(VarType.Vartype_Int, 0, null), iff), fexpr_1.bytecode)); } } break; } case Exprent.Exprent_Assignment: { // check for conditional assignment AssignmentExprent asexpr = (AssignmentExprent)exprent; Exprent right = asexpr.GetRight(); Exprent left = asexpr.GetLeft(); if (right.type == Exprent.Exprent_Function) { FunctionExprent func = (FunctionExprent)right; VarType midlayer = null; if (func.GetFuncType() >= FunctionExprent.Function_I2l && func.GetFuncType() <= FunctionExprent .Function_I2s) { right = func.GetLstOperands()[0]; midlayer = func.GetSimpleCastType(); if (right.type == Exprent.Exprent_Function) { func = (FunctionExprent)right; } else { return(null); } } List <Exprent> lstFuncOperands = func.GetLstOperands(); Exprent cond = null; switch (func.GetFuncType()) { case FunctionExprent.Function_Add: case FunctionExprent.Function_And: case FunctionExprent.Function_Or: case FunctionExprent.Function_Xor: { if (left.Equals(lstFuncOperands[1])) { cond = lstFuncOperands[0]; break; } goto case FunctionExprent.Function_Sub; } case FunctionExprent.Function_Sub: case FunctionExprent.Function_Mul: case FunctionExprent.Function_Div: case FunctionExprent.Function_Rem: case FunctionExprent.Function_Shl: case FunctionExprent.Function_Shr: case FunctionExprent.Function_Ushr: { if (left.Equals(lstFuncOperands[0])) { cond = lstFuncOperands[1]; } break; } } if (cond != null && (midlayer == null || midlayer.Equals(cond.GetExprType()))) { asexpr.SetRight(cond); asexpr.SetCondType(func.GetFuncType()); } } break; } case Exprent.Exprent_Invocation: { if (!statement_level) { // simplify if exprent is a real expression. The opposite case is pretty absurd, can still happen however (and happened at least once). Exprent retexpr = ConcatenationHelper.ContractStringConcat(exprent); if (!exprent.Equals(retexpr)) { return(retexpr); } } break; } } return(null); }
private static bool RemoveReturnCheck(Statement stat, StructMethod mt) { Statement parent = stat.GetParent(); if (parent != null && parent.type == Statement.Type_If && stat.type == Statement. Type_Basicblock && stat.GetExprents().Count == 1) { Exprent exprent = stat.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exit_exprent = (ExitExprent)exprent; if (exit_exprent.GetExitType() == ExitExprent.Exit_Return) { Exprent exprent_value = exit_exprent.GetValue(); //if(exprent_value.type == Exprent.EXPRENT_VAR) { // VarExprent var_value = (VarExprent)exprent_value; IfStatement ifparent = (IfStatement)parent; Exprent if_condition = ifparent.GetHeadexprent().GetCondition(); if (ifparent.GetElsestat() == stat && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent)if_condition).GetFuncType() == FunctionExprent.Function_Eq) { // TODO: reversed order possible (in theory) FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; StatEdge ifedge = ifparent.GetIfEdge(); StatEdge elseedge = ifparent.GetElseEdge(); Statement ifbranch = ifparent.GetIfstat(); Statement elsebranch = ifparent.GetElsestat(); 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)first_param).getIndex() == var_value.getIndex()) { if (first_param.Equals(exprent_value)) { // TODO: check for absence of side effects like method invocations etc. if (ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents()[0].type == Exprent.Exprent_Exit) { // TODO: special check for IllegalStateException ifparent.GetFirst().RemoveSuccessor(ifedge); ifparent.GetFirst().RemoveSuccessor(elseedge); ifparent.GetStats().RemoveWithKey(ifbranch.id); ifparent.GetStats().RemoveWithKey(elsebranch.id); if (!(ifbranch.GetAllSuccessorEdges().Count == 0)) { ifbranch.RemoveSuccessor(ifbranch.GetAllSuccessorEdges()[0]); } if (!(ifparent.GetFirst().GetExprents().Count == 0)) { elsebranch.GetExprents().InsertRange(0, ifparent.GetFirst().GetExprents()); } ifparent.GetParent().ReplaceStatement(ifparent, elsebranch); ifparent.GetParent().SetAllParent(); return(true); } } } } } } } else if (parent != null && parent.type == Statement.Type_Sequence && stat.type == Statement.Type_Basicblock && stat.GetExprents().Count == 1) { //} Exprent exprent = stat.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exit_exprent = (ExitExprent)exprent; if (exit_exprent.GetExitType() == ExitExprent.Exit_Return) { Exprent exprent_value = exit_exprent.GetValue(); SequenceStatement sequence = (SequenceStatement)parent; int sequence_stats_number = sequence.GetStats().Count; if (sequence_stats_number > 1 && sequence.GetStats().GetLast() == stat && sequence .GetStats()[sequence_stats_number - 2].type == Statement.Type_If) { IfStatement ifstat = (IfStatement)sequence.GetStats()[sequence_stats_number - 2]; Exprent if_condition = ifstat.GetHeadexprent().GetCondition(); if (ifstat.iftype == IfStatement.Iftype_If && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent)if_condition).GetFuncType() == FunctionExprent.Function_Eq) { // TODO: reversed order possible (in theory) FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; Statement ifbranch = ifstat.GetIfstat(); if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order if (first_param.Equals(exprent_value)) { // TODO: check for absence of side effects like method invocations etc. if (ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents()[0].type == Exprent.Exprent_Exit) { // TODO: special check for IllegalStateException ifstat.RemoveSuccessor(ifstat.GetAllSuccessorEdges()[0]); // remove 'else' edge if (!(ifstat.GetFirst().GetExprents().Count == 0)) { stat.GetExprents().InsertRange(0, ifstat.GetFirst().GetExprents()); } foreach (StatEdge edge in ifstat.GetAllPredecessorEdges()) { ifstat.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, stat); stat.AddPredecessor(edge); } sequence.GetStats().RemoveWithKey(ifstat.id); sequence.SetFirst(sequence.GetStats()[0]); return(true); } } } } } } } } foreach (Statement st in stat.GetStats()) { if (RemoveReturnCheck(st, mt)) { return(true); } } return(false); }
public static Exprent ContractStringConcat(Exprent expr) { Exprent exprTmp = null; VarType cltype = null; // first quick test if (expr.type == Exprent.Exprent_Invocation) { InvocationExprent iex = (InvocationExprent)expr; if ("toString".Equals(iex.GetName())) { if (builderClass.Equals(iex.GetClassname())) { cltype = builderType; } else if (bufferClass.Equals(iex.GetClassname())) { cltype = bufferType; } if (cltype != null) { exprTmp = iex.GetInstance(); } } else if ("makeConcatWithConstants".Equals(iex.GetName())) { // java 9 style List <Exprent> parameters = ExtractParameters(iex.GetBootstrapArguments(), iex); if (parameters.Count >= 2) { return(CreateConcatExprent(parameters, expr.bytecode)); } } } if (exprTmp == null) { return(expr); } // iterate in depth, collecting possible operands List <Exprent> lstOperands = new List <Exprent>(); while (true) { int found = 0; switch (exprTmp.type) { case Exprent.Exprent_Invocation: { InvocationExprent iex = (InvocationExprent)exprTmp; if (IsAppendConcat(iex, cltype)) { lstOperands.Add(0, iex.GetLstParameters()[0]); exprTmp = iex.GetInstance(); found = 1; } break; } case Exprent.Exprent_New: { NewExprent nex = (NewExprent)exprTmp; if (IsNewConcat(nex, cltype)) { VarType[] @params = nex.GetConstructor().GetDescriptor().@params; if (@params.Length == 1) { lstOperands.Add(0, nex.GetConstructor().GetLstParameters()[0]); } found = 2; } break; } } if (found == 0) { return(expr); } else if (found == 2) { break; } } int first2str = 0; int index = 0; while (index < lstOperands.Count && index < 2) { if (lstOperands[index].GetExprType().Equals(VarType.Vartype_String)) { first2str |= (index + 1); } index++; } if (first2str == 0) { lstOperands.Add(0, new ConstExprent(VarType.Vartype_String, string.Empty, expr.bytecode )); } // remove redundant String.valueOf for (int i = 0; i < lstOperands.Count; i++) { Exprent rep = RemoveStringValueOf(lstOperands[i]); bool ok = (i > 1); if (!ok) { bool isstr = rep.GetExprType().Equals(VarType.Vartype_String); ok = isstr || first2str != i + 1; if (i == 0) { first2str &= 2; } } if (ok) { lstOperands[i] = rep; } } return(CreateConcatExprent(lstOperands, expr.bytecode)); }