Pass structure with pointers to go memory in C code

Viewed 37

I'm relatively new in Go and studying how to operate with native API. Here is a particular example, need to verify that binary file is signed. For that, I want to use WinVerifyTrust windows API.

The problem: WinVerifyTrust supplies WINTRUST_DATA structure which contains a pointer to WINTRUST_FILE_INFO which in order contains a pointer to a string =)

As we know it is forbidden to pass a pointer to the memory which contains pointers to other go memory in C or syscall.

But I just need to do that. What needs to be done?

Here is a package which wraps function above https://github.com/itchio/ox/blob/master/winox/verifytrust_windows.go they do that in a forbidden way

winTrustData.FileOrCatalogOrBlobOrSgnrOrCert = uintptr(unsafe.Pointer(fileData))

trustErr := syscallex.WinVerifyTrust(syscall.Handle(0), &policyGUID, winTrustData)

it is not allowed to store uintptr to go object in the intermediate variable before passing to syscall

What I want to do os next:

winTrustFileInfoMemory := C.malloc(unsafe.Sizeof(windows.WinTrustFileInfo{}))
if winTrustFileInfoMemory == nil {
    return errors.New("out of memory")
}
defer C.free(winTrustFileInfoMemory)

winTrustFileInfo := (*windows.WinTrustFileInfo)(unsafe.Pointer(winTrustFileInfoMemory))
winTrustFileInfo.Size = uint32(unsafe.Sizeof(windows.WinTrustFileInfo{}))
....
winTrustData.FileOrCatalogOrBlobOrSgnrOrCert = unsafe.Pointer(winTrustFileInfoMemory)

but it looks really ugly, do we have an ability to somehow pin the memory or something like it?

0 Answers
Related