11private import powershell
22private import semmle.code.powershell.Cfg
33private import DataFlowPrivate
4+ private import DataFlowPublic
5+ private import semmle.code.powershell.typetracking.internal.TypeTrackingImpl
46private import codeql.util.Boolean
57private import codeql.util.Unit
68
@@ -123,11 +125,47 @@ class NormalCall extends DataFlowCall, TNormalCall {
123125/** A call for which we want to compute call targets. */
124126private class RelevantCall extends CfgNodes:: CallCfgNode { }
125127
126- /** Holds if `call` may resolve to the returned source-code method. */
127- private DataFlowCallable viableSourceCallable ( DataFlowCall call ) {
128- none ( ) // TODO
129- or
130- result = any ( AdditionalCallTarget t ) .viableTarget ( call .asCall ( ) )
128+ private module TrackInstanceInput implements CallGraphConstruction:: InputSig {
129+ newtype State = additional MkState ( Type m , Boolean exact )
130+
131+ predicate start ( Node start , State state ) {
132+ exists ( Type tp , boolean exact | state = MkState ( tp , exact ) |
133+ start .asExpr ( ) .( CfgNodes:: ExprNodes:: ConstructorCallCfgNode ) .getConstructedType ( ) = tp
134+ )
135+ }
136+
137+ pragma [ nomagic]
138+ predicate stepNoCall ( Node nodeFrom , Node nodeTo , StepSummary summary ) {
139+ smallStepNoCall ( nodeFrom , nodeTo , summary )
140+ }
141+
142+ predicate stepCall ( Node nodeFrom , Node nodeTo , StepSummary summary ) {
143+ smallStepCall ( nodeFrom , nodeTo , summary )
144+ }
145+
146+ class StateProj = Unit ;
147+
148+ Unit stateProj ( State state ) { exists ( state ) and exists ( result ) }
149+
150+ predicate filter ( Node n , Unit u ) { none ( ) }
151+ }
152+
153+ private predicate qualifiedCall ( CfgNodes:: CallCfgNode call , Node receiver , string method ) {
154+ call .getQualifier ( ) = receiver .asExpr ( ) and
155+ call .getName ( ) = method
156+ }
157+
158+ private Node trackInstance ( Type t , boolean exact ) {
159+ result =
160+ CallGraphConstruction:: Make< TrackInstanceInput > :: track ( TrackInstanceInput:: MkState ( t , exact ) )
161+ }
162+
163+ private CfgScope getTargetInstance ( CfgNodes:: CallCfgNode call ) {
164+ exists ( Node receiver , string method , Type t |
165+ qualifiedCall ( call , receiver , method ) and
166+ receiver = trackInstance ( t , _) and
167+ result = t .getMemberFunction ( method ) .getBody ( )
168+ )
131169}
132170
133171/**
@@ -154,7 +192,14 @@ private module Cached {
154192
155193 /** Gets a viable run-time target for the call `call`. */
156194 cached
157- DataFlowCallable viableCallable ( DataFlowCall call ) { result = viableSourceCallable ( call ) }
195+ DataFlowCallable viableCallable ( DataFlowCall call ) {
196+ result .asCfgScope ( ) = getTargetInstance ( call .asCall ( ) )
197+ or
198+ result = any ( AdditionalCallTarget t ) .viableTarget ( call .asCall ( ) )
199+ }
200+
201+ cached
202+ CfgScope getTarget ( DataFlowCall call ) { result = viableCallable ( call ) .asCfgScope ( ) }
158203
159204 cached
160205 newtype TArgumentPosition =
0 commit comments