CertainLach/VMProtect-Rust-Example

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
}

截屏2022-01-31 20 08 34

截屏2022-01-31 20 09 24

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