11import powershell
2+ private import semmle.code.powershell.dataflow.internal.DataFlowImplCommon
3+ private import semmle.code.powershell.dataflow.internal.DataFlowDispatch
4+ private import semmle.code.powershell.controlflow.CfgNodes
25
36abstract private class AbstractCall extends Ast {
47 abstract Expr getCommand ( ) ;
@@ -17,6 +20,9 @@ abstract private class AbstractCall extends Ast {
1720
1821 /** Gets the qualifier of this call, if any. */
1922 Expr getQualifier ( ) { none ( ) }
23+
24+ /** Gets a possible runtime target of this call. */
25+ abstract Function getATarget ( ) ;
2026}
2127
2228private class CmdCall extends AbstractCall instanceof Cmd {
@@ -27,6 +33,14 @@ private class CmdCall extends AbstractCall instanceof Cmd {
2733 final override Expr getArgument ( int i ) { result = Cmd .super .getArgument ( i ) }
2834
2935 final override Expr getNamedArgument ( string name ) { result = Cmd .super .getNamedArgument ( name ) }
36+
37+ final override Function getATarget ( ) {
38+ exists ( DataFlowCall call | call .asCall ( ) .( StmtNodes:: CmdCfgNode ) .getStmt ( ) = this |
39+ result .getBody ( ) = viableCallableLambda ( call , _) .asCfgScope ( )
40+ or
41+ result .getBody ( ) = getTarget ( call )
42+ )
43+ }
3044}
3145
3246private class InvokeMemberCall extends AbstractCall instanceof InvokeMemberExpr {
@@ -41,6 +55,14 @@ private class InvokeMemberCall extends AbstractCall instanceof InvokeMemberExpr
4155 final override Expr getQualifier ( ) { result = InvokeMemberExpr .super .getQualifier ( ) }
4256
4357 final override Expr getNamedArgument ( string name ) { none ( ) }
58+
59+ final override Function getATarget ( ) {
60+ exists ( DataFlowCall call | call .asCall ( ) .( ExprNodes:: InvokeMemberCfgNode ) .getExpr ( ) = this |
61+ result .getBody ( ) = viableCallableLambda ( call , _) .asCfgScope ( )
62+ or
63+ result .getBody ( ) = getTarget ( call )
64+ )
65+ }
4466}
4567
4668final class Call = AbstractCall ;
0 commit comments