Forum: PC-Programmierung Go-Crosscompile: Executable läuft nicht unter Win11


von Ein T. (ein_typ)


Lesenswert?

Hallo Ihr Lieben,

für einen Freund habe ich ein kleines Golang-Programm erstellt, das bei 
ihm unter Windows laufen soll -- allerdings habe ich kein Windows und 
entwickele unter Linux. An sich sollte das jedoch trotzdem kein Problem 
darstellen, denn Go kann laut seiner Dokumentation crosskompilieren. Die 
Zielplattform und die Zielarchitektur sollen dabei dann über die 
Umgebungsvariablen GOARCH und GOOS eingestellt werden können. (Mit dem 
RasPi klappt das auch prima.)

Also habe ich mit
1
GOARCH=amd64 GOOS=windows CGO_ENABLED=0 go build -tags netgo,usergo,osusergo \ -ldflags="-s -w -extldflags=-static -buildid=" -gcflags=all="-l -B -C" \
2
-trimpath -o $(TARGET).exe

ein statisch gelinktes Executable "aa.exe" gebaut, das laut Linux' 
file(1) ein "PE32+ executable for MS Windows 6.01 (console), x86-64 
(stripped to external PDB), 7 sections" ist. Laut Internet sollte dies 
seit Windows 7 das korrekte Binärformat für Windows auf x86_64 sein.

Leider erhält mein Anwender bei dem Versuch, das Executable auszuführen, 
Fehlermeldungen, entweder "Diese App kann auf dem PC nicht ausgeführt 
werden. Wenden Sie sich an den Softwareherausgeber, um eine geeignete 
Version für Ihren PC zu finden." oder beim Versuch aus seiner 
Eingabeaufforderung eine Messagebox mit dem Titel "Nicht unterstützte 16 
Bit-Anwendung" und dem Text 'Das Programm bzw. das Feature 
"\??\C:\Users\username\aa.exe" kann aufgrund einer Inkompatibilität mit 
64 Bit-Versionen von Windows nicht gestartet bzw. ausgeführt werden. 
Wenden Siesich an den Softwarehersteller, [...]'.

Ich bin, um es vorsichtig zu sagen, verwirrt. Offensichtlich ist doch 
mein Executable im Format PE32+ (siehe oben), warum faselt Windows dabei 
etwas von 16 Bit? Außerdem habe ich irgendwo hier im Forum IIRC mal 
gelesen, daß auch moderne Windows-Versionen noch 16 Bit-Programme 
ausführen könnten? Gibt es eine eventuell Möglichkeit, bessere 
Fehlermeldungen zu erhalten? Und, achja: ist es normal, daß der Pfad in 
der Fehlermeldung mit "\??\" beginnt?

Wie dem auch sei: hat jemand entweder eine Idee, woran das Problem 
liegen könnte, oder, noch besser, vielleicht sogar einen 
Lösungsvorschlag?
von Udo K. (udok)


Lesenswert?

Fehlende DLL?  Zeig mal das Programm her, da kann ich mal schauen welche 
DLLs benötigt werden...
von Εrnst B. (ernst)


Lesenswert?

Ein T. schrieb:
> warum faselt Windows dabei
> etwas von 16 Bit?

Halbwissen:
Windows versucht den PE-Header zuerst als 64-Bit, dann 32-Bit, dann 
16-Bit zu lesen. Wenn die "16-Bit" Fehlermeldung kommt, sind die beiden 
vorherigen Versuche fehlgeschlagen.

Ein T. schrieb:
> ist es normal, daß der Pfad in
> der Fehlermeldung mit "\??\" beginnt?

Ja. Pfad im  NT-Namespace. Erlaubt z.B. die lästige Begrenzung auf 
Pfadlänge von 260 Zeichen zu umgehen.
Hat dein Freund es mit Unter-Unter-Unterordnern übertrieben, dass der 
gesamte Pfad so lang ist?

Ein T. schrieb:
> GOARCH=amd64 GOOS=windows CGO_ENABLED=0 go build -tags
> netgo,usergo,osusergo  -ldflags="-s -w -extldflags=-static -buildid="
> -gcflags=all="-l -B -C"
> -trimpath -o $(TARGET).exe

Versuch das mal ohne ldflags, gcflags, trimpath.

