### Install go-clr Package Source: https://github.com/atsika/go-clr/blob/master/README.md This command installs the go-clr package, making it available for use as a dependency in other Go projects. No specific input or output is directly shown, but it ensures the package is available in the Go module cache. ```bash go get github.com/ropnop/go-clr ``` -------------------------------- ### Get Installed CLR Runtimes in Go Source: https://context7.com/atsika/go-clr/llms.txt Enumerates all .NET Framework runtime versions installed on the system using the go-clr library. It requires the 'github.com/ropnop/go-clr' package and outputs a list of detected runtime versions. ```go package main import ( "fmt" "log" clr "github.com/ropnop/go-clr" ) func main() { // Create CLR metahost interface metahost, err := clr.CLRCreateInstance( clr.CLSID_CLRMetaHost, clr.IID_ICLRMetaHost) if err != nil { log.Fatal(err) } defer metahost.Release() // Enumerate installed runtimes runtimes, err := clr.GetInstalledRuntimes(metahost) if err != nil { log.Fatal(err) } fmt.Println("Installed .NET Runtimes:") for _, version := range runtimes { fmt.Printf(" - %s\n", version) } } ``` -------------------------------- ### Manual CLR Hosting and Assembly Invocation in Go Source: https://context7.com/atsika/go-clr/llms.txt Demonstrates manual control over CLR initialization, AppDomain access, and assembly invocation in Go. This advanced example uses the go-clr library to load and execute a .NET assembly ('program.exe') from byte data, requiring the assembly file to be present in the execution directory. ```go package main import ( "fmt" "io/ioutil" "log" "runtime" "strings" "syscall" "unsafe" clr "github.com/ropnop/go-clr" ) func main() { // Step 1: Create metahost metaHost, err := clr.CLRCreateInstance( clr.CLSID_CLRMetaHost, clr.IID_ICLRMetaHost) if err != nil { log.Fatal(err) } // Step 2: Get specific runtime version versionString := "v4.0.30319" pwzVersion, err := syscall.UTF16PtrFromString(versionString) if err != nil { log.Fatal(err) } runtimeInfo, err := metaHost.GetRuntime(pwzVersion, clr.IID_ICLRRuntimeInfo) if err != nil { log.Fatal(err) } // Step 3: Check if runtime is loadable isLoadable, err := runtimeInfo.IsLoadable() if err != nil || !isLoadable { log.Fatal("Runtime not loadable") } // Step 4: Bind as legacy v2 runtime (for .NET 4.x assemblies) err = runtimeInfo.BindAsLegacyV2Runtime() if err != nil { log.Fatal(err) } // Step 5: Get ICORRuntimeHost interface var runtimeHost *clr.ICORRuntimeHost err = runtimeInfo.GetInterface( clr.CLSID_CorRuntimeHost, clr.IID_ICorRuntimeHost, unsafe.Pointer(&runtimeHost)) if err != nil { log.Fatal(err) } // Step 6: Start the runtime err = runtimeHost.Start() if err != nil { log.Fatal(err) } fmt.Println("[+] CLR loaded and started") // Step 7: Get default AppDomain iu, err := runtimeHost.GetDefaultDomain() if err != nil { log.Fatal(err) } var appDomain *clr.AppDomain err = iu.QueryInterface(clr.IID_AppDomain, unsafe.Pointer(&appDomain)) if err != nil { log.Fatal(err) } fmt.Println("[+] Got AppDomain") // Step 8: Load assembly from bytes exebytes, err := ioutil.ReadFile("program.exe") if err != nil { log.Fatal(err) } runtime.KeepAlive(exebytes) safeArray, err := clr.CreateSafeArray(exebytes) if err != nil { log.Fatal(err) } runtime.KeepAlive(safeArray) assembly, err := appDomain.Load_3(safeArray) if err != nil { log.Fatal(err) } fmt.Printf("[+] Assembly loaded at %p\n", assembly) // Step 9: Get entry point methodInfo, err := assembly.GetEntryPoint() if err != nil { log.Fatal(err) } // Step 10: Prepare parameters if needed var paramSafeArray *clr.SafeArray methodSignature, err := methodInfo.GetString() if err != nil { log.Fatal(err) } if !strings.Contains(methodSignature, "Void Main()") { params := []string{"arg1", "arg2"} paramSafeArray, err = clr.PrepareParameters(params) if err != nil { log.Fatal(err) } } // Step 11: Invoke the assembly nullVariant := clr.Variant{VT: 1, Val: uintptr(0)} err = methodInfo.Invoke_3(nullVariant, paramSafeArray) if err != nil { log.Fatal(err) } // Cleanup appDomain.Release() runtimeHost.Release() runtimeInfo.Release() metaHost.Release() fmt.Println("[+] Execution complete") } ``` -------------------------------- ### Execute .NET DLL and EXE from Go Source: https://github.com/atsika/go-clr/blob/master/README.md Demonstrates using the go-clr package to execute a .NET DLL from disk and a .NET EXE from a byte array in memory. It involves importing the package, reading the EXE file, and calling the respective execution functions. Outputs the return codes of the executed .NET code. ```go package main import ( clr "github.com/ropnop/go-clr" "log" "fmt" "io/ioutil" "runtime" ) func main() { fmt.Println("[+] Loading DLL from Disk") ret, err := clr.ExecuteDLLFromDisk( "TestDLL.dll", "TestDLL.HelloWorld", "SayHello", "foobar") if err != nil { log.Fatal(err) } fmt.Printf("[+] DLL Return Code: %d\n", ret) fmt.Println("[+] Executing EXE from memory") exebytes, err := ioutil.ReadFile("helloworld.exe") if err != nil { log.Fatal(err) } runtime.KeepAlive(exebytes) ret2, err := clr.ExecuteByteArray(exebytes) if err != nil { log.Fatal(err) } fmt.Printf("[+] EXE Return Code: %d\n", ret2) } ``` -------------------------------- ### Load CLR Once for Multiple Executions using go-clr Source: https://context7.com/atsika/go-clr/llms.txt Initializes the CLR environment once and reuses the host for subsequent assembly executions. This includes redirecting stdout/stderr, loading the CLR, loading an assembly into the default AppDomain, and invoking it multiple times with different parameters. It captures and prints the output and errors. ```go package main import ( "fmt" "io/ioutil" "log" clr "github.com/ropnop/go-clr" ) func main() { // Redirect STDOUT/STDERR to capture assembly output err := clr.RedirectStdoutStderr() if err != nil { log.Fatal(err) } // Load CLR once (expensive operation) runtimeHost, err := clr.LoadCLR("v4") if err != nil { log.Fatal(err) } // Read assembly bytes assemblyBytes, err := ioutil.ReadFile("tool.exe") if err != nil { log.Fatal(err) } // Load assembly into default AppDomain methodInfo, err := clr.LoadAssembly(runtimeHost, assemblyBytes) if err != nil { log.Fatal(err) } // Execute multiple times with different arguments stdout, stderr := clr.InvokeAssembly(methodInfo, []string{"command1"}) fmt.Printf("Output 1:\n%s\n", stdout) if stderr != "" { fmt.Printf("Errors 1:\n%s\n", stderr) } stdout, stderr = clr.InvokeAssembly(methodInfo, []string{"command2", "--verbose"}) fmt.Printf("Output 2:\n%s\n", stdout) if stderr != "" { fmt.Printf("Errors 2:\n%s\n", stderr) } } ``` -------------------------------- ### Execute DLL from Disk using go-clr Source: https://context7.com/atsika/go-clr/llms.txt Loads and executes a .NET DLL from the file system. It takes the target .NET runtime version, the DLL path, the full class name, the method name, and arguments as input. The function returns an integer result or an error if execution fails. ```go package main import ( "fmt" "log" clr "github.com/ropnop/go-clr" ) func main() { // Execute a DLL from disk targeting v4 runtime ret, err := clr.ExecuteDLLFromDisk( "v4", // Target .NET runtime version "TestDLL.dll", // Path to the DLL file "TestDLL.HelloWorld", // Full class name including namespace "SayHello", // Method name to invoke "foobar") // Argument to pass to the method if err != nil { log.Fatalf("Failed to execute DLL: %v", err) } fmt.Printf("DLL returned: %d\n", ret) } ``` -------------------------------- ### Execute Assembly in Default AppDomain (One-Time) using go-clr Source: https://context7.com/atsika/go-clr/llms.txt Executes a .NET assembly once within the default AppDomain using a pre-loaded CLR runtime. This function handles I/O redirection, CLR loading, assembly reading, and then invokes the assembly with provided parameters, returning any stdout and stderr. ```go package main import ( "fmt" "io/ioutil" "log" clr "github.com/ropnop/go-clr" ) func main() { // Setup I/O redirection err := clr.RedirectStdoutStderr() if err != nil { log.Fatal(err) } // Load CLR runtimeHost, err := clr.LoadCLR("v4") if err != nil { log.Fatal(err) } // Read assembly rawBytes, err := ioutil.ReadFile("utility.exe") if err != nil { log.Fatal(err) } // Execute once in default AppDomain params := []string{"scan", "--target", "127.0.0.1"} stdout, stderr := clr.ExecuteByteArrayDefaultDomain(runtimeHost, rawBytes, params) if stderr != "" { fmt.Printf("Errors: %s\n", stderr) } fmt.Printf("Output: %s\n", stdout) } ``` -------------------------------- ### Capture .NET Assembly Output with STDOUT/STDERR Redirection in Go Source: https://context7.com/atsika/go-clr/llms.txt This Go code snippet demonstrates how to redirect and capture the standard output (STDOUT) and standard error (STDERR) streams from a .NET assembly executed within a Go process using the go-clr library. It loads the CLR, reads assembly bytes, invokes a method, and then processes the captured output. Dependencies include the 'github.com/ropnop/go-clr' package. ```go package main import ( "fmt" "io/ioutil" "log" clr "github.com/ropnop/go-clr" ) func main() { // Redirect program's STDOUT/STDERR before loading CLR err := clr.RedirectStdoutStderr() if err != nil { log.Fatal(err) } // Load CLR and assembly runtimeHost, err := clr.LoadCLR("v4") if err != nil { log.Fatal(err) } assemblyBytes, err := ioutil.ReadFile("tool.exe") if err != nil { log.Fatal(err) } methodInfo, err := clr.LoadAssembly(runtimeHost, assemblyBytes) if err != nil { log.Fatal(err) } // Execute and capture output stdout, stderr := clr.InvokeAssembly(methodInfo, []string{"info"}) // Process captured output if stderr != "" { fmt.Printf("[!] Assembly STDERR:\n%s\n", stderr) } if stdout != "" { fmt.Printf("[+] Assembly STDOUT:\n%s\n", stdout) } // Can execute multiple times with output captured each time stdout2, stderr2 := clr.InvokeAssembly(methodInfo, []string{"list"}) fmt.Printf("[+] Second execution output:\n%s\n", stdout2) if stderr2 != "" { fmt.Printf("[!] Second execution errors:\n%s\n", stderr2) } } ``` -------------------------------- ### Execute .NET Assembly from Memory using go-clr Source: https://context7.com/atsika/go-clr/llms.txt Executes a .NET assembly directly from a byte array without writing it to disk. This method requires the .NET runtime version, the assembly's byte content, and a slice of command-line arguments. It returns the execution result or an error. ```go package main import ( "fmt" "io/ioutil" "log" "runtime" clr "github.com/ropnop/go-clr" ) func main() { // Read executable bytes from file exebytes, err := ioutil.ReadFile("program.exe") if err != nil { log.Fatal(err) } runtime.KeepAlive(exebytes) // Execute with command-line arguments params := []string{"arg1", "arg2", "--flag"} ret, err := clr.ExecuteByteArray("v4", exebytes, params) if err != nil { log.Fatalf("Execution failed: %v", err) } fmt.Printf("Assembly returned: %d\n", ret) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.