|
|
|
package win32api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"syscall"
|
|
|
|
"unsafe"
|
|
|
|
|
|
|
|
"golang.org/x/sys/windows"
|
|
|
|
)
|
|
|
|
|
|
|
|
func DuplicateTokenEx(hExistingToken HANDLE, dwDesiredAccess DWORD,
|
|
|
|
lpTokenAttributes uintptr, ImpersonationLevel int,
|
|
|
|
TokenType TOKEN_TYPE, phNewToken *TOKEN) error {
|
|
|
|
|
|
|
|
advapi32, err := syscall.LoadLibrary("advapi32.dll")
|
|
|
|
if err != nil {
|
|
|
|
return errors.New("Can't Load Advapi32 API")
|
|
|
|
}
|
|
|
|
defer syscall.FreeLibrary(advapi32)
|
|
|
|
Dup, err := syscall.GetProcAddress(syscall.Handle(advapi32), "DuplicateTokenEx")
|
|
|
|
if err != nil {
|
|
|
|
return errors.New("Can't Load WTSQueryUserToken API")
|
|
|
|
}
|
|
|
|
r, _, errno := syscall.Syscall6(uintptr(Dup), 6, uintptr(hExistingToken), uintptr(dwDesiredAccess), lpTokenAttributes, uintptr(ImpersonationLevel),
|
|
|
|
uintptr(TokenType), uintptr(unsafe.Pointer(phNewToken)))
|
|
|
|
if r == 0 {
|
|
|
|
return error(errno)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func CreateProcessAsUser(hToken TOKEN, lpApplicationName, lpCommandLine string,
|
|
|
|
lpProcessAttributes, lpThreadAttributes, bInheritHandles uintptr,
|
|
|
|
dwCreationFlags uint16, lpEnvironment HANDLE, lpCurrentDirectory string,
|
|
|
|
lpStartupInfo *StartupInfo, lpProcessInformation *ProcessInformation) error {
|
|
|
|
var (
|
|
|
|
commandLine uintptr = 0
|
|
|
|
workingDir uintptr = 0
|
|
|
|
)
|
|
|
|
advapi32, err := syscall.LoadLibrary("advapi32.dll")
|
|
|
|
if err != nil {
|
|
|
|
return errors.New("Can't Load Advapi32 API")
|
|
|
|
}
|
|
|
|
defer syscall.FreeLibrary(advapi32)
|
|
|
|
CPAU, err := syscall.GetProcAddress(syscall.Handle(advapi32), "CreateProcessAsUserW")
|
|
|
|
if err != nil {
|
|
|
|
return errors.New("Can't Load CreateProcessAsUserW API")
|
|
|
|
}
|
|
|
|
if len(lpCommandLine) > 0 {
|
|
|
|
commandLine = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpCommandLine)))
|
|
|
|
}
|
|
|
|
if len(lpCurrentDirectory) > 0 {
|
|
|
|
workingDir = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpCurrentDirectory)))
|
|
|
|
}
|
|
|
|
r, _, errno := syscall.Syscall12(uintptr(CPAU), 11, uintptr(hToken), uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpApplicationName))),
|
|
|
|
commandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, uintptr(dwCreationFlags), uintptr(lpEnvironment),
|
|
|
|
workingDir, uintptr(unsafe.Pointer(lpStartupInfo)), uintptr(unsafe.Pointer(lpProcessInformation)), 0)
|
|
|
|
if r == 0 {
|
|
|
|
return error(errno)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func GetTokenInformation(TokenHandle HANDLE, TokenInformationClass, TokenInformation,
|
|
|
|
TokenInformationLength uintptr, ReturnLength *uintptr) error {
|
|
|
|
advapi32, err := syscall.LoadLibrary("advapi32.dll")
|
|
|
|
if err != nil {
|
|
|
|
return errors.New("Can't Load Advapi32 API")
|
|
|
|
}
|
|
|
|
defer syscall.FreeLibrary(advapi32)
|
|
|
|
GTI, err := syscall.GetProcAddress(syscall.Handle(advapi32), "GetTokenInformation")
|
|
|
|
if err != nil {
|
|
|
|
return errors.New("Can't Load GetTokenInformation API")
|
|
|
|
}
|
|
|
|
if r, _, errno := syscall.Syscall6(uintptr(GTI), 5, uintptr(TokenHandle), TokenInformationClass,
|
|
|
|
TokenInformation, TokenInformationLength, uintptr(unsafe.Pointer(ReturnLength)), 0); r == 0 {
|
|
|
|
return error(errno)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|