-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontext.go
More file actions
156 lines (143 loc) · 4.62 KB
/
context.go
File metadata and controls
156 lines (143 loc) · 4.62 KB
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package injector
import (
"bytes"
)
var (
saveContextX86 = [][]byte{{0x60}} // pushad
restoreContextX86 = [][]byte{{0x61}} // popad
saveContextFPX86 = [][]byte{
{0x9C}, // pushfd
{0x55}, // push ebp
{0x8B, 0xEC}, // mov ebp, esp
{0x81, 0xE4, 0xF0, 0xFF, 0xFF, 0xFF}, // and esp, 0xFFFFFFF0
{0x81, 0xEC, 0x00, 0x02, 0x00, 0x00}, // sub esp, 0x200
{0x0F, 0xAE, 0x04, 0x24}, // fxsave [esp]
}
restoreContextFPX86 = [][]byte{
{0x0F, 0xAE, 0x0C, 0x24}, // fxrstor [esp]
{0x8B, 0xE5}, // mov esp, ebp
{0x5D}, // pop ebp
{0x9D}, // popfd
}
saveContextX64 = [][]byte{
{0x50}, {0x53}, {0x51}, {0x52}, // push rax, rbx, rcx, rdx
{0x56}, {0x57}, {0x55}, {0x54}, // push rsi, rdi, rbp, rsp
{0x41, 0x50}, {0x41, 0x51}, // push r8, r9
{0x41, 0x52}, {0x41, 0x53}, // push r10, r11
{0x41, 0x54}, {0x41, 0x55}, // push r12, r13
{0x41, 0x56}, {0x41, 0x57}, // push r14, r15
}
restoreContextX64 = [][]byte{
{0x58}, {0x5B}, {0x59}, {0x5A}, // pop rax, rbx, rcx, rdx
{0x5E}, {0x5F}, {0x5D}, {0x5C}, // pop rsi, rdi, rbp, rsp
{0x41, 0x58}, {0x41, 0x59}, // pop r8, r9
{0x41, 0x5A}, {0x41, 0x5B}, // pop r10, r11
{0x41, 0x5C}, {0x41, 0x5D}, // pop r12, r13
{0x41, 0x5E}, {0x41, 0x5F}, // pop r14, r15
}
saveContextFPX64 = [][]byte{
{0x9C}, // pushfq
{0x55}, // push rbp
{0x48, 0x8B, 0xEC}, // mov rbp, rsp
{0x48, 0x83, 0xE4, 0xF0}, // and rsp, 0xFFFFFFFFFFFFFFF0
{0x48, 0x81, 0xEC, 0x00, 0x02, 0x00, 0x00}, // sub rsp, 0x200
{0x0F, 0xAE, 0x04, 0x24}, // fxsave [rsp]
}
restoreContextFPX64 = [][]byte{
{0x0F, 0xAE, 0x0C, 0x24}, // fxrstor [rsp]
{0x48, 0x8B, 0xE5}, // mov rsp, rbp
{0x5D}, // pop rbp
{0x9D}, // popfq
}
)
// for calculate the instruction size about save and
// restore context and with insert junk instruction
var (
reversedContextInst uint32
reversedCtxJunkInst uint32
)
func init() {
rsvCtxJunkInst := 0
rsvCtxJunkInst += len(mergeBytes(saveContextX64)) + len(mergeBytes(saveContextFPX64))
reversedContextInst = uint32(rsvCtxJunkInst) // #nosec G115
rsvCtxJunkInst += (len(saveContextX64) + len(saveContextFPX64)) * maxJunkInstShortSize
reversedCtxJunkInst = uint32(rsvCtxJunkInst) // #nosec G115
}
func (inj *Injector) saveContext() [][]byte {
if inj.opts.NotSaveContext || inj.opts.NoHookMode {
return nil
}
var (
save [][]byte
fp [][]byte
)
switch inj.arch {
case "386":
save = saveContextX86
fp = saveContextFPX86
case "amd64":
save = saveContextX64
fp = saveContextFPX64
}
inj.contextSeq = inj.rand.Perm(len(save))
insts := make([][]byte, 0, len(fp)+len(save))
for i := 0; i < len(fp); i++ {
insts = append(insts, bytes.Clone(fp[i]))
junk := inj.insertJunkInstShort()
if len(junk) > 0 {
insts = append(insts, junk)
}
}
for i := 0; i < len(save); i++ {
selected := save[inj.contextSeq[i]]
insts = append(insts, bytes.Clone(selected))
junk := inj.insertJunkInstShort()
if len(junk) > 0 {
insts = append(insts, junk)
}
}
return insts
}
func (inj *Injector) restoreContext() [][]byte {
if inj.opts.NotSaveContext || inj.opts.NoHookMode {
return nil
}
var (
restore [][]byte
fp [][]byte
)
switch inj.arch {
case "386":
restore = restoreContextX86
fp = restoreContextFPX86
case "amd64":
restore = restoreContextX64
fp = restoreContextFPX64
}
insts := make([][]byte, 0, len(fp)+len(restore))
for i := len(restore) - 1; i >= 0; i-- {
selected := restore[inj.contextSeq[i]]
insts = append(insts, bytes.Clone(selected))
junk := inj.insertJunkInstShort()
if len(junk) > 0 {
insts = append(insts, junk)
}
}
for i := 0; i < len(fp); i++ {
insts = append(insts, bytes.Clone(fp[i]))
junk := inj.insertJunkInstShort()
if len(junk) > 0 {
insts = append(insts, junk)
}
}
return insts
}
func (inj *Injector) calcReservedCtxInstSize() uint32 {
if inj.opts.NotSaveContext {
return 0
}
if inj.opts.NoJunkCode {
return reversedContextInst
}
return reversedCtxJunkInst
}