diff --git a/advapi32.go b/advapi32.go new file mode 100644 index 0000000..31088ca --- /dev/null +++ b/advapi32.go @@ -0,0 +1,79 @@ +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, _, err := syscall.Syscall6(uintptr(Dup), 6, uintptr(hExistingToken), uintptr(dwDesiredAccess), lpTokenAttributes, uintptr(ImpersonationLevel), + uintptr(TokenType), uintptr(unsafe.Pointer(phNewToken))) + if r == 0 { + return err + } + 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, _, err := 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 err + } + 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, _, err := syscall.Syscall6(uintptr(GTI), 5, uintptr(TokenHandle), TokenInformationClass, + TokenInformation, TokenInformationLength, uintptr(unsafe.Pointer(ReturnLength)), 0); r == 0 { + return err + } + return nil +} diff --git a/advapi32typedef.go b/advapi32typedef.go new file mode 100644 index 0000000..34ef277 --- /dev/null +++ b/advapi32typedef.go @@ -0,0 +1,5 @@ +package win32api + +type TOKEN_LINKED_TOKEN struct { + LinkedToken TOKEN +} diff --git a/kernel32.go b/kernel32.go new file mode 100644 index 0000000..b19bfc0 --- /dev/null +++ b/kernel32.go @@ -0,0 +1,36 @@ +package win32api + +import ( + "errors" + "syscall" +) + +func WTSGetActiveConsoleSessionId() (DWORD, error) { + kernel32, err := syscall.LoadLibrary("kernel32.dll") + if err != nil { + return 0, errors.New("Can't Load Kernel32 API") + } + defer syscall.FreeLibrary(kernel32) + WTGet, err := syscall.GetProcAddress(syscall.Handle(kernel32), "WTSGetActiveConsoleSessionId") + if err != nil { + return 0, errors.New("Can't Load WTSGetActiveConsoleSessionId API") + } + res, _, _ := syscall.Syscall(uintptr(WTGet), 0, 0, 0, 0) + return DWORD(res), nil +} + +func CloseHandle(hObject HANDLE) error { + kernel32, err := syscall.LoadLibrary("kernel32.dll") + if err != nil { + return errors.New("Can't Load Kernel32 API") + } + defer syscall.FreeLibrary(kernel32) + CH, err := syscall.GetProcAddress(syscall.Handle(kernel32), "CloseHandle") + if err != nil { + return errors.New("Can't Load CloseHandle API") + } + if r, _, err := syscall.Syscall(uintptr(CH), 1, uintptr(hObject), 0, 0); r == 0 { + return err + } + return nil +} diff --git a/userenv.go b/userenv.go new file mode 100644 index 0000000..bcae2f4 --- /dev/null +++ b/userenv.go @@ -0,0 +1,32 @@ +package win32api + +import ( + "errors" + "syscall" + "unsafe" +) + +/* +BOOL CreateEnvironmentBlock( + LPVOID *lpEnvironment, + HANDLE hToken, + BOOL bInherit +); +*/ + +func CreateEnvironmentBlock(lpEnvironment *HANDLE, hToken TOKEN, bInherit uintptr) error { + userenv, err := syscall.LoadLibrary("userenv.dll") + if err != nil { + return errors.New("Can't Load Userenv API") + } + defer syscall.FreeLibrary(userenv) + Dup, err := syscall.GetProcAddress(syscall.Handle(userenv), "CreateEnvironmentBlock") + if err != nil { + return errors.New("Can't Load WTSQueryUserToken API") + } + r, _, err := syscall.Syscall6(uintptr(Dup), 3, uintptr(unsafe.Pointer(lpEnvironment)), uintptr(hToken), bInherit, 0, 0, 0) + if r == 0 { + return err + } + return nil +} diff --git a/win32api.go b/win32api.go index 8dc327d..4240307 100644 --- a/win32api.go +++ b/win32api.go @@ -1,49 +1,137 @@ package win32api -import "unsafe" +import ( + "unsafe" +) type ( - ATOM uint16 - BOOL int32 - COLORREF uint32 - DWM_FRAME_COUNT uint64 - DWORD uint32 - HACCEL HANDLE - HANDLE uintptr - HBITMAP HANDLE - HBRUSH HANDLE - HCURSOR HANDLE - HDC HANDLE - HDROP HANDLE - HDWP HANDLE - HENHMETAFILE HANDLE - HFONT HANDLE - HGDIOBJ HANDLE - HGLOBAL HANDLE - HGLRC HANDLE - HHOOK HANDLE - HICON HANDLE - HIMAGELIST HANDLE - HINSTANCE HANDLE - HKEY HANDLE - HKL HANDLE - HMENU HANDLE - HMODULE HANDLE - HMONITOR HANDLE - HPEN HANDLE - HRESULT int32 - HRGN HANDLE - HRSRC HANDLE - HTHUMBNAIL HANDLE - HWND HANDLE - LPARAM uintptr - LPCVOID unsafe.Pointer - LPVOID unsafe.Pointer - LRESULT uintptr - PVOID unsafe.Pointer - QPC_TIME uint64 - ULONG uint32 - ULONG_PTR uintptr - WPARAM uintptr - TRACEHANDLE uintptr + ATOM uint16 + BOOL int32 + COLORREF uint32 + DWM_FRAME_COUNT uint64 + DWORD uint32 + HACCEL HANDLE + HANDLE uintptr + HBITMAP HANDLE + HBRUSH HANDLE + HCURSOR HANDLE + HDC HANDLE + HDROP HANDLE + HDWP HANDLE + HENHMETAFILE HANDLE + HFONT HANDLE + HGDIOBJ HANDLE + HGLOBAL HANDLE + HGLRC HANDLE + HHOOK HANDLE + HICON HANDLE + HIMAGELIST HANDLE + HINSTANCE HANDLE + HKEY HANDLE + HKL HANDLE + HMENU HANDLE + HMODULE HANDLE + HMONITOR HANDLE + HPEN HANDLE + HRESULT int32 + HRGN HANDLE + HRSRC HANDLE + HTHUMBNAIL HANDLE + HWND HANDLE + LPARAM uintptr + LPCVOID unsafe.Pointer + LPVOID unsafe.Pointer + LRESULT uintptr + PVOID unsafe.Pointer + QPC_TIME uint64 + ULONG uint32 + ULONG_PTR uintptr + WPARAM uintptr + WTS_CONNECTSTATE_CLASS int + TRACEHANDLE uintptr + TOKEN HANDLE + TOKEN_TYPE int + SW int + SECURITY_IMPERSONATION_LEVEL int +) + +type WTS_SESSION_INFO struct { + SessionID HANDLE + WinStationName *uint16 + State WTS_CONNECTSTATE_CLASS +} + +const ( + WTS_CURRENT_SERVER_HANDLE uintptr = 0 +) +const ( + WTSActive WTS_CONNECTSTATE_CLASS = iota + WTSConnected + WTSConnectQuery + WTSShadow + WTSDisconnected + WTSIdle + WTSListen + WTSReset + WTSDown + WTSInit +) +const ( + SecurityAnonymous SECURITY_IMPERSONATION_LEVEL = iota + SecurityIdentification + SecurityImpersonation + SecurityDelegation ) +const ( + TokenPrimary TOKEN_TYPE = iota + 1 + TokenImpersonazion +) +const ( + SW_HIDE SW = 0 + SW_SHOWNORMAL = 1 + SW_NORMAL = 1 + SW_SHOWMINIMIZED = 2 + SW_SHOWMAXIMIZED = 3 + SW_MAXIMIZE = 3 + SW_SHOWNOACTIVATE = 4 + SW_SHOW = 5 + SW_MINIMIZE = 6 + SW_SHOWMINNOACTIVE = 7 + SW_SHOWNA = 8 + SW_RESTORE = 9 + SW_SHOWDEFAULT = 10 + SW_MAX = 1 +) +const ( + CREATE_UNICODE_ENVIRONMENT uint16 = 0x00000400 + CREATE_NO_WINDOW = 0x08000000 + CREATE_NEW_CONSOLE = 0x00000010 +) + +type StartupInfo struct { + Cb uint32 + _ *uint16 + Desktop *uint16 + Title *uint16 + X uint32 + Y uint32 + XSize uint32 + YSize uint32 + XCountChars uint32 + YCountChars uint32 + FillAttribute uint32 + Flags uint32 + ShowWindow uint16 + _ uint16 + _ *byte + StdInput HANDLE + StdOutput HANDLE + StdErr HANDLE +} + +type ProcessInformation struct { + Process HANDLE + Thread HANDLE + ProcessId uint32 + ThreadId uint32 +} diff --git a/wtsapi32.go b/wtsapi32.go new file mode 100644 index 0000000..8962e6b --- /dev/null +++ b/wtsapi32.go @@ -0,0 +1,42 @@ +package win32api + +import ( + "errors" + "syscall" + "unsafe" +) + +func WTSQueryUserToken(SessionId HANDLE, phToken *HANDLE) error { + wtsapi32, err := syscall.LoadLibrary("wtsapi32.dll") + if err != nil { + return errors.New("Can't Load Wtsapi32 API") + } + defer syscall.FreeLibrary(wtsapi32) + WTGet, err := syscall.GetProcAddress(syscall.Handle(wtsapi32), "WTSQueryUserToken") + if err != nil { + return errors.New("Can't Load WTSQueryUserToken API") + } + r, _, err := syscall.Syscall(uintptr(WTGet), 2, uintptr(SessionId), uintptr(unsafe.Pointer(phToken)), 0) + if r == 0 { + return err + } else { + return nil + } +} + +func WTSEnumerateSessions(hServer HANDLE, Reserved, Version DWORD, ppSessionInfo *HANDLE, pCount *int) error { + wtsapi32, err := syscall.LoadLibrary("wtsapi32.dll") + if err != nil { + return errors.New("Can't Load Wtsapi32 API") + } + defer syscall.FreeLibrary(wtsapi32) + WT, err := syscall.GetProcAddress(syscall.Handle(wtsapi32), "WTSEnumerateSessionsW") + if err != nil { + return errors.New("Can't Load WTSQueryUserToken API") + } + r, _, err := syscall.Syscall6(uintptr(WT), 5, uintptr(hServer), uintptr(Reserved), uintptr(Version), uintptr(unsafe.Pointer(ppSessionInfo)), uintptr(unsafe.Pointer(pCount)), 0) + if r == 0 { + return err + } + return nil +}