使用系统调用调用mono-2.0-sgen.dll获得“不是有效的Win32应用程序”

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用系统调用调用mono-2.0-sgen.dll获得“不是有效的Win32应用程序”相关的知识,希望对你有一定的参考价值。

我想通过Go运行带有Mono Framework的HelloWorldConsole.exe。

所以我想调用mono-2.0-sgen.dll函数“mono_main”来执行exe。 mono-2.0-sgen.dll是MS Windows的可执行文件,see

但我收到错误“不是一个有效的Win32应用程序”

_ = os.Setenv("MONO_PATH", `monolibmono4.5;C:DEVHelloWorldConsoleHelloWorldConsoleinDebug`)
_ = os.Setenv("MONO_CFG_DIR", `"C:Program Files (x86)Monoetc"`)
_ = os.Setenv("MONO_CONFIG", `"C:Program Files (x86)Monoetcmonoconfig"`)

mono := `C:Program Files (x86)Monoinmono-2.0-sgen.dll`
app := `C:DEVHelloWorldConsoleHelloWorldConsoleinDebugHelloWorldConsole.exe`

fmt.Println("Execute")

var mod = syscall.NewLazyDLL(mono)
var proc = mod.NewProc("mono_main")

ret, _, _ := proc.Call(0,
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("mono.exe"))),
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(app)))  )

windows.NewLazySystemDLL相同的行为

dll := windows.NewLazySystemDLL(mono)
lazyProc := dll.NewProc("mono_main")
lazyProc.Call()

功能名称

mono-2.0-sgen.dll

完全错误:

panic: Failed to load C:Program Files (x86)Monoinmono-2.0-sgen.dll: %1 is **not a valid Win32 application**.
答案

%1 is not a valid Win32 application

错误%1 is not a valid Win32 application是来自Windows本身的Win32错误代码的描述。

Win32错误代码本身是0x000000C1 ERROR_BAD_EXE_FORMAT,请参阅docs.microsoft.com

BAD_EXE_FORMATmeans你在x64进程中调用x86 dll。您必须使用Go的x86变体,例如来自https://golang.org/dl/的go1.12.1.windows-386.zip。

现在必须将GOROOT和PATH更改为提取的bin文件夹,然后您就可以开始了。

Type of Arguments

当你调用mono_main时,你需要以正确的方式使用这个函数。如果你看看implementation,你会看到签名是int mono_main (int argc, char* argv[]);。 argc和argv是一个广泛使用的模式,请参阅here

Working Sample

func main() {
    _ = os.Setenv("MONO_PATH", `C:DEVHelloWorldConsoleHelloWorldConsoleinx86Debugmonolibmono4.5;C:DEVHelloWorldConsoleHelloWorldConsoleinx86Debug`)
    _ = os.Setenv("MONO_CFG_DIR", `C:DEVHelloWorhpm.goldConsoleHelloWorldConsoleinx86Debugmonoetc`)
    _ = os.Setenv("MONO_CONFIG", `C:DEVHelloWorldConsoleHelloWorldConsoleinx86Debugmonoetcmonoconfig`)

    _ = os.Chdir(`C:DEVHelloWorldConsoleHelloWorldConsoleinx86Debug`)

    mono := `C:DEVHelloWorldConsoleHelloWorldConsoleinx86Debugmonoinmono-2.0-sgen.dll`

    // https://github.com/mono/mono/blob/c5b88ec4f323f2bdb7c7d0a595ece28dae66579c/mcs/tools/mkbundle/template_main.c#L1
    dll := windows.NewLazySystemDLL(mono)
    lazyProc := dll.NewProc("mono_main")

    dotNetAssembly := []byte(`HelloWorldConsole.exe`)

    var argummentData [260]byte
    ptr := unsafe.Pointer(&argummentData)

    copy(argummentData[:], dotNetAssembly)

    args := [2]uintptr{0, uintptr(ptr)}

    _, _, _ = lazyProc.Call(2, uintptr(unsafe.Pointer(&args)))
}

以上是关于使用系统调用调用mono-2.0-sgen.dll获得“不是有效的Win32应用程序”的主要内容,如果未能解决你的问题,请参考以下文章

使用汇编代码调用系统调用

Linux系统调用跟我学(1)

系统调用和函数调用的区别

Linux 系统调用

使用 Ptrace 检索系统调用,在第一个之后停止

为啥我应该在我的代码中尽量减少系统调用的使用?