private static Exprent IsPPIorMMI(Exprent first) { if (first.type == Exprent.Exprent_Assignment) { AssignmentExprent @as = (AssignmentExprent)first; if (@as.GetRight().type == Exprent.Exprent_Function) { FunctionExprent func = (FunctionExprent)@as.GetRight(); 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(); if (left.type != Exprent.Exprent_Var && left.Equals(econd)) { int type = func.GetFuncType() == FunctionExprent.Function_Add ? FunctionExprent.Function_Ppi : FunctionExprent.Function_Mmi; FunctionExprent ret = new FunctionExprent(type, econd, func.bytecode); ret.SetImplicitType(VarType.Vartype_Int); return(ret); } } } } } return(null); }
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 object[] IterateChildExprent(Exprent exprent, Exprent parent, Exprent next, Dictionary <VarVersionPair, Exprent> mapVarValues, SSAUConstructorSparseEx ssau) { bool changed = false; foreach (Exprent expr in exprent.GetAllExprents()) { var oldExpr = expr; while (true) { object[] arr = IterateChildExprent(oldExpr, parent, next, mapVarValues, ssau); Exprent retexpr = (Exprent)arr[0]; changed |= (bool)arr[1]; bool isReplaceable = (bool)arr[2]; if (retexpr != null) { if (isReplaceable) { ReplaceSingleVar(exprent, (VarExprent)oldExpr, retexpr, ssau); oldExpr = retexpr; } else { exprent.ReplaceExprent(oldExpr, retexpr); } changed = true; } if (!isReplaceable) { break; } } } Exprent dest = IsReplaceableVar(exprent, mapVarValues); if (dest != null) { return(new object[] { dest, true, true }); } VarExprent left = null; Exprent right = null; if (exprent.type == Exprent.Exprent_Assignment) { AssignmentExprent @as = (AssignmentExprent)exprent; if (@as.GetLeft().type == Exprent.Exprent_Var) { left = (VarExprent)@as.GetLeft(); right = @as.GetRight(); } } if (left == null) { return(new object[] { null, changed, false }); } bool isHeadSynchronized = false; if (next == null && parent.type == Exprent.Exprent_Monitor) { MonitorExprent monexpr = (MonitorExprent)parent; if (monexpr.GetMonType() == MonitorExprent.Monitor_Enter && exprent.Equals(monexpr .GetValue())) { isHeadSynchronized = true; } } // stack variable or synchronized head exprent if (!left.IsStack() && !isHeadSynchronized) { return(new object[] { null, changed, false }); } VarVersionPair leftpaar = new VarVersionPair(left); List <VarVersionNode> usedVers = new List <VarVersionNode>(); bool notdom = GetUsedVersions(ssau, leftpaar, usedVers); if (!notdom && (usedVers.Count == 0)) { return(new object[] { right, changed, false }); } // stack variables only if (!left.IsStack()) { return(new object[] { null, changed, false }); } int useflags = right.GetExprentUse(); if ((useflags & Exprent.Both_Flags) != Exprent.Both_Flags) { return(new object[] { null, changed, false }); } Dictionary <int, HashSet <VarVersionPair> > mapVars = GetAllVarVersions(leftpaar, right , ssau); if (mapVars.ContainsKey(leftpaar.var) && notdom) { return(new object[] { null, changed, false }); } Sharpen.Collections.Remove(mapVars, leftpaar.var); HashSet <VarVersionPair> setAllowedVars = GetAllVersions(parent); if (next != null) { Sharpen.Collections.AddAll(setAllowedVars, GetAllVersions(next)); } bool vernotreplaced = false; HashSet <VarVersionPair> setTempUsedVers = new HashSet <VarVersionPair>(); foreach (VarVersionNode usedvar in usedVers) { VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version); if (IsVersionToBeReplaced(usedver, mapVars, ssau, leftpaar) && (right.type == Exprent .Exprent_Var || setAllowedVars.Contains(usedver))) { setTempUsedVers.Add(usedver); } else { vernotreplaced = true; } } if (!notdom && !vernotreplaced) { foreach (VarVersionPair usedver in setTempUsedVers) { Exprent copy = right.Copy(); if (right.type == Exprent.Exprent_Field && ssau.GetMapFieldVars().ContainsKey(right .id)) { Sharpen.Collections.Put(ssau.GetMapFieldVars(), copy.id, ssau.GetMapFieldVars().GetOrNullable (right.id)); } Sharpen.Collections.Put(mapVarValues, usedver, copy); } // remove assignment return(new object[] { right, changed, false }); } return(new object[] { null, changed, false }); }
private static void ExtractDynamicInitializers(ClassWrapper wrapper) { StructClass cl = wrapper.GetClassStruct(); bool isAnonymous = DecompilerContext.GetClassProcessor().GetMapRootClasses().GetOrNull (cl.qualifiedName).type == ClassesProcessor.ClassNode.Class_Anonymous; List <List <Exprent> > lstFirst = new List <List <Exprent> >(); List <MethodWrapper> lstMethodWrappers = new List <MethodWrapper>(); foreach (MethodWrapper method in wrapper.GetMethods()) { if (ICodeConstants.Init_Name.Equals(method.methodStruct.GetName()) && method.root != null) { // successfully decompiled constructor Statement firstData = Statements.FindFirstData(method.root); if (firstData == null || (firstData.GetExprents().Count == 0)) { return; } lstFirst.Add(firstData.GetExprents()); lstMethodWrappers.Add(method); Exprent exprent = firstData.GetExprents()[0]; if (!isAnonymous) { // FIXME: doesn't make sense if (exprent.type != Exprent.Exprent_Invocation || !Statements.IsInvocationInitConstructor ((InvocationExprent)exprent, method, wrapper, false)) { return; } } } } if ((lstFirst.Count == 0)) { return; } while (true) { string fieldWithDescr = null; Exprent value = null; for (int i = 0; i < lstFirst.Count; i++) { List <Exprent> lst = lstFirst[i]; if (lst.Count < (isAnonymous ? 1 : 2)) { return; } Exprent exprent = lst[isAnonymous ? 0 : 1]; bool found = false; if (exprent.type == Exprent.Exprent_Assignment) { AssignmentExprent assignExpr = (AssignmentExprent)exprent; if (assignExpr.GetLeft().type == Exprent.Exprent_Field) { FieldExprent fExpr = (FieldExprent)assignExpr.GetLeft(); if (!fExpr.IsStatic() && fExpr.GetClassname().Equals(cl.qualifiedName) && cl.HasField (fExpr.GetName(), fExpr.GetDescriptor().descriptorString)) { // check for the physical existence of the field. Could be defined in a superclass. if (IsExprentIndependent(assignExpr.GetRight(), lstMethodWrappers[i])) { string fieldKey = InterpreterUtil.MakeUniqueKey(fExpr.GetName(), fExpr.GetDescriptor ().descriptorString); if (fieldWithDescr == null) { fieldWithDescr = fieldKey; value = assignExpr.GetRight(); } else if (!fieldWithDescr.Equals(fieldKey) || !value.Equals(assignExpr.GetRight())) { return; } found = true; } } } } if (!found) { return; } } if (!wrapper.GetDynamicFieldInitializers().ContainsKey(fieldWithDescr)) { wrapper.GetDynamicFieldInitializers().AddWithKey(value, fieldWithDescr); foreach (List <Exprent> lst in lstFirst) { lst.RemoveAtReturningValue(isAnonymous ? 0 : 1); } } else { return; } } }
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); }
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); }