mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-05-19 18:58:03 +02:00
50 lines
1.1 KiB
Go
50 lines
1.1 KiB
Go
//go:build windows
|
|
|
|
package winapi
|
|
|
|
import (
|
|
"fmt"
|
|
"unsafe"
|
|
)
|
|
|
|
var (
|
|
procCryptUnprotectData = Crypt32.NewProc("CryptUnprotectData")
|
|
procLocalFree = Kernel32.NewProc("LocalFree")
|
|
)
|
|
|
|
// dataBlob mirrors the DPAPI DATA_BLOB struct.
|
|
type dataBlob struct {
|
|
cbData uint32
|
|
pbData *byte
|
|
}
|
|
|
|
func newBlob(d []byte) *dataBlob {
|
|
if len(d) == 0 {
|
|
return &dataBlob{}
|
|
}
|
|
return &dataBlob{pbData: &d[0], cbData: uint32(len(d))}
|
|
}
|
|
|
|
func (b *dataBlob) bytes() []byte {
|
|
d := make([]byte, b.cbData)
|
|
copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:])
|
|
return d
|
|
}
|
|
|
|
// DecryptDPAPI decrypts a DPAPI-protected blob using the current user's
|
|
// master key. It is the Windows counterpart to macOS/Linux os_crypt
|
|
// fallbacks and is called by crypto.DecryptDPAPI.
|
|
func DecryptDPAPI(ciphertext []byte) ([]byte, error) {
|
|
var out dataBlob
|
|
r, _, err := procCryptUnprotectData.Call(
|
|
uintptr(unsafe.Pointer(newBlob(ciphertext))),
|
|
0, 0, 0, 0, 0,
|
|
uintptr(unsafe.Pointer(&out)),
|
|
)
|
|
if r == 0 {
|
|
return nil, fmt.Errorf("CryptUnprotectData: %w", err)
|
|
}
|
|
defer procLocalFree.Call(uintptr(unsafe.Pointer(out.pbData)))
|
|
return out.bytes(), nil
|
|
}
|