Last active
January 22, 2016 22:43
-
-
Save edef1c/a8118bf5b047f5f77c6c to your computer and use it in GitHub Desktop.
NixOS module: dispatch PE execution to either WINE or Mono based on whether it is a CLR executable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"debug/pe" | |
"errors" | |
"fmt" | |
"os" | |
"syscall" | |
) | |
func main() { | |
args := os.Args[1:] | |
f, err := pe.Open(args[0]) | |
if err == nil { | |
err = f.Close() | |
} | |
if err != nil { | |
fmt.Fprintln(os.Stderr, err) | |
os.Exit(-1) | |
} | |
var dataDirectories *[16]pe.DataDirectory | |
switch hdr := f.OptionalHeader.(type) { | |
default: | |
panic(fmt.Errorf("unexpected OptionalHeader type: %T", hdr)) | |
case nil: | |
case *pe.OptionalHeader32: | |
dataDirectories = &hdr.DataDirectory | |
case *pe.OptionalHeader64: | |
dataDirectories = &hdr.DataDirectory | |
} | |
isCLR := dataDirectories != nil && dataDirectories[14].Size != 0 | |
execute := "@executorWIN@" | |
if isCLR { | |
execute = "@executorCLR@" | |
} | |
err = syscall.Exec(execute, append([]string{execute}, args...), os.Environ()) | |
if err == nil { | |
err = errors.New("unexpected return from syscall.Exec") | |
} | |
fmt.Fprintln(os.Stderr, err) | |
os.Exit(-1) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ pkgs, ... }: | |
let | |
executorWIN = "${pkgs.wine}/bin/wine"; | |
executorCLR = "${pkgs.mono}/bin/mono"; | |
dispatch = (pkgs.goPackages.buildGoPackage rec { | |
name = "binfmt_dispatch"; | |
goPackagePath = name; | |
preferLocalBuild = true; | |
src = pkgs.substituteAll { | |
name = "binfmt_dispatch.go"; | |
src = ./binfmt_dispatch.go; | |
dir = "."; | |
inherit executorWIN executorCLR; | |
}; | |
}).bin; | |
in { | |
environment.systemPackages = [ dispatch pkgs.wine pkgs.mono ]; | |
environment.etc."binfmt.d/pe.conf" = { | |
text = ":DOSWin:M::MZ::${dispatch}/bin/binfmt_dispatch:\n"; | |
}; | |
systemd.additionalUpstreamSystemUnits = [ "systemd-binfmt.service" ]; | |
systemd.services.systemd-binfmt.wants = [ "proc-sys-fs-binfmt_misc.automount" ]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment