func init() { var argc int32 cmd := syscall.GetCommandLine() argv, e := syscall.CommandLineToArgv(cmd, &argc) if e != 0 { return } defer syscall.LocalFree(uint32(uintptr(unsafe.Pointer(argv)))) Args = make([]string, argc) for i, v := range (*argv)[:argc] { Args[i] = string(syscall.UTF16ToString((*v)[:])) } }
// Decrypt converts the output from a call to ConvertFrom-SecureString // back to the original input string and returns it func Decrypt(input string) (string, error) { // first we decode the hexadecimal string into a raw slice of bytes data, err := hex.DecodeString(input) if err != nil { return "", err } inputBlob := blob{uint32(len(data)), &data[0]} outputBlob := blob{} err = unprotectData(uintptr(unsafe.Pointer(&inputBlob)), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outputBlob))) if err != nil { return "", fmt.Errorf("Failed to decrypt %s, error: &s", input, err) } defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(outputBlob.data))) a := outputBlob.getData() return syscall.UTF16ToString(a), nil }
// CommandLineToArgv wraps the Windows syscall to turn a commandline into an argument array. func CommandLineToArgv(commandLine string) ([]string, error) { var argc int32 argsPtr, err := syscall.UTF16PtrFromString(commandLine) if err != nil { return nil, err } argv, err := syscall.CommandLineToArgv(argsPtr, &argc) if err != nil { return nil, err } defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv)))) newArgs := make([]string, argc) for i, v := range (*argv)[:argc] { newArgs[i] = string(syscall.UTF16ToString((*v)[:])) } return newArgs, nil }
// Encrypt encrypts a string provided as input into a hexadecimal string // the output corresponds to the output of ConvertFrom-SecureString: func Encrypt(input string) (string, error) { // we need to convert UTF8 to UTF16 before sending it into CryptProtectData // to be compatible with the way powershell does it data, err := convertToUTF16(input) if err != nil { return "", err } inputBlob := blob{uint32(len(data)), &data[0]} outputBlob := blob{} err = protectData(uintptr(unsafe.Pointer(&inputBlob)), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outputBlob))) if err != nil { return "", fmt.Errorf("Failed to encrypt %s, error: %s", input, err) } defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(outputBlob.data))) output := outputBlob.getDataAsBytes() // the result is a slice of bytes, which we must encode into hexa // to match ConvertFrom-SecureString's output before returning it h := hex.EncodeToString([]byte(output)) return h, nil }