Wäre meine erste Vermutung, dass einer dieser Optimierungsschritte im 
Crosscompiler "zu Aggressiv" ist, und den EXE-Header beschädigt. "file" 
schaut ja nur grob nach Magic Numbers, und macht keine komplette 
Überprüfung vom Header.

Wenn's dann geht, die Flags sukkzessive wieder einsetzen.
von Dieter D. (Firma: Hobbytheoretiker) (dieter_1234)


Lesenswert?

Es gibt drei Sperrmechanismen, die fremde oder selbsterzeugte EXE nicht 
ausführen lassen. Das sind Smart-Screen-Filter, Windows im S-Mode oder 
der Defender.
von Ein T. (ein_typ)


Lesenswert?

Udo K. schrieb:
> Fehlende DLL?  Zeig mal das Programm her, da kann ich mal schauen welche
> DLLs benötigt werden...

Danke für Deine Antwort, aber das kann ich ausschließen. Das Programm 
wird statisch kompiliert und lädt also keine dynamischen Bibliotheken.
von Ein T. (ein_typ)


Lesenswert?

Εrnst B. schrieb:
> Halbwissen:
> Windows versucht den PE-Header zuerst als 64-Bit, dann 32-Bit, dann
> 16-Bit zu lesen. Wenn die "16-Bit" Fehlermeldung kommt, sind die beiden
> vorherigen Versuche fehlgeschlagen.

Sowas hatte ich befürchtet... wie "schön", daß Windows nichts über seine 
fehlgeschlagenen Versuche mit den 64- und 32-Bit-Headern sagt. :-)

> Hat dein Freund es mit Unter-Unter-Unterordnern übertrieben, dass der
> gesamte Pfad so lang ist?

C:\Users\<username>\aa.exe -- und der Username ist fünf Zeichen lang, 
alles zusammen also 21 Zeichen.

> Versuch das mal ohne ldflags, gcflags, trimpath.

Gute Idee, das versuche ich mal.
von Ein T. (ein_typ)


Lesenswert?

Dieter D. schrieb:
> Es gibt drei Sperrmechanismen, die fremde oder selbsterzeugte EXE nicht
> ausführen lassen. Das sind Smart-Screen-Filter, Windows im S-Mode oder
> der Defender.

Aber Windows beklagt sich ja anscheinend über das Binärformat. Würde es 
denn nichts über Filter, Defender oder diesen S-Mode sagen, wenn es 
darin läge?
von Udo K. (udok)


Lesenswert?

Ein T. schrieb:
> Danke für Deine Antwort, aber das kann ich ausschließen. Das Programm
> wird statisch kompiliert und lädt also keine dynamischen Bibliotheken.

Optimist 😏
von Heinz B. (Firma: Privat) (hbrill)


Lesenswert?

Ein T. schrieb:
> Danke für Deine Antwort, aber das kann ich ausschließen. Das Programm
> wird statisch kompiliert und lädt also keine dynamischen Bibliotheken.
Du lädst in deinem Code vielleicht keine DLL, aber vielleicht braucht
ja GoLang intern irgendwelche DLLs.
Das würde aber obige Fehlermeldungen nicht erklären.
: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Ein T. schrieb:
> Würde es denn nichts über Filter, Defender oder diesen
> S-Mode sagen, wenn es darin läge?

Glaubst Du daran, daß Dieter konkrete Fragen beantworten kann?
von Frank D. (Firma: LAPD) (frank_s634)


Lesenswert?

Läufts denn bei dir unter Wine?
Mach mal
1
winedump -j import deine.exe

und schau was es an dlls braucht.
von Ein T. (ein_typ)


Lesenswert?

Heinz B. schrieb:
> Ein T. schrieb:
>> Danke für Deine Antwort, aber das kann ich ausschließen. Das Programm
>> wird statisch kompiliert und lädt also keine dynamischen Bibliotheken.
> Du lädst in deinem Code vielleicht keine DLL, aber vielleicht braucht
> ja GoLang intern irgendwelche DLLs.

ldd(1), objdump(1) und die anderen mir bekannten Werkzeuge sagen alle, 
das Programm sei nicht dynamisch gelinkt, peldd(1) nennt eine 
Abhängigkeit von einer kernel32.dll, die auf einem Windows doch 
sicherlich vorhanden und von dessen dynamischen Linker auffindbar sein 
sollte?!

