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
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?
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.
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.
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.
Ε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.
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?
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 😏
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.
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?
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. :-)
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. :-)
>> 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.
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ß.
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. :-)
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.
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.
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.
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. :-)
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
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.
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.
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"...
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.
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