-
Notifications
You must be signed in to change notification settings - Fork 3
/
advapi32.go
261 lines (236 loc) · 8.33 KB
/
advapi32.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// Copyright 2010 The win Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build windows
// +build windows
package win
import (
"errors"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"syscall"
"unsafe"
)
const KEY_READ REGSAM = 0x20019
const KEY_WRITE REGSAM = 0x20006
const (
HKEY_CLASSES_ROOT HKEY = 0x80000000
HKEY_CURRENT_USER HKEY = 0x80000001
HKEY_LOCAL_MACHINE HKEY = 0x80000002
HKEY_USERS HKEY = 0x80000003
HKEY_PERFORMANCE_DATA HKEY = 0x80000004
HKEY_CURRENT_CONFIG HKEY = 0x80000005
HKEY_DYN_DATA HKEY = 0x80000006
)
const (
LOGON_WITH_PROFILE = 1
LOGON_NETCREDENTIALS_ONLY = 2
)
const (
DISABLE_MAX_PRIVILEGE = 1
)
const (
ERROR_NO_MORE_ITEMS = 259
TokenPrimary = 1
TokenImpersonation = 2
)
type (
ACCESS_MASK uint32
HKEY HANDLE
REGSAM ACCESS_MASK
)
const (
REG_NONE uint64 = 0 // No value type
REG_SZ = 1 // Unicode nul terminated string
REG_EXPAND_SZ = 2 // Unicode nul terminated string
// (with environment variable references)
REG_BINARY = 3 // Free form binary
REG_DWORD = 4 // 32-bit number
REG_DWORD_LITTLE_ENDIAN = 4 // 32-bit number (same as REG_DWORD)
REG_DWORD_BIG_ENDIAN = 5 // 32-bit number
REG_LINK = 6 // Symbolic Link (unicode)
REG_MULTI_SZ = 7 // Multiple Unicode strings
REG_RESOURCE_LIST = 8 // Resource list in the resource map
REG_FULL_RESOURCE_DESCRIPTOR = 9 // Resource list in the hardware description
REG_RESOURCE_REQUIREMENTS_LIST = 10
REG_QWORD = 11 // 64-bit number
REG_QWORD_LITTLE_ENDIAN = 11 // 64-bit number (same as REG_QWORD)
)
var (
// Library
libadvapi32 *windows.LazyDLL
// Functions
regCloseKey *windows.LazyProc
regOpenKeyEx *windows.LazyProc
regQueryValueEx *windows.LazyProc
regEnumValue *windows.LazyProc
regSetValueEx *windows.LazyProc
createProcessAsUser *windows.LazyProc
createProcessWithToken *windows.LazyProc
createRestrictedToken *windows.LazyProc
impersonateLoggedOnUser *windows.LazyProc
regDisableReflectionKey *windows.LazyProc
regDeleteKeyEx *windows.LazyProc
)
func init() {
// Library
libadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
// Functions
regCloseKey = libadvapi32.NewProc("RegCloseKey")
regOpenKeyEx = libadvapi32.NewProc("RegOpenKeyExW")
regQueryValueEx = libadvapi32.NewProc("RegQueryValueExW")
regEnumValue = libadvapi32.NewProc("RegEnumValueW")
regSetValueEx = libadvapi32.NewProc("RegSetValueExW")
createProcessAsUser = libadvapi32.NewProc("CreateProcessAsUserW")
createProcessWithToken = libadvapi32.NewProc("CreateProcessWithTokenW")
createRestrictedToken = libadvapi32.NewProc("CreateRestrictedToken")
impersonateLoggedOnUser = libadvapi32.NewProc("ImpersonateLoggedOnUser")
regDisableReflectionKey = libadvapi32.NewProc("RegDisableReflectionKey")
regDeleteKeyEx = libadvapi32.NewProc("RegDeleteKeyExW")
}
func RegCloseKey(hKey HKEY) int32 {
ret, _, _ := syscall.Syscall(regCloseKey.Addr(), 1,
uintptr(hKey),
0,
0)
return int32(ret)
}
func RegOpenKeyEx(hKey HKEY, lpSubKey *uint16, ulOptions uint32, samDesired REGSAM, phkResult *HKEY) int32 {
ret, _, _ := syscall.Syscall6(regOpenKeyEx.Addr(), 5,
uintptr(hKey),
uintptr(unsafe.Pointer(lpSubKey)),
uintptr(ulOptions),
uintptr(samDesired),
uintptr(unsafe.Pointer(phkResult)),
0)
return int32(ret)
}
func RegQueryValueEx(hKey HKEY, lpValueName *uint16, lpReserved, lpType *uint32, lpData *byte, lpcbData *uint32) int32 {
ret, _, _ := syscall.Syscall6(regQueryValueEx.Addr(), 6,
uintptr(hKey),
uintptr(unsafe.Pointer(lpValueName)),
uintptr(unsafe.Pointer(lpReserved)),
uintptr(unsafe.Pointer(lpType)),
uintptr(unsafe.Pointer(lpData)),
uintptr(unsafe.Pointer(lpcbData)))
return int32(ret)
}
func RegEnumValue(hKey HKEY, index uint32, lpValueName *uint16, lpcchValueName *uint32, lpReserved, lpType *uint32, lpData *byte, lpcbData *uint32) int32 {
ret, _, _ := syscall.Syscall9(regEnumValue.Addr(), 8,
uintptr(hKey),
uintptr(index),
uintptr(unsafe.Pointer(lpValueName)),
uintptr(unsafe.Pointer(lpcchValueName)),
uintptr(unsafe.Pointer(lpReserved)),
uintptr(unsafe.Pointer(lpType)),
uintptr(unsafe.Pointer(lpData)),
uintptr(unsafe.Pointer(lpcbData)),
0)
return int32(ret)
}
func RegSetValueEx(hKey HKEY, lpValueName *uint16, lpReserved, lpDataType uint64, lpData *byte, cbData uint32) int32 {
ret, _, _ := syscall.Syscall6(regSetValueEx.Addr(), 6,
uintptr(hKey),
uintptr(unsafe.Pointer(lpValueName)),
uintptr(lpReserved),
uintptr(lpDataType),
uintptr(unsafe.Pointer(lpData)),
uintptr(cbData))
return int32(ret)
}
func RegDisableReflectionKey(hKey registry.Key) int32 {
ret, _, _ := syscall.Syscall(regDisableReflectionKey.Addr(), 1,
uintptr(hKey),
0, 0)
return int32(ret)
}
func RegDeleteKeyEx(hKey registry.Key, path string, desired uint32) error {
ret, _, _ := syscall.Syscall6(regDeleteKeyEx.Addr(), 4, uintptr(hKey),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))),
uintptr(desired), 0, 0, 0)
if ret != 0 {
return syscall.Errno(ret)
}
return nil
}
func CreateRestrictedToken(token windows.Token, flags int, disables, restricted []windows.SIDAndAttributes, delete []windows.LUIDAndAttributes) (windows.Token, error) {
var ds, rs, de uintptr
if len(disables) > 0 {
ds = uintptr(unsafe.Pointer(&disables[0]))
}
if len(restricted) > 0 {
rs = uintptr(unsafe.Pointer(&restricted[0]))
}
if len(delete) > 0 {
de = uintptr(unsafe.Pointer(&delete[0]))
}
var pInfo windows.Token
ret, _, err := syscall.Syscall9(createRestrictedToken.Addr(), 9, uintptr(token), uintptr(flags), uintptr(len(disables)), ds,
uintptr(len(delete)), de, uintptr(len(restricted)), rs, uintptr(unsafe.Pointer(&pInfo)))
if ret == 0 {
return pInfo, errors.New("Syscall9:" + err.Error())
}
return pInfo, nil
}
func CreateProcessWithToken(token windows.Token, logonFlags int, appName, cmdLine, curDir string, flags int, env *uint16, sInfo *windows.StartupInfo) (windows.ProcessInformation, error) {
var pInfo windows.ProcessInformation
an, err := syscall.UTF16PtrFromString(appName)
if err != nil {
return pInfo, errors.New("UTF16PtrFromString1:" + err.Error())
}
var cl, cd *uint16
if len(cmdLine) > 0 {
cl, err = syscall.UTF16PtrFromString(cmdLine)
if err != nil {
return pInfo, errors.New("UTF16PtrFromString2:" + err.Error())
}
}
if len(curDir) > 0 {
cd, err = syscall.UTF16PtrFromString(curDir)
if err != nil {
return pInfo, errors.New("UTF16PtrFromString3:" + err.Error())
}
}
ret, _, err := syscall.Syscall9(createProcessWithToken.Addr(), 9, uintptr(token), uintptr(logonFlags), uintptr(unsafe.Pointer(an)), uintptr(unsafe.Pointer(cl)),
uintptr(flags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(cd)), uintptr(unsafe.Pointer(sInfo)), uintptr(unsafe.Pointer(&pInfo)))
if ret == 0 {
return pInfo, errors.New("Syscall9:" + err.Error())
}
return pInfo, nil
}
func CreateProcessAsUser(token windows.Token, appName, cmdLine string, pAttr, tAttr uintptr, inherit bool, flags int,
env *uint16, curDir string, sInfo *windows.StartupInfo) (windows.ProcessInformation, error) {
var pInfo windows.ProcessInformation
an, err := syscall.UTF16PtrFromString(appName)
if err != nil {
return pInfo, errors.New("UTF16PtrFromString1:" + err.Error())
}
var cl, cd *uint16
if len(cmdLine) > 0 {
cl, err = syscall.UTF16PtrFromString(cmdLine)
if err != nil {
return pInfo, errors.New("UTF16PtrFromString2:" + err.Error())
}
}
if len(curDir) > 0 {
cd, err = syscall.UTF16PtrFromString(curDir)
if err != nil {
return pInfo, errors.New("UTF16PtrFromString3:" + err.Error())
}
}
ret, _, err := syscall.Syscall12(createProcessAsUser.Addr(), 11, uintptr(token), uintptr(unsafe.Pointer(an)), uintptr(unsafe.Pointer(cl)), pAttr, tAttr,
uintptr(BoolToBOOL(inherit)),
uintptr(flags),
uintptr(unsafe.Pointer(env)),
uintptr(unsafe.Pointer(cd)),
uintptr(unsafe.Pointer(sInfo)),
uintptr(unsafe.Pointer(&pInfo)), 0)
if ret == 0 {
return pInfo, errors.New("Syscall12:" + err.Error())
}
return pInfo, nil
}
func ImpersonateLoggedOnUser(token windows.Token) bool {
ret, _, _ := syscall.Syscall(impersonateLoggedOnUser.Addr(), 1, uintptr(token), 0, 0)
return ret != 0
}