@@ -28,6 +28,10 @@ func ApplyMethod(target reflect.Type, methodName string, double interface{}) *Pa
2828 return create ().ApplyMethod (target , methodName , double )
2929}
3030
31+ func ApplyMethodFunc (target reflect.Type , methodName string , doubleFunc interface {}) * Patches {
32+ return create ().ApplyMethodFunc (target , methodName , doubleFunc )
33+ }
34+
3135func ApplyPrivateMethod (target reflect.Type , methodName string , double interface {}) * Patches {
3236 return create ().ApplyPrivateMethod (target , methodName , double )
3337}
@@ -52,6 +56,18 @@ func ApplyFuncVarSeq(target interface{}, outputs []OutputCell) *Patches {
5256 return create ().ApplyFuncVarSeq (target , outputs )
5357}
5458
59+ func ApplyFuncReturn (target interface {}, output ... interface {}) * Patches {
60+ return create ().ApplyFuncReturn (target , output ... )
61+ }
62+
63+ func ApplyMethodReturn (target interface {}, methodName string , output ... interface {}) * Patches {
64+ return create ().ApplyMethodReturn (target , methodName , output ... )
65+ }
66+
67+ func ApplyFuncVarReturn (target interface {}, output ... interface {}) * Patches {
68+ return create ().ApplyFuncVarReturn (target , output ... )
69+ }
70+
5571func create () * Patches {
5672 return & Patches {originals : make (map [uintptr ][]byte ), values : make (map [reflect.Value ]reflect.Value ), valueHolders : make (map [reflect.Value ]reflect.Value )}
5773}
@@ -75,6 +91,15 @@ func (this *Patches) ApplyMethod(target reflect.Type, methodName string, double
7591 return this .ApplyCore (m .Func , d )
7692}
7793
94+ func (this * Patches ) ApplyMethodFunc (target reflect.Type , methodName string , doubleFunc interface {}) * Patches {
95+ m , ok := target .MethodByName (methodName )
96+ if ! ok {
97+ panic ("retrieve method by name failed" )
98+ }
99+ d := funcToMethod (m .Type , doubleFunc )
100+ return this .ApplyCore (m .Func , d )
101+ }
102+
78103func (this * Patches ) ApplyPrivateMethod (target reflect.Type , methodName string , double interface {}) * Patches {
79104 m , ok := creflect .MethodByName (target , methodName )
80105 if ! ok {
@@ -136,6 +161,40 @@ func (this *Patches) ApplyFuncVarSeq(target interface{}, outputs []OutputCell) *
136161 return this .ApplyGlobalVar (target , double )
137162}
138163
164+ func (this * Patches ) ApplyFuncReturn (target interface {}, returns ... interface {}) * Patches {
165+ funcType := reflect .TypeOf (target )
166+ t := reflect .ValueOf (target )
167+ outputs := []OutputCell {{Values : returns , Times : - 1 }}
168+ d := getDoubleFunc (funcType , outputs )
169+ return this .ApplyCore (t , d )
170+ }
171+
172+ func (this * Patches ) ApplyMethodReturn (target interface {}, methodName string , returns ... interface {}) * Patches {
173+ m , ok := reflect .TypeOf (target ).MethodByName (methodName )
174+ if ! ok {
175+ panic ("retrieve method by name failed" )
176+ }
177+
178+ outputs := []OutputCell {{Values : returns , Times : - 1 }}
179+ d := getDoubleFunc (m .Type , outputs )
180+ return this .ApplyCore (m .Func , d )
181+ }
182+
183+ func (this * Patches ) ApplyFuncVarReturn (target interface {}, returns ... interface {}) * Patches {
184+ t := reflect .ValueOf (target )
185+ if t .Type ().Kind () != reflect .Ptr {
186+ panic ("target is not a pointer" )
187+ }
188+ if t .Elem ().Kind () != reflect .Func {
189+ panic ("target is not a func" )
190+ }
191+
192+ funcType := reflect .TypeOf (target ).Elem ()
193+ outputs := []OutputCell {{Values : returns , Times : - 1 }}
194+ double := getDoubleFunc (funcType , outputs ).Interface ()
195+ return this .ApplyGlobalVar (target , double )
196+ }
197+
139198func (this * Patches ) Reset () {
140199 for target , bytes := range this .originals {
141200 modifyBinary (target , bytes )
@@ -203,8 +262,14 @@ func getDoubleFunc(funcType reflect.Type, outputs []OutputCell) reflect.Value {
203262 funcType .NumOut (), len (outputs [0 ].Values )))
204263 }
205264
265+ needReturn := false
206266 slice := make ([]Params , 0 )
207267 for _ , output := range outputs {
268+ if output .Times == - 1 {
269+ needReturn = true
270+ slice = []Params {output .Values }
271+ break
272+ }
208273 t := 0
209274 if output .Times <= 1 {
210275 t = 1
@@ -217,9 +282,12 @@ func getDoubleFunc(funcType reflect.Type, outputs []OutputCell) reflect.Value {
217282 }
218283
219284 i := 0
220- len := len (slice )
285+ lenOutputs := len (slice )
221286 return reflect .MakeFunc (funcType , func (_ []reflect.Value ) []reflect.Value {
222- if i < len {
287+ if needReturn {
288+ return GetResultValues (funcType , slice [0 ]... )
289+ }
290+ if i < lenOutputs {
223291 i ++
224292 return GetResultValues (funcType , slice [i - 1 ]... )
225293 }
@@ -259,3 +327,14 @@ func entryAddress(p uintptr, l int) []byte {
259327func pageStart (ptr uintptr ) uintptr {
260328 return ptr & ^ (uintptr (syscall .Getpagesize () - 1 ))
261329}
330+
331+ func funcToMethod (funcType reflect.Type , doubleFunc interface {}) reflect.Value {
332+ rf := reflect .TypeOf (doubleFunc )
333+ if rf .Kind () != reflect .Func {
334+ panic ("doubleFunc is not a func" )
335+ }
336+ vf := reflect .ValueOf (doubleFunc )
337+ return reflect .MakeFunc (funcType , func (in []reflect.Value ) []reflect.Value {
338+ return vf .Call (in [1 :])
339+ })
340+ }
0 commit comments