unicorn-engine / unicorn

Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
http://www.unicorn-engine.org
GNU General Public License v2.0
7.33k stars 1.31k forks source link

syscall.LoadDLL("unicorn.dll") #1961

Closed ddkwork closed 4 weeks ago

ddkwork commented 4 weeks ago

After some reading of the source code, I couldn't find a complete list of exported functions for the compiled dll to use for dll binding, and the speed of cgo's compilation and the compilation parameters are mind-boggling. So please provide me with the full list of dll exported functions along with the structure, type etc of the formal parameter and I will try to bind the dll to improve the compilation speed of the go language bindings!

ddkwork commented 4 weeks ago

I have been created a demo:

package unicorn

import (
    "syscall"

    "github.com/ddkwork/golibrary/mylog"
)

func ArchSupported()        { procArchSupported.Call() }
func Close()                { procClose.Call() }
func ContextAlloc()         { procContextAlloc.Call() }
func ContextFree()          { procContextFree.Call() }
func ContextRegRead()       { procContextRegRead.Call() }
func ContextRegReadBatch()  { procContextRegReadBatch.Call() }
func ContextRegWrite()      { procContextRegWrite.Call() }
func ContextRegWriteBatch() { procContextRegWriteBatch.Call() }
func ContextRestore()       { procContextRestore.Call() }
func ContextSave()          { procContextSave.Call() }
func ContextSize()          { procContextSize.Call() }
func Ctl()                  { procCtl.Call() }
func EmuStart()             { procEmuStart.Call() }
func EmuStop()              { procEmuStop.Call() }
func Errno()                { procErrno.Call() }
func Free()                 { procFree.Call() }
func HookAdd()              { procHookAdd.Call() }
func HookDel()              { procHookDel.Call() }
func MemMap()               { procMemMap.Call() }
func MemMapPtr()            { procMemMapPtr.Call() }
func MemProtect()           { procMemProtect.Call() }
func MemRead()              { procMemRead.Call() }
func MemRegions()           { procMemRegions.Call() }
func MemUnmap()             { procMemUnmap.Call() }
func MemWrite()             { procMemWrite.Call() }
func MmioMap()              { procMmioMap.Call() }
func Open()                 { procOpen.Call() }
func Query()                { procQuery.Call() }
func RegRead()              { procRegRead.Call() }
func RegReadBatch()         { procRegReadBatch.Call() }
func RegWrite()             { procRegWrite.Call() }
func RegWriteBatch()        { procRegWriteBatch.Call() }
func StrError()             { procStrError.Call() }
func Version()              { procVersion.Call() }

