Can Golang use VMP?
Closed this issue · 2 comments
Hello, are you familiar with golang? I tried to use VMP to protect Go code, but it can't recognize the correct marker address. Virtual protection doesn't work, but registration verification is working.there is a little similar to the binary structure of GO and rust. Seeing that you have implemented VMP in rust, so I came to consult.
my demo code:
package main
// #include <stdbool.h>
// #include <stdlib.h>
// #include "VMProtectSDK.h"
import "C"
import (
"fmt"
"unsafe"
)
func main() {
Cprotect := C.CString("protect")
defer C.free(unsafe.Pointer(Cprotect))
C.VMProtectBeginUltra(Cprotect)
//C.VMProtectBeginUltraLockByKey(Cprotect)
serial := "CMQz+nTnrgqB4OUBXAwCT9k40JM5qqVCQFSD4IAqega6C3KPidYeqE3iuVNelEbYYykEl2eTrzbjU424kGAsCz+Y478jMVfco6gVWoWDd+FwZrRU06dWdhkBzvzsVxnHmtdpN9An7pKEvH4RCEyqcc19WjBgas4TlSjOBUjXNMtx9txsGVev06nmgOUhx9gELi6R/e9xDMqhnK5Ys58jh52xTjuWUtw58qtRlJyMAnESC8YRH4awnnkOAOFsRqpwMJB2uRIgHjfdkhd5JFUDU1UHFFH8ASZ0w1ti464OSybPB9AmlP+2L/1+ZonvkID3bjHIHPG2Tr55BGE0nxDQ=="
fmt.Println("HWID: ", VMProtectGetCurrentHWID())
fmt.Println("Is Protected:", VMProtectIsProtected())
fmt.Println("SerialState:", GetSerialState(serial))
fmt.Println("User:", GetUser())
C.VMProtectEnd()
}
func VMProtectGetCurrentHWID() (hwid string) {
nSize := C.VMProtectGetCurrentHWID(nil, 0)
hw := new(C.char)
C.VMProtectGetCurrentHWID(hw, nSize)
hwid = C.GoString(hw)
return hwid
}
func VMProtectIsProtected() bool {
return bool(C.VMProtectIsProtected())
}
func GetSerialState(serial string) (state int) {
Cserial := C.CString(serial)
defer C.free(unsafe.Pointer(Cserial))
state = int(C.VMProtectSetSerialNumber(Cserial))
return state
}
func GetUser() (user string) {
var sd C.VMProtectSerialNumberData
C.VMProtectGetSerialNumberData(&sd, C.sizeof_VMProtectSerialNumberData)
for _, v := range sd.wUserName {
if v != 0 {
user += fmt.Sprintf("%c", v)
}
}
return user
}
I doubt it is possible to make it work without changes on vmprotect side, golang C function calls are not zero cost, and causes some conversions, such as allocation of zero-terminated strings from standard go strings, which vmprotect doesn't understand
In case of Rust it can be solved, for example see how i define marker in this repo, and even can be made more readable, as i do in https://github.com/CertainLach/vmprotect
But for golang i think you shouldn't use markers, and protect whole functions instead (And even then, i'm not sure how vmprotect will deal with custom calling convention/other quirks of golang compiler)
To ease manual function selection - you can make vmprotect select functions based on name, as i do here: https://github.com/CertainLach/vmprotect/blob/master/script.lua
And then name functions to protect accordingly