java.lang.Object
com.pnfsoftware.jeb.core.units.code.asm.decompiler.ast.CUtil

public class CUtil extends Object
Utility methods to manipulate AST elements.
  • Constructor Details

    • CUtil

      public CUtil()
  • Method Details

    • findParent

      public static ICElement findParent(ICElement root, ICElement elt)
      Retrieve the parent of an AST element (or first parent, if the element is reusable and has potentially multiple parents - e.g. ICIdentifier).
      Parameters:
      root - a root element, typically, an ICMethod
      elt - the element for which the first parent is to be found
      Returns:
      the parent or null
    • isClassMethodField

      public static boolean isClassMethodField(ICElement e)
      Check if the element is either an ICClass, an ICMethod or an ICField
    • isIntegerConstant

      public static boolean isIntegerConstant(ICExpression expr)
      Check if the element is a ICConstantInteger
    • isIntegerValue

      public static boolean isIntegerValue(ICExpression expr, long value)
      Check if the element is a ICConstantInteger equals to the given value.
    • getConstantAsLong

      public static Long getConstantAsLong(ICConstant<?> expr)
      Retrieve the value associated to an ICConstant as a Long.
      Parameters:
      expr -
      Returns:
      constant value, null if none could be retrieved
    • hasNoSideEffects

      public static boolean hasNoSideEffects(ICElement elem)
      Check if an ICElement can not possibly modify variables. This method is intended to be safe, e.g. it will return false on ICCall.
      Parameters:
      elem -
      Returns:
      true if no variables would be modified by executing the element, false otherwise
    • hasNoCall

      public static boolean hasNoCall(ICElement elem)
      Check if no ICCall is done by this ICElement.
      Parameters:
      elem -
      Returns:
      true if no ICCall is done, false otherwise
    • getIfGotoTarget

      public static ICLabel getIfGotoTarget(ICStatement stm)
      Check if the statement follows the pattern if(P){goto x;} and if so, returns x.
      Parameters:
      stm -
      Returns:
      the label pointed by the goto if the statement follows the pattern, null otherwise
    • isIfBranch

      public static boolean isIfBranch(ICStatement stm)
      Check if the statement follows the pattern if(P){BRANCH;}, where BRANCH is a sole branch instruction.
    • hasEmptyBranch

      public static boolean hasEmptyBranch(ICIfStm stm)
      Check if a if-statement has an empty branch (including the default one).
    • isContainingLabel

      public static boolean isContainingLabel(ICStatement stm, ICLabel targetLabel)
      Check if a statement contains a given label; compound statements are recursively processed to search for the label.
    • isGotoTo

      public static boolean isGotoTo(ICStatement stm, ICLabel target)
      Check if the statement is a ICGoto to the given label.
    • getGotoLabel

      public static ICLabel getGotoLabel(ICStatement stm)
      Check if the statement is a ICGoto to return the label; else, return null.
    • isBreakTo

      public static boolean isBreakTo(ICStatement stm, ICLabel target)
      Check if the statement is a ICBreak to the given label.
    • isPlainBreak

      public static boolean isPlainBreak(ICStatement stm)
      Check if the statement is a ICBreak without label.
    • isIfElse

      public static boolean isIfElse(ICStatement stm)
      Check if a statement is a if-statement with two blocks, including a default block.
    • flipIfElse

      public static boolean flipIfElse(ICStatement stm, ICOperatorFactory of)
      Check if a statement is a if-statement with two blocks, including a default block, and reverse the condition. Effectively, if(A){X}else{Y} is transformed to if(!A){Y}else{X}}.
      Parameters:
      stm -
      of -
      Returns:
      success indicator
    • isIfNoElse

      public static boolean isIfNoElse(ICStatement stm)
      Check if a statement follows the pattern if(P){ }[else if(...){}]*, i.e. a if-statement with possibly multiple blocks but no default else block.
    • isWhileTrue

      public static boolean isWhileTrue(ICStatement stm)
      Check if a statement is a while loop, whose predicate is literal True.
    • isDoWhileTrue

      public static boolean isDoWhileTrue(ICStatement stm)
      Check if a statement is a do-while loop, whose predicate is literal True.
    • countAllSubElements

      public static int countAllSubElements(ICElement elem)
      Recursively count the total number of sub-elements in the given element (see ICElement.getSubElements()).
    • getFirstRealStatement

      public static ICStatement getFirstRealStatement(ICBlock b, int i)
      Get the next "real" statement to be executed in the block, starting at the given index inclusively.

      In particular, this method skips over:

      • the do { part of a do-while block
      • the while(true) { part of a while block
      • the if(true) { part of a conditional statement
      Note: label statements are not skipped over.
      Parameters:
      b -
      i - the index in the block, at which to start the search
      Returns:
      the next statement to be executed, or null if none were found
    • getFirstRealStatementEx

      public static ICStatement getFirstRealStatementEx(ICMethod m, ICStatement first)
      This method does two things:
      • locating the statement provided, and skipping over it (note: if it is a compound statement, the entire compound is skipped)
      • the next real statement that immediately follows is returned (see #getFirstRealStatement()).
      Examples:
       stm1;  // first
       while(true) {
         stm2;  // next
         ...
       
      Or:
       stm1;  // first
       do {
         stm2;  // next
         ...
       
      Or:
       if(...) {
         while(...) {  // first
            ...;
         }
       }
       stm2;  // next
       
      Parameters:
      m -
      first -
      Returns:
      the next statement to be executed, or null if none were found
    • canFallthrough

      public static boolean canFallthrough(ICStatement currentStmt, ICStatement fallthroughStmt, boolean ignoreBreak)
      Check if the current statement can fallthrough to the next statement, i.e. if the first one can redirect execution to the second one (directly or indirectly) when these two statements are next to each other. If the answer is false, the second statement can not possibly be executed once its predecessor has been executed.

      Note: this is a conservative analysis (= false is a correct result, while true might indicate an unknown case). In particular, if the fallthrough statement is a label or a compound statement, the answer is true.

      Parameters:
      currentStmt -
      fallthroughStmt - the statement immediately following the current statement in the block
      ignoreBreak - indicate that the break should be ignored (in particular, when not in loop or in a switch context)
      Returns:
    • getPreviouslyExecutedStatements

      public static List<ICStatement> getPreviouslyExecutedStatements(ICMethod m, ICStatement first)
      Attempt to retrieve the previously executed statements from a given statement.

      Note that there is no look up for goto and jump so the previous statement of a label will only be the previous instruction as seen in the method. This method returns null when previous statements are too complicated to retrieve.

      Parameters:
      m -
      first -
      Returns:
      the possible previously executed statements, null if none were found
    • getParentBlock

      public static ICStatement getParentBlock(ICMethod m, ICStatement b)
      Retrieve parent block or null if no parent was found (or processed statement is the top body of the ICMethod)
      Parameters:
      m - method to check
      b - statement to look for parent
      Returns:
      parent block, null if none were found
    • isBreakingFlow

      public static CUtil.BreakFlowStatus isBreakingFlow(ICStatement e)
    • getBreakingFlowResult

      public static CUtil.BreakFlowResult getBreakingFlowResult(ICStatement e)
      Indicate if next instruction will be executed. This is not an in-depth analysis, meaning that if there if a if (true) return; b = 2;, the method will return CUtil.BreakFlowStatus.BOTH (predicates are not examined, only branches and based on last instruction).
      Parameters:
      e -
      Returns:
    • lt

      public static ICOperation lt(ICMethod m, ICExpression a, ICExpression b)
    • le

      public static ICOperation le(ICMethod m, ICExpression a, ICExpression b)
    • gt

      public static ICOperation gt(ICMethod m, ICExpression a, ICExpression b)
    • ge

      public static ICOperation ge(ICMethod m, ICExpression a, ICExpression b)
    • eq

      public static ICOperation eq(ICMethod m, ICExpression a, ICExpression b)
    • ne

      public static ICOperation ne(ICMethod m, ICExpression a, ICExpression b)
    • andL

      public static ICOperation andL(ICMethod m, ICExpression a, ICExpression b)
    • orL

      public static ICOperation orL(ICMethod m, ICExpression a, ICExpression b)
    • notL

      public static ICExpression notL(ICMethod m, ICExpression a)
    • notLDeepReplace

      public static ICExpression notLDeepReplace(ICMethod m, ICExpression a)
    • resolveNotOperation

      public static ICExpression resolveNotOperation(ICMethod m, ICOperation e, ICElement parent)
    • andB

      public static ICOperation andB(ICMethod m, ICExpression a, ICExpression b)
    • orB

      public static ICOperation orB(ICMethod m, ICExpression a, ICExpression b)
    • xorB

      public static ICOperation xorB(ICMethod m, ICExpression a, ICExpression b)
    • notB

      public static ICExpression notB(ICMethod m, ICExpression a)
    • add

      public static ICOperation add(ICMethod m, ICExpression a, ICExpression b)
    • add

      public static ICOperation add(ICMethod m, ICExpression a, ICExpression b, ICExpression c)
    • sub

      public static ICOperation sub(ICMethod m, ICExpression a, ICExpression b)
    • mul

      public static ICOperation mul(ICMethod m, ICExpression a, ICExpression b)
    • div

      public static ICOperation div(ICMethod m, ICExpression a, ICExpression b)
    • rem

      public static ICOperation rem(ICMethod m, ICExpression a, ICExpression b)
    • shl

      public static ICOperation shl(ICMethod m, ICExpression a, ICExpression b)
    • shr

      public static ICOperation shr(ICMethod m, ICExpression a, ICExpression b)
    • ushr

      public static ICOperation ushr(ICMethod m, ICExpression a, ICExpression b)
    • isOperation

      public static boolean isOperation(ICExpression e, COperatorType... optypes)
    • getOperation

      public static COperatorType getOperation(ICExpression e, COperatorType... optypes)
    • getOperation

      public static COperatorType getOperation(ICOperation e, COperatorType... optypes)
    • replaceSubElementRecurse

      public static int replaceSubElementRecurse(ICElement elt, ICExpression oldElement, ICExpression newElement)
      Recursively replace sub-elements of an element , using equals() equality.
      Parameters:
      elt -
      oldElement -
      newElement -
      Returns:
      number of replacements done
    • getDefinition

      public static ICDecl getDefinition(ICElement element)
      Get the ICDecl possibly contained in a statement; either the statement itself, or the left-side of an assignment.
      Parameters:
      element -
      Returns:
      definition, null if it could not be retrieved
    • getDefinitionInitialValue

      public static ICElement getDefinitionInitialValue(ICElement element)
      Get the initial value of a defined variable, from its definition statement.
      Parameters:
      element -
      Returns:
      the initial value set to a defined variable, null if none
    • isDeclareAndAssign

      public static boolean isDeclareAndAssign(ICElement element)
    • visitICStatementDepthPost

      public static boolean visitICStatementDepthPost(ICVisitor visitor, ICBlock elt, int from, CVisitResults results)
    • visitICStatementDepthPost

      public static boolean visitICStatementDepthPost(ICVisitor visitor, ICStatement elt, CVisitResults results)
    • containsBreak

      public static boolean containsBreak(ICStatement stm)
    • containsLabel

      public static boolean containsLabel(ICStatement stm)
    • containsStatement

      public static boolean containsStatement(ICStatement stm, Class<? extends ICStatement> class_)