var (
    dll                      = mylog.Check2(syscall.LoadDLL("unicorn.dll"))
    procArchSupported        = mylog.Check2(dll.FindProc("uc_arch_supported"))
    procClose                = mylog.Check2(dll.FindProc("uc_close"))
    procContextAlloc         = mylog.Check2(dll.FindProc("uc_context_alloc"))
    procContextFree          = mylog.Check2(dll.FindProc("uc_context_free"))
    procContextRegRead       = mylog.Check2(dll.FindProc("uc_context_reg_read"))
    procContextRegReadBatch  = mylog.Check2(dll.FindProc("uc_context_reg_read_batch"))
    procContextRegWrite      = mylog.Check2(dll.FindProc("uc_context_reg_write"))
    procContextRegWriteBatch = mylog.Check2(dll.FindProc("uc_context_reg_write_batch"))
    procContextRestore       = mylog.Check2(dll.FindProc("uc_context_restore"))
    procContextSave          = mylog.Check2(dll.FindProc("uc_context_save"))
    procContextSize          = mylog.Check2(dll.FindProc("uc_context_size"))
    procCtl                  = mylog.Check2(dll.FindProc("uc_ctl"))
    procEmuStart             = mylog.Check2(dll.FindProc("uc_emu_start"))
    procEmuStop              = mylog.Check2(dll.FindProc("uc_emu_stop"))
    procErrno                = mylog.Check2(dll.FindProc("uc_errno"))
    procFree                 = mylog.Check2(dll.FindProc("uc_free"))
    procHookAdd              = mylog.Check2(dll.FindProc("uc_hook_add"))
    procHookDel              = mylog.Check2(dll.FindProc("uc_hook_del"))
    procMemMap               = mylog.Check2(dll.FindProc("uc_mem_map"))
    procMemMapPtr            = mylog.Check2(dll.FindProc("uc_mem_map_ptr"))
    procMemProtect           = mylog.Check2(dll.FindProc("uc_mem_protect"))
    procMemRead              = mylog.Check2(dll.FindProc("uc_mem_read"))
    procMemRegions           = mylog.Check2(dll.FindProc("uc_mem_regions"))
    procMemUnmap             = mylog.Check2(dll.FindProc("uc_mem_unmap"))
    procMemWrite             = mylog.Check2(dll.FindProc("uc_mem_write"))
    procMmioMap              = mylog.Check2(dll.FindProc("uc_mmio_map"))
    procOpen                 = mylog.Check2(dll.FindProc("uc_open"))
    procQuery                = mylog.Check2(dll.FindProc("uc_query"))
    procRegRead              = mylog.Check2(dll.FindProc("uc_reg_read"))
    procRegReadBatch         = mylog.Check2(dll.FindProc("uc_reg_read_batch"))
    procRegWrite             = mylog.Check2(dll.FindProc("uc_reg_write"))
    procRegWriteBatch        = mylog.Check2(dll.FindProc("uc_reg_write_batch"))
    procStrError             = mylog.Check2(dll.FindProc("uc_strerror"))
    procVersion              = mylog.Check2(dll.FindProc("uc_version"))
)
package main

import (
    "strconv"
    "strings"
    "testing"

    "github.com/ddkwork/golibrary/stream"
)

func TestName(t *testing.T) {
    b := stream.NewBuffer("")
    b.WriteStringLn(`
package unicorn
import (
    "github.com/ddkwork/golibrary/mylog"
    "syscall"
)
`)
    procs := []string{}
    for _, name := range names {
        name = strings.ReplaceAll(name, " ", "")
        exportName := name
        name = strings.TrimPrefix(name, "uc_")
        name = stream.ToCamelUpper(name, false)
        if name == "Strerror" {
            name = "StrError"
        }
        procs = append(procs, "proc"+name+" = mylog.Check2(dll.FindProc("+strconv.Quote(exportName)+"))")
        name = "func " + name + "(){" + "proc" + name + ".Call()" + "}"
        b.WriteStringLn(name)
    }
    b.WriteStringLn("var (")
    b.WriteStringLn("dll = mylog.Check2(syscall.LoadDLL(\"unicorn.dll\"))")
    for _, proc := range procs {
        b.WriteStringLn(proc)
    }
    b.WriteStringLn(")")
    stream.WriteGoFile("tmp/bind_gen.go", b)
}

var names = []string{
    "uc_arch_supported           ",
    "uc_close                    ",
    "uc_context_alloc            ",
    "uc_context_free             ",
    "uc_context_reg_read         ",
    "uc_context_reg_read_batch   ",
    "uc_context_reg_write        ",
    "uc_context_reg_write_batch  ",
    "uc_context_restore          ",
    "uc_context_save             ",
    "uc_context_size             ",
    "uc_ctl                      ",
    "uc_emu_start                ",
    "uc_emu_stop                 ",
    "uc_errno                    ",
    "uc_free                     ",
    "uc_hook_add                 ",
    "uc_hook_del                 ",
    "uc_mem_map                  ",
    "uc_mem_map_ptr              ",
    "uc_mem_protect              ",
    "uc_mem_read                 ",
    "uc_mem_regions              ",
    "uc_mem_unmap                ",
    "uc_mem_write                ",
    "uc_mmio_map                 ",
    "uc_open                     ",
    "uc_query                    ",
    "uc_reg_read                 ",
    "uc_reg_read_batch           ",
    "uc_reg_write                ",
    "uc_reg_write_batch          ",
    "uc_strerror                 ",
    "uc_version                  ",
}