Außerdem gehört es ja gerade zu den besonderen Alleinstellungsmerkmalen 
von Go bzw. seinem Compiler, statisch gelinkte Binaries erzeugen zu 
können.

> Das würde aber obige Fehlermeldungen nicht erklären.

Bezüglich der Fehlermeldungen von Windows kann und will ich nichts ein- 
und auch nichts ausschließen. Wirklich rein gar nichts. :-)
von Ein T. (ein_typ)


Lesenswert?

Harald K. schrieb:
> Ein T. schrieb:
>> Würde es denn nichts über Filter, Defender oder diesen
>> S-Mode sagen, wenn es darin läge?
>
> Glaubst Du daran, daß Dieter konkrete Fragen beantworten kann?

Die Hoffnung stirbt bekanntlich zuletzt. :-)
von Ein T. (ein_typ)


Angehängte Dateien:

Lesenswert?

Frank D. schrieb:
> Läufts denn bei dir unter Wine?
> Mach mal
>
1
winedump -j import deine.exe
>
> und schau was es an dlls braucht.

Danke für den Tipp, auch winedump(1) nennt lediglich eine Abhängigkeit 
von kernel32.dll -- nach meinem Verständnis dürfte dies die 
Schnittstelle zum Systemkernel sein, ähnlich linux-vdso.so.1 bei 
Linux-Executables, oder?

Die Ausgabe von winedump(1) habe ich angehängt, vielleicht kann ein 
klügerer Mensch als ich etwas darin erkennen, das mir verborgen bleibt.
von Heinz B. (Firma: Privat) (hbrill)


Lesenswert?

Ja, die Kernel32.dll, User32.dll und GDI32.dll lädt Windows beim Start 
schon
automatisch. Ich kenne mich zwar nicht in GoLang aUs, aber evtl. gibt es
in der IDE noch einen Schalter, den man zusätzlich noch anhaken muß.
von Ein T. (ein_typ)


Lesenswert?

Heinz B. schrieb:
> Ja, die Kernel32.dll, User32.dll und GDI32.dll lädt Windows beim Start
> schon automatisch. Ich kenne mich zwar nicht in GoLang aUs, aber evtl.
> gibt es in der IDE noch einen Schalter, den man zusätzlich noch
> anhaken muß.

Es gibt keine IDE, ich arbeite immer noch klassisch mit dem GNU Emacs, 
GNU make, dem Go-Compiler in Version 1.26.0 und natürlich der guten 
alten Bash-Shell. Ich bin faul -- was laut Larry Wall, dem wir Perl 
verdanken, aber zu den wichtigsten Kardinaltugenden von Entwicklern 
gehört. :-)
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Ein T. schrieb:

> Leider erhält mein Anwender bei dem Versuch, das Executable auszuführen,
> Fehlermeldungen, entweder "Diese App kann auf dem PC nicht ausgeführt
> werden. Wenden Sie sich an den Softwareherausgeber, um eine geeignete
> Version für Ihren PC zu finden." oder beim Versuch aus seiner
> Eingabeaufforderung eine Messagebox mit dem Titel "Nicht unterstützte 16
> Bit-Anwendung" und dem Text 'Das Programm bzw. das Feature
> "\??\C:\Users\username\aa.exe" kann aufgrund einer Inkompatibilität mit
> 64 Bit-Versionen von Windows nicht gestartet bzw. ausgeführt werden.
> Wenden Siesich an den Softwarehersteller, [...]'.

Der PE-Header ist definitiv ungültig! Poste das Programm doch einfach 
mal hier, dann kann ich dir sagen, wo's klemmt.

Beim Start von der Console gibt es dann einen Fallback-Mechanismus, der 
versucht, das Programm als DOS-Programm zu verwenden. Jede Exe enthalt 
nämlich auch noch einen DOS-Stub. Auf einer 32Bit-Version von Windows 
würde das klappen und der DOS-Stub ausgeführt werden, welcher dann aber 
auch bloß eine Fehlermeldung auf der Konsole ausgeben würde.
Bei einer 64Bit-Windows-Version existiert aber das DOS-Subsystem nicht 
mehr und so kann auch der Stub nicht gestartet werden. Es kommt dann 
halt die Fehlermeldung vom System.

