forked from brahma-adshonor/gohook
-
Notifications
You must be signed in to change notification settings - Fork 12
/
example3.go
139 lines (108 loc) · 2.74 KB
/
example3.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"fmt"
"github.com/brahma-adshonor/gohook"
)
type base struct {
id int
}
type advance struct {
base
name string
}
type who interface {
Id() int
}
//go:noinline
func (b *base) Id() int {
fmt.Printf("calling base.Id()\n")
return b.id
}
//go:noinline
func (a *advance) Name() string {
return fmt.Sprintf("%d@%s", a.Id(), a.name)
}
func MyId(a *base) int {
fmt.Printf("in fake MyId() base\n")
return MyIdTrampoline(a) + 1000
}
//go:noinline
func MyIdTrampoline(a *base) int {
fmt.Printf("abccccc")
fmt.Printf("abccccc")
fmt.Printf("abccccc")
fmt.Printf("abccccc")
for {
if a != nil {
fmt.Printf("bbbbbb")
} else {
fmt.Printf("cbbcbb")
}
}
return 233
}
func MyId2(a *advance) int {
fmt.Printf("in fake MyId() advance\n")
return MyIdTrampoline2(a) + 5000
}
//go:noinline
func MyIdTrampoline2(a *advance) int {
fmt.Printf("abccccc")
fmt.Printf("abccccc")
fmt.Printf("abccccc")
fmt.Printf("abccccc")
for {
if a != nil {
fmt.Printf("bbbbbb")
} else {
fmt.Printf("cbbcbb")
}
}
return 233
}
func get_id_from(v who) int {
return v.Id()
}
func main() {
a := &advance{base:base{id:23},name:"miliao"}
fmt.Printf("before hook advance, id:%d\n", a.Id())
fmt.Printf("before hook advance, id from interface:%d\n", get_id_from(a))
err := gohook.HookMethod(a, "Id", MyId2, MyIdTrampoline2)
if err != nil {
panic(fmt.Sprintf("Hook advance instance method failed:%s", err.Error()))
}
fmt.Printf("after hook advance, id:%d\n", a.Id())
fmt.Printf("after hook advance, id from interface:%d\n", get_id_from(a))
b := &base{id:333}
err2 := gohook.HookMethod(b, "Id", MyId, MyIdTrampoline)
if err2 != nil {
panic(fmt.Sprintf("Hook base instance method failed:%s", err2.Error()))
}
fmt.Printf("after hook base, id:%d\n", a.Id())
fmt.Printf("after hook base, id from interface:%d\n", get_id_from(a))
fmt.Printf("debug info:\n%s\n", gohook.ShowDebugInfo())
fmt.Printf("method value by value:%v, by type:%v\n", a.Id, (*advance).Id)
gohook.UnHookMethod(a, "Id")
gohook.UnHookMethod(b, "Id")
// (*advance.Id has the type of func(*advance)())
// (a.Id has the type of func()())
// so a.Id is a closure wrappiing 'a' as the first argument to function the advance.Id()
err3 := gohook.Hook((*advance).Id, MyId2, MyIdTrampoline2)
if err3 != nil {
panic(fmt.Sprintf("hook method by method type failed\n", err3.Error()))
}
fmt.Printf("after hook advance by method type, id:%d\n", a.Id())
err4 := gohook.Hook(a.Id, MyId2, MyIdTrampoline2)
if err4 != nil {
fmt.Printf("hook method by method value failed:%s\n", err4.Error())
}
fmt.Printf("debug info:\n%s\n", gohook.ShowDebugInfo())
call_base_id(b)
call_advance_id(a)
}
func call_advance_id(a *advance) {
a.Id()
}
func call_base_id(b *base) {
b.Id()
}