Class CUtil
java.lang.Object
com.pnfsoftware.jeb.core.units.code.asm.decompiler.ast.CUtil
Utility methods to manipulate
AST elements
.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
static enum
Status of a flow breaker AST statement. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic ICOperation
add
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
add
(ICMethod m, ICExpression a, ICExpression b, ICExpression c) static ICOperation
andB
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
andL
(ICMethod m, ICExpression a, ICExpression b) static boolean
canFallthrough
(ICStatement currentStmt, ICStatement fallthroughStmt, boolean ignoreBreak) Check if the current statement can fallthrough to the next statement, i.e.static boolean
containsBreak
(ICStatement stm) static boolean
containsLabel
(ICStatement stm) static boolean
containsStatement
(ICStatement stm, Class<? extends ICStatement> class_) static int
countAllSubElements
(ICElement elem) Recursively count the total number of sub-elements in the given element (seeICElement.getSubElements()
).static ICOperation
div
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
eq
(ICMethod m, ICExpression a, ICExpression b) 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.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.static ICOperation
ge
(ICMethod m, ICExpression a, ICExpression b) static CUtil.BreakFlowResult
Indicate if next instruction will be executed.static Long
getConstantAsLong
(ICConstant<?> expr) Retrieve the value associated to anICConstant
as a Long.static ICDecl
getDefinition
(ICElement element) Get theICDecl
possibly contained in a statement; either the statement itself, or the left-side of an assignment.static ICElement
getDefinitionInitialValue
(ICElement element) Get the initial value of a defined variable, from its definition statement.static ICStatement
getFirstRealStatement
(ICBlock b, int i) Get the next "real" statement to be executed in the block, starting at the given index inclusively.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()
).static ICLabel
getGotoLabel
(ICStatement stm) Check if the statement is aICGoto
to return the label; else, return null.static ICLabel
Check if the statement follows the patternif(P){goto x;}
and if so, returnsx
.static COperatorType
getOperation
(ICExpression e, COperatorType... optypes) static COperatorType
getOperation
(ICOperation e, COperatorType... optypes) static ICStatement
Retrieve parent block or null if no parent was found (or processed statement is the top body of theICMethod
)static List<ICStatement>
Attempt to retrieve the previously executed statements from a given statement.static ICOperation
gt
(ICMethod m, ICExpression a, ICExpression b) static boolean
hasEmptyBranch
(ICIfStm stm) Check if a if-statement has an empty branch (including the default one).static boolean
static boolean
hasNoSideEffects
(ICElement elem) Check if anICElement
can not possibly modify variables.static CUtil.BreakFlowStatus
static boolean
isBreakTo
(ICStatement stm, ICLabel target) Check if the statement is aICBreak
to the given label.static boolean
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.static boolean
isDeclareAndAssign
(ICElement element) static boolean
isDoWhileTrue
(ICStatement stm) Check if a statement is a do-while loop, whose predicate is literal True.static boolean
isGotoTo
(ICStatement stm, ICLabel target) Check if the statement is aICGoto
to the given label.static boolean
isIfBranch
(ICStatement stm) Check if the statement follows the patternif(P){BRANCH;}
, whereBRANCH
is a sole branch instruction.static boolean
isIfElse
(ICStatement stm) Check if a statement is a if-statement with two blocks, including a default block.static boolean
isIfNoElse
(ICStatement stm) Check if a statement follows the patternif(P){ }[else if(...){}]*
, i.e.static boolean
Check if the element is aICConstantInteger
static boolean
isIntegerValue
(ICExpression expr, long value) Check if the element is aICConstantInteger
equals to the given value.static boolean
isOperation
(ICExpression e, COperatorType... optypes) static boolean
isPlainBreak
(ICStatement stm) Check if the statement is aICBreak
without label.static boolean
isWhileTrue
(ICStatement stm) Check if a statement is a while loop, whose predicate is literal True.static ICOperation
le
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
lt
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
mul
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
ne
(ICMethod m, ICExpression a, ICExpression b) static ICExpression
notB
(ICMethod m, ICExpression a) static ICExpression
notL
(ICMethod m, ICExpression a) static ICExpression
static ICOperation
orB
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
orL
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
rem
(ICMethod m, ICExpression a, ICExpression b) static int
replaceSubElementRecurse
(ICElement elt, ICExpression oldElement, ICExpression newElement) Recursively replace sub-elements of an element , using equals() equality.static ICExpression
resolveNotOperation
(ICMethod m, ICOperation e, ICElement parent) static ICOperation
shl
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
shr
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
sub
(ICMethod m, ICExpression a, ICExpression b) static ICOperation
ushr
(ICMethod m, ICExpression a, ICExpression b) static boolean
visitICStatementDepthPost
(ICVisitor visitor, ICBlock elt, int from, CVisitResults results) static boolean
visitICStatementDepthPost
(ICVisitor visitor, ICStatement elt, CVisitResults results) static ICOperation
xorB
(ICMethod m, ICExpression a, ICExpression b)
-
Constructor Details
-
CUtil
public CUtil()
-
-
Method Details
-
findParent
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, anICMethod
elt
- the element for which the first parent is to be found- Returns:
- the parent or null
-
isClassMethodField
-
isIntegerConstant
Check if the element is aICConstantInteger
-
isIntegerValue
Check if the element is aICConstantInteger
equals to the given value. -
getConstantAsLong
Retrieve the value associated to anICConstant
as a Long.- Parameters:
expr
-- Returns:
- constant value, null if none could be retrieved
-
hasNoSideEffects
Check if anICElement
can not possibly modify variables. This method is intended to be safe, e.g. it will return false onICCall
.- Parameters:
elem
-- Returns:
- true if no variables would be modified by executing the element, false otherwise
-
hasNoCall
- Parameters:
elem
-- Returns:
- true if no
ICCall
is done, false otherwise
-
getIfGotoTarget
Check if the statement follows the patternif(P){goto x;}
and if so, returnsx
.- Parameters:
stm
-- Returns:
- the label pointed by the goto if the statement follows the pattern, null otherwise
-
isIfBranch
Check if the statement follows the patternif(P){BRANCH;}
, whereBRANCH
is a sole branch instruction. -
hasEmptyBranch
Check if a if-statement has an empty branch (including the default one). -
isContainingLabel
Check if a statement contains a given label; compound statements are recursively processed to search for the label. -
isGotoTo
Check if the statement is aICGoto
to the given label. -
getGotoLabel
Check if the statement is aICGoto
to return the label; else, return null. -
isBreakTo
Check if the statement is aICBreak
to the given label. -
isPlainBreak
Check if the statement is aICBreak
without label. -
isIfElse
Check if a statement is a if-statement with two blocks, including a default block. -
flipIfElse
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 toif(!A){Y}else{X}}
.- Parameters:
stm
-of
-- Returns:
- success indicator
-
isIfNoElse
Check if a statement follows the patternif(P){ }[else if(...){}]*
, i.e. a if-statement with possibly multiple blocks but no defaultelse
block. -
isWhileTrue
Check if a statement is a while loop, whose predicate is literal True. -
isDoWhileTrue
Check if a statement is a do-while loop, whose predicate is literal True. -
countAllSubElements
Recursively count the total number of sub-elements in the given element (seeICElement.getSubElements()
). -
getFirstRealStatement
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
- 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
- the
-
getFirstRealStatementEx
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()
).
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 blockignoreBreak
- indicate that the break should be ignored (in particular, when not in loop or in a switch context)- Returns:
-
getPreviouslyExecutedStatements
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
Retrieve parent block or null if no parent was found (or processed statement is the top body of theICMethod
)- Parameters:
m
- method to checkb
- statement to look for parent- Returns:
- parent block, null if none were found
-
isBreakingFlow
-
getBreakingFlowResult
Indicate if next instruction will be executed. This is not an in-depth analysis, meaning that if there if aif (true) return; b = 2;
, the method will returnCUtil.BreakFlowStatus.BOTH
(predicates are not examined, only branches and based on last instruction).- Parameters:
e
-- Returns:
-
lt
-
le
-
gt
-
ge
-
eq
-
ne
-
andL
-
orL
-
notL
-
notLDeepReplace
-
resolveNotOperation
-
andB
-
orB
-
xorB
-
notB
-
add
-
add
-
sub
-
mul
-
div
-
rem
-
shl
-
shr
-
ushr
-
isOperation
-
getOperation
-
getOperation
-
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
Get theICDecl
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
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
-
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
-
containsLabel
-
containsStatement
-