> Wie dem auch sei: hat jemand entweder eine Idee, woran das Problem
> liegen könnte, oder, noch besser, vielleicht sogar einen
> Lösungsvorschlag?

Woran es liegt: s.o. Lösungsvorschlag: s.o.
von Rbx (rcx)


Lesenswert?

Ein T. schrieb:
> An sich sollte das jedoch trotzdem kein Problem
> darstellen, denn Go kann laut seiner Dokumentation crosskompilieren

Ja, du Schlauberger. Hast du dir mal genauer angesehen, welche 
Bibliotheken dein Programm nutzt? Du musst doch wenigstens ausschließen, 
nicht doch MinGw nutzen zu müssen. Die Haskell-Plattform-Entwickler 
waren auch so frei, ungefragt den Zielordner bei Auspacken zu überladen. 
Happy-Emacs-Noobs eben.
: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Ein „hello world“ probiert?

https://go.dev/wiki/WindowsCrossCompiling

Oliver
von Ein T. (ein_typ)


Angehängte Dateien:

Lesenswert?

Ob S. schrieb:
> Der PE-Header ist definitiv ungültig!

Woran machst Du das fest?

> Poste das Programm doch einfach
> mal hier, dann kann ich dir sagen, wo's klemmt.

Das gewünschte "Hello World" ist "helloworld.exe", das Programm 
"aa.exe", beide findest Du im Anhang.

> Bei einer 64Bit-Windows-Version existiert aber das DOS-Subsystem nicht
> mehr und so kann auch der Stub nicht gestartet werden. Es kommt dann
> halt die Fehlermeldung vom System.

Hmmm... das Programm "aa.exe" soll am Ende von FoxPro aufgerufen werden. 
Es war schon schwierig genug für mein Gemüt, zu erfahren, daß FoxPro 
wohl kein Konzept von stdin, stdout, stderr und popen(3) haben soll, 
jedenfalls keins bei dem FoxPro von std{out,err} eines aufgerufenen 
Programms lesen kann.

Also operiert das Programm mit Dateien, einer Logdatei und einer 
CSV-Datei, die FoxPro wohl einlesen können soll. In meinem Leichtsinn 
gehe ich einmal davon aus daß die Ausführung aus FoxPro jener in der 
"Eingabeaufforderung" ähneln sollte.
von Ein T. (ein_typ)


Lesenswert?

Rbx schrieb:
´> Ja, du Schlauberger. Hast du dir mal genauer angesehen, welche
> Bibliotheken dein Programm nutzt?

Ja. Steht im Thread.

> Du musst doch wenigstens ausschließen,
> nicht doch MinGw nutzen zu müssen.

Ja. Steht im Thread.

> Die Haskell-Plattform-Entwickler

...sind hier egal. Hier geht es um Go(lang). Steht sogar im Titel.

> Happy-Emacs-Noobs eben.

lol Na das sagt ja gerade der Richtige. Du kannst doch nichtmal 
zwischen Haskell und Golang unterscheiden oder auch nur den Thread 
verstehend lesen, bevor Du Dein wirres Gefasel abkippst. Trotzdem 
allerherzlichsten Dank für Deinen gewohnt "wertvollen" "Beitrag" "zum 
Thema", Scherzkeks. :-)
von Ein T. (ein_typ)


Lesenswert?

von Udo K. (udok)


Lesenswert?

Ein T. schrieb:
>> Der PE-Header ist definitiv ungültig!
>
> Woran machst Du das fest?

Die Header sind gültig.  Das helloworld.exe läuft durch und gibt "Hallo 
Wereld!" auf die Console aus.
Wie man es schafft ein einfaches HelloWorld.exe mit über 2.4 MByte zu 
schreiben möchte ich nicht wissen.

Das aa.exe crasht unmittelbar nach dem Aufruf:
1
[130]$ ./aa.exe
2
panic: runtime error: invalid memory address or nil pointer dereference
3
[signal 0xc0000005 code=0x0 addr=0x50 pc=0x1405be1be]
4
5
goroutine 20 [running]:
6
main.GetTitle(0x7ae3be8e690, 0x7ae3be90ac8, {0x1407b0e38, 0x4})
7
        /app/main.go:62 +0x11e
8
created by main.main in goroutine 1
9
        /app/main.go:48 +0x325
von Dieter D. (Firma: Hobbytheoretiker) (dieter_1234)


Lesenswert?

Udo K. schrieb:
> crasht

Das passt. Die Sicherheitsfunktionen bei Win11 sind aktiv, wie es sein 
soll.
von Udo K. (udok)


Angehängte Dateien:

Lesenswert?

Im Bild die benötigten DLLs.
Die ext-ms-win-oobe-query-l1-1-0.dll wird zur Laufzeit geladen und nicht 
gefunden.  Keine Ahnung ob das schlimm ist.
von Udo K. (udok)


Lesenswert?

Dieter D. schrieb:
> Das passt. Die Sicherheitsfunktionen bei Win11 sind aktiv, wie es sein
> soll.

Blödsinn
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Udo K. schrieb:
> Dieter D. schrieb:
>> Das passt. Die Sicherheitsfunktionen bei Win11 sind aktiv, wie es sein
>> soll.
>
> Blödsinn

Ausnahmsweise scheinbar nicht. Die MS-Scan-Engine erkennt in aa.exe 
einen Trojaner, aber scheinbar fast als einzige. Dürfte also vermutlich 
ein false positive sein.

Etwas anders ist die Sachlage bei helloworld.exe. Lt. Virustotal 
erkennen hier ungefähr 1/3 der Scan-Engines Malware, MS auch wieder 
denselben Trojaner wie bei aa.exe.

Hier unter Win10 wurde helloworld.exe dann auch beim nächsten 
Systemstart stumpf gelöscht, aa.exe allerdings nicht.

Aber Win11 ist per default deutlich schärfer konfiguriert, also ist es 
sehr gut möglich, dass Dieter recht hat und der Kram wirklich geblockt 
wird.

Kann natürlich aber trotzdem in beiden Fällen letztlich nur false 
positive sein. Muss aber nicht. Wer sich sicher ist, kann ja dem 
Defender bzw. SmartScreen sagen, dass die Dinger nicht gefährlich sind 
und entsprechende Ausnahmen definieren.
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Ein T. schrieb:

> Woran machst Du das fest?

Eigentlich am Verhalten. Aber das reichte hier offensichtlich nicht für 
eine zuverlässige Diagnose. Inzwischen konnte ich mir ja die Header 
ansehen und habe festgestellt: valide.
von Udo K. (udok)


Lesenswert?

Ob S. schrieb:
> Ausnahmsweise scheinbar nicht. Die MS-Scan-Engine erkennt in aa.exe
> einen Trojaner, aber scheinbar fast als einzige. Dürfte also vermutlich
> ein false positive sein.

Zeigt nur wie stumpfsinning der MS Defender ist.  Die haben aufgegeben.
Alles was nicht in einer White-List drinnen ist wird erst mal gesperrt.
Wenn sich dann 100 Leute aufregen wird das Programm freigegeben - ein 
Armutszeugnis.

Auf meinem PC läuft es aber.  Musst halt drei mal sagen "Beibehalten", 
"Ist sicher" und "ist ganz sicher sicher"...
von Oliver S. (oliverso)


Lesenswert?

Ob S. schrieb:
> Die MS-Scan-Engine erkennt in aa.exe
> einen Trojaner

So ganz völlig kommentarlos?

Oliver
von Rbx (rcx)


Lesenswert?

Ein T. schrieb:
> hat jemand entweder eine Idee, woran das Problem
> liegen könnte,

Sitzt vorm PC, aber mehr schreibe ich nicht mehr, schade eigentlich.
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Oliver S. schrieb:
> Ob S. schrieb:
>> Die MS-Scan-Engine erkennt in aa.exe
>> einen Trojaner
>
> So ganz völlig kommentarlos?

Kommt auf die Konfiguration an. Wenn man die Benachrichtigungen 
deaktiviert hat, dann halt ggf. auch völlig kommentarlos.
von G. K. (zumsel)


Lesenswert?

Könnte es das hier sein?

Microsoft defender false positives of Go binaries on windows #1255
https://github.com/microsoft/go/issues/1255
von Oliver S. (oliverso)


Lesenswert?

Ob S. schrieb:
> Kommt auf die Konfiguration an. Wenn man die Benachrichtigungen
> deaktiviert hat, dann halt ggf. auch völlig kommentarlos.

Hm. Klingt komisch.

Oliver
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.