github.com/google/osv-scalibr@v0.4.1/detector/weakcredentials/winlocal/win32_windows.go (about) 1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build windows 16 17 package winlocal 18 19 import ( 20 "errors" 21 "syscall" 22 "unsafe" 23 24 "golang.org/x/sys/windows" 25 ) 26 27 var ( 28 advapiDLL = syscall.NewLazyDLL("Advapi32.dll") 29 regSaveKeyEx = advapiDLL.NewProc("RegSaveKeyExW") 30 ) 31 32 func securityAttributesFromSDDL(sddl string) (*windows.SecurityAttributes, error) { 33 if sddl == "" { 34 return nil, nil 35 } 36 37 sd, err := windows.SecurityDescriptorFromString(sddl) 38 if err != nil { 39 return nil, err 40 } 41 42 sa := &windows.SecurityAttributes{ 43 Length: uint32(unsafe.Sizeof(windows.SecurityAttributes{})), 44 SecurityDescriptor: sd, 45 InheritHandle: 0, 46 } 47 48 return sa, nil 49 } 50 51 // RegSaveKey wraps the `RegSaveKeyExW` Win32 API to save a registry key to a file. 52 // 53 // Note: sddl is optional. If empty, the security attribute will be null and the file will get a 54 // default security descriptor. 55 // 56 // https://learn.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regsavekeyexw 57 // 58 // LSTATUS RegSaveKeyExW( 59 // 60 // [in] HKEY hKey, 61 // [in] LPCWSTR lpFile, 62 // [in, optional] const LPSECURITY_ATTRIBUTES lpSecurityAttributes, 63 // [in] DWORD Flags 64 // 65 // ); 66 func RegSaveKey(key syscall.Handle, path string, sddl string) error { 67 if regSaveKeyEx == nil { 68 return errors.New("cannot find RegSaveKeyExW in Advapi32.dll") 69 } 70 71 securityAttributes, err := securityAttributesFromSDDL(sddl) 72 if err != nil { 73 return err 74 } 75 76 p, err := syscall.UTF16PtrFromString(path) 77 if err != nil { 78 return err 79 } 80 81 // Note: we enforce the `Flags` parameter to be 1 (REG_STANDARD_FORMAT) to always use the standard 82 // registry format. 83 flags := uintptr(1) 84 hKey := uintptr(key) 85 lpFile := uintptr(unsafe.Pointer(p)) 86 lpSecurityAttributes := uintptr(unsafe.Pointer(securityAttributes)) 87 88 if ret, _, _ := regSaveKeyEx.Call(hKey, lpFile, lpSecurityAttributes, flags); ret != 0 { 89 return syscall.Errno(ret) 90 } 91 92 return nil 93 }