From f5d29ecf7e1a959859e0e139ca28371e9af6041b Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 3 Mar 2021 14:28:14 +0100 Subject: elevate: use ntdll functions from x/sys Signed-off-by: Jason A. Donenfeld --- elevate/loader.go | 6 ++--- elevate/shellexecute.go | 4 +-- elevate/syscall_windows.go | 59 --------------------------------------------- elevate/zsyscall_windows.go | 20 +++------------ 4 files changed, 8 insertions(+), 81 deletions(-) (limited to 'elevate') diff --git a/elevate/loader.go b/elevate/loader.go index 03f4e7c6..d474a007 100644 --- a/elevate/loader.go +++ b/elevate/loader.go @@ -13,14 +13,14 @@ import ( /* We could use the undocumented LdrFindEntryForAddress function instead, but that's undocumented, and we're trying * to be as rock-solid as possible here. */ -func findCurrentDataTableEntry() (entry *cLDR_DATA_TABLE_ENTRY, err error) { - peb := rtlGetCurrentPeb() +func findCurrentDataTableEntry() (entry *windows.LDR_DATA_TABLE_ENTRY, err error) { + peb := windows.RtlGetCurrentPeb() if peb == nil || peb.Ldr == nil { err = windows.ERROR_INVALID_ADDRESS return } for cur := peb.Ldr.InMemoryOrderModuleList.Flink; cur != &peb.Ldr.InMemoryOrderModuleList; cur = cur.Flink { - entry = (*cLDR_DATA_TABLE_ENTRY)(unsafe.Pointer(uintptr(unsafe.Pointer(cur)) - unsafe.Offsetof(cLDR_DATA_TABLE_ENTRY{}.InMemoryOrderLinks))) + entry = (*windows.LDR_DATA_TABLE_ENTRY)(unsafe.Pointer(uintptr(unsafe.Pointer(cur)) - unsafe.Offsetof(windows.LDR_DATA_TABLE_ENTRY{}.InMemoryOrderLinks))) if entry.DllBase == peb.ImageBaseAddress { return } diff --git a/elevate/shellexecute.go b/elevate/shellexecute.go index 81584f26..b681a8a7 100644 --- a/elevate/shellexecute.go +++ b/elevate/shellexecute.go @@ -107,9 +107,9 @@ func ShellExecute(program string, arguments string, directory string, show int32 } originalPath := dataTableEntry.FullDllName.Buffer explorerPath := windows.StringToUTF16Ptr(filepath.Join(windowsDirectory, "explorer.exe")) - rtlInitUnicodeString(&dataTableEntry.FullDllName, explorerPath) + windows.RtlInitUnicodeString(&dataTableEntry.FullDllName, explorerPath) defer func() { - rtlInitUnicodeString(&dataTableEntry.FullDllName, originalPath) + windows.RtlInitUnicodeString(&dataTableEntry.FullDllName, originalPath) runtime.KeepAlive(explorerPath) }() diff --git a/elevate/syscall_windows.go b/elevate/syscall_windows.go index f4f01b18..2c820083 100644 --- a/elevate/syscall_windows.go +++ b/elevate/syscall_windows.go @@ -17,70 +17,11 @@ type cBIND_OPTS3 struct { hwnd *uintptr } -type cUNICODE_STRING struct { - Length uint16 - MaximumLength uint16 - Buffer *uint16 -} - -type cLIST_ENTRY struct { - Flink *cLIST_ENTRY - Blink *cLIST_ENTRY -} - -/* The below three structs have several "reserved" members. These are of course well-known and extensively reverse- - * engineered, but the below shows only the documented and therefore stable fields from Microsoft's winternl.h header */ - -type cLDR_DATA_TABLE_ENTRY struct { - Reserved1 [2]uintptr - InMemoryOrderLinks cLIST_ENTRY - Reserved2 [2]uintptr - DllBase uintptr - Reserved3 [2]uintptr - FullDllName cUNICODE_STRING - Reserved4 [8]byte - Reserved5 [3]uintptr - Reserved6 uintptr - TimeDateStamp uint32 -} - -type cPEB_LDR_DATA struct { - Reserved1 [8]byte - Reserved2 [3]uintptr - InMemoryOrderModuleList cLIST_ENTRY -} - -type cPEB struct { - Reserved1 [2]byte - BeingDebugged byte - Reserved2 [1]byte - Reserved3 uintptr - ImageBaseAddress uintptr - Ldr *cPEB_LDR_DATA - ProcessParameters uintptr - Reserved4 [3]uintptr - AtlThunkSListPtr uintptr - Reserved5 uintptr - Reserved6 uint32 - Reserved7 uintptr - Reserved8 uint32 - AtlThunkSListPtr32 uint32 - Reserved9 [45]uintptr - Reserved10 [96]byte - PostProcessInitRoutine uintptr - Reserved11 [128]byte - Reserved12 [1]uintptr - SessionId uint32 -} - const ( cCLSCTX_LOCAL_SERVER = 4 cCOINIT_APARTMENTTHREADED = 2 ) -//sys rtlInitUnicodeString(destinationString *cUNICODE_STRING, sourceString *uint16) = ntdll.RtlInitUnicodeString -//sys rtlGetCurrentPeb() (peb *cPEB) = ntdll.RtlGetCurrentPeb - //sys coInitializeEx(reserved uintptr, coInit uint32) (ret error) = ole32.CoInitializeEx //sys coUninitialize() = ole32.CoUninitialize //sys coGetObject(name *uint16, bindOpts *cBIND_OPTS3, guid *windows.GUID, functionTable ***[0xffff]uintptr) (ret error) = ole32.CoGetObject diff --git a/elevate/zsyscall_windows.go b/elevate/zsyscall_windows.go index c7f71819..452c8cfc 100644 --- a/elevate/zsyscall_windows.go +++ b/elevate/zsyscall_windows.go @@ -38,27 +38,13 @@ func errnoErr(e syscall.Errno) error { } var ( - modntdll = windows.NewLazySystemDLL("ntdll.dll") modole32 = windows.NewLazySystemDLL("ole32.dll") - procRtlGetCurrentPeb = modntdll.NewProc("RtlGetCurrentPeb") - procRtlInitUnicodeString = modntdll.NewProc("RtlInitUnicodeString") - procCoGetObject = modole32.NewProc("CoGetObject") - procCoInitializeEx = modole32.NewProc("CoInitializeEx") - procCoUninitialize = modole32.NewProc("CoUninitialize") + procCoGetObject = modole32.NewProc("CoGetObject") + procCoInitializeEx = modole32.NewProc("CoInitializeEx") + procCoUninitialize = modole32.NewProc("CoUninitialize") ) -func rtlGetCurrentPeb() (peb *cPEB) { - r0, _, _ := syscall.Syscall(procRtlGetCurrentPeb.Addr(), 0, 0, 0, 0) - peb = (*cPEB)(unsafe.Pointer(r0)) - return -} - -func rtlInitUnicodeString(destinationString *cUNICODE_STRING, sourceString *uint16) { - syscall.Syscall(procRtlInitUnicodeString.Addr(), 2, uintptr(unsafe.Pointer(destinationString)), uintptr(unsafe.Pointer(sourceString)), 0) - return -} - func coGetObject(name *uint16, bindOpts *cBIND_OPTS3, guid *windows.GUID, functionTable ***[0xffff]uintptr) (ret error) { r0, _, _ := syscall.Syscall6(procCoGetObject.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bindOpts)), uintptr(unsafe.Pointer(guid)), uintptr(unsafe.Pointer(functionTable)), 0, 0) if r0 != 0 { -- cgit v1.2.3-59-g8ed1b