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.)
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?
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.
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?
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.
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.
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?
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.
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. :-)
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ß.
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. :-)
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?
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.
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 im Beitrag #8058957:
´> 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. :-)
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
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.
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.
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"...
Kommt auf die Konfiguration an. Wenn man die Benachrichtigungen
deaktiviert hat, dann halt ggf. auch völlig kommentarlos.
Hm. Klingt komisch.
Oliver
Was soll daran komisch sein? Komisch (aber nicht lustig) wäre, wenn die Benachrichtigungen deaktiviert sind, aber trotzdem erfolgen. Oder auch das Gegenteil, wenn sie aktiviert sind, aber keine erfolgen.
Alles andere ist nicht komisch, sondern normal, erwartbar und logisch. Was hast du für ein Problem mit solchem Verhalten?
Ich gehe davon aus, daß der Defender so einen „Ich will die Datei nicht starten“-Alarm nicht im allgemeinen Benachrichtigungscenter bringt, sondern prominent als Dialog mitten auf den Bildschirm.
hat jemand entweder eine Idee, woran das Problem
liegen könnte,
Sitzt vorm PC, aber mehr schreibe ich nicht mehr, schade eigentlich.
Natürlich sitzt Dein Problem vor Deinem PC, aber das ist hier nicht das Thema. Wenn Du nichts zum Thema des Threads beitragen kannst, was offensichtlich der Fall ist, halt Dich bitte raus.
Sicher. Da hat also wohl mal irgendein Arsch so ein Go-Executable als Trojan-Dropper missbraucht. Und das führt dank der primitiven Mustererkennung dazu, dass nun automatisch alle Go-Executables, die aus demselben Werkzeug stammen, mehr oder weniger verdächtig sind.
Die Virenscanner wissen halt nix von Go, die können nur das bissel Maschinencode analysieren, was da in den Executables enthalten ist.
Das Problem hat man bei allen interpretierenden Sprachen, der analysierbare Maschinencode für den Payload entsteht erst zur Laufzeit. Und auch bei allen Sprachen, die irgendeinen Zwischencode benutzen.
Deswegen sehe ich böse Zeiten anbrechen, wenn die ganzen Web-Frickler erst mal massiv mit WebAssembly rumsauen, um ihre Werbe- und Tracking-Scheiße zu verbreiten. Dagegen wird die heutige Bedrohung durch die JS-Seuche wie eine warme Sommerbrise im Vergleich zu einem Hurrican Kategorie 5 wirken.
Sicher. Da hat also wohl mal irgendein Arsch so ein Go-Executable als
Trojan-Dropper missbraucht. Und das führt dank der primitiven
Mustererkennung dazu, dass nun automatisch alle Go-Executables, die aus
demselben Werkzeug stammen, mehr oder weniger verdächtig sind.
Aber $Mistding beschwert sich doch nicht über irgendwelche Malware, sondern über das verd~mmte Binärformat?! Ist Windows wirklich /SOOO/ schlecht?
Deswegen sehe ich böse Zeiten anbrechen, wenn die ganzen Web-Frickler
erst mal massiv mit WebAssembly rumsauen, um ihre Werbe- und
Tracking-Scheiße zu verbreiten.
Für Microsoft wäre das vermutlich das Paradies: Programme können nur noch aus Microsofts Appstore installiert werden, und da werden sie nur angeboten, wenn der Hersteller freundlich zu Microsoft ist und ein kleines bisschen Kleingeld einwirft. Nächstes Jahr dann nur noch ein winzig kleines bisschen mehr. Sowas ist doch der feuchte Traum jedes Softwareherstellers: nicht nur an den eigenen Produkten verdienen, sondern auch an der Arbeit aller anderen schmarotzen. :-)
Und auch bei allen Sprachen, die irgendeinen Zwischencode benutzen.
Auch das ist Go nicht.
Offensichtlich doch. Wenn man das Executable auseinandernimmt, kann man das ganz deutlich sehen. In .text steckt nicht wirklich das, was man hier erwartet: ausführbarer Code für x86/64. Es ist vielmehr eine riesige Ansammlung von Sprungtabellen und ein paar gut verteilten Stücken echtem Code. Also exakt das, was man bei einer Sprache erwarten würde, die mit einem Zwischencode arbeitet.
Vergleichbar etwa mit dem, was man bei einer vorkompilierten Java-Anwendung oder .Net-CLI-Code zu sehen bekommt. Natürlich im Detail anders, aber letztlich dieselbe Soße.
Aber $Mistding beschwert sich doch nicht über irgendwelche Malware,
sondern über das verd~mmte Binärformat?! Ist Windows wirklich SOOO
schlecht?
Nein, tut es nicht. Du hast einen SegFault, wahrscheinlich in der
GetTitle Funktion. Siehe weiter oben.
Der Segfault trat auf, wenn für -titles ein leerer String übergeben wurde, das wird allerdings jetzt abgefangen. Aber die oben beschriebenen Fehlermeldungen sprechen doch nicht von einem Segfault, sondern davon, daß Windows das Format des Binary nicht erkannt, nicht verstanden, oder blockiert hat? Oder sieht so heute ein Segfault-Fehler unter Windows aus? Nicht wirklich, oder?
Andererseits ist das Programm bei Dir offensichtlich gestartet, sonst könnte es schließlich keinen Segfault auslösen und natürlich auch keine Debug-Infos zu Funktionen und Adressen ausgeben. Insofern würde ich es sehr interessant finden, herauszufinden, was Du dafür eingestellt hast, oder hast Du es nach Deinem Download einfach angestoßen und es lief? Hast Du den Virenscanner für die Ausführung ausgeschaltet, einen Kompatibilitätsmodus bemüht, oder etwas anderes getan, um die Ausführung zu ermöglichen? Welche Windows-Version nutzt Du, und auf was für einer CPU-Architektur?
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.
Man kann auch in Windows Ausnahmen definieren, dann ist das Programm dem Defender so was von egal.
Und auch bei allen Sprachen, die irgendeinen Zwischencode benutzen.
Auch das ist Go nicht.
Offensichtlich doch. Wenn man das Executable auseinandernimmt, kann man
das ganz deutlich sehen. In .text steckt nicht wirklich das, was man
hier erwartet: ausführbarer Code für x86/64. Es ist vielmehr eine
riesige Ansammlung von Sprungtabellen und ein paar gut verteilten
Stücken echtem Code. Also exakt das, was man bei einer Sprache erwarten
würde, die mit einem Zwischencode arbeitet.
Der Compiler arbeitet mit einem Zwischencode (Plan9 Assembly) und übersetzt den dann in nativen Maschinencode. Aufgrund des Garbage-Collectors, Reflect, Struct Tags und allerlei Debug-Symbolen sieht das wild aus, ist aber dennoch nativer Maschinencode für x86_64, den "pedis -s .text aa.exe" auch ausgibt.
Golang-Binaries sind -- und das sagen die Entwickler auch selbst -- anders aufgebaut und organisiert als Binaries aus anderen Sprachen. Das verwirrt manche Malwarescanner so oft, daß es sogar in der FAQ steht: [1].
Aber $Mistding beschwert sich doch nicht über irgendwelche Malware,
sondern über das verd~mmte Binärformat?! Ist Windows wirklich /SOOO/
schlecht?
Der Bin-Loader weiß einfach nix über des Kernel-Modul des Defender, was
da reingrätscht. Sieht nur die Auswirkung in seiner Prozessumgebung.
Würde dazu dann nicht wenigstens etwas in Windows' Logs stehen? Früher gab es da doch mal diese "Ereignisanzeige" oder so ähnlich, wie kommt man da unter Win11 mittlerweile heran, und wonach müßte man dort suchen?
Für Microsoft wäre das vermutlich das Paradies
Leider eben nicht nur für MS. Siehe z.B. Android...
Google ist mit Android ja gerade erst auf dem Weg, Apple macht das seit sehr langer Zeit vor... :-(
Der Compiler arbeitet mit einem Zwischencode (Plan9 Assembly) und
übersetzt den dann in nativen Maschinencode.
Nunja, das ist dann doch etwas Euphemismus.
Aufgrund des
Garbage-Collectors, Reflect, Struct Tags und allerlei Debug-Symbolen
sieht das wild aus, ist aber dennoch nativer Maschinencode für x86_64,
den "pedis -s .text aa.exe" auch ausgibt.
Ja, rein formal ist es gültiger Maschinencode. Aber einer, dem die Abstammung von einem Zwischencode nur allzu deutlich anzusehen ist. Sprich: deutlich suboptimal und natürlich verwirrend für alles, was ihn analysieren soll. Jedenfalls, so lange es keine Ahnung von dem Zwischencode hat.
Golang-Binaries sind -- und das sagen die Entwickler auch selbst --
anders aufgebaut und organisiert als Binaries aus anderen Sprachen.
Debug-Infos zu Funktionen und Adressen ausgeben. Insofern würde ich es
sehr interessant finden, herauszufinden, was Du dafür eingestellt hast,
oder hast Du es nach Deinem Download einfach angestoßen und es lief?
Hast Du den Virenscanner für die Ausführung ausgeschaltet, einen
Kompatibilitätsmodus bemüht, oder etwas anderes getan, um die Ausführung
zu ermöglichen? Welche Windows-Version nutzt Du, und auf was für einer
CPU-Architektur?
Windows 11, x64. Ich habe das Programm in einem Ordner ausgeführt mit einer Ausnahmeregel für den Defender.
Vorher musst du das Programm runterladen, ein zip wäre einfacher. Die exe wird sonst markiert und als nicht sicher eingestuft.
Wenn Du nichts zum Thema des Threads beitragen kannst, was
offensichtlich der Fall ist, halt Dich bitte raus.
Du hast doch angefangen, herumzustänkern, nicht ich. Und wenn dir nicht passt, was ich hier schreibe, dann ist das auch dein Problem. Und die Beleidigungen über Email habe ich auch noch nicht vergessen - du reitest ständig auf der Persönlichkeitsebene herum - dabei wäre etwas mehr Sachverstand und Respekt schon wünschenswert.
Letztlich: du hast lange Zeit gehabt, dich mal mit Windows-Grundlagen zu beschäftigen. Weil du dir aber viel dazu zu fein bist, nimmst du dir hier heraus, Leute anzuprangern - was letztendlich dein Ziel ist. Wenn man sich keine Mühe gibt, gewisse Sachzusammenhänge zu verstehen, weil man sich für etwas besseres hält, dann bleibt einem eben mur die Persönlichkeitsebene. Alles andere ist von dir hier nur vorgegaukelt.
Windows 11, x64. Ich habe das Programm in einem Ordner ausgeführt mit
einer Ausnahmeregel für den Defender.
Vorher musst du das Programm runterladen, ein zip wäre einfacher. Die
exe wird sonst markiert und als nicht sicher eingestuft.
Ein Virenscanner der keine Archive scannt?
Wow, echte Profi-Software.
Ein Virenscanner der keine Archive scannt?
Wow, echte Profi-Software.
Es geht nicht um den Virenscanner, es geht um das "Mark-of-the-Web", was Windows unabhängig vom Virenscanner verwaltet.
(Metadaten-Tag in einem NTFS-Alternate Data Stream "Zone.Identifier" für die Datei)
Wird vom Webbrowser/Mail-Programm beim Download gesetzt, Windows "merkt" sich damit, dass die Datei aus dem Bösen Internet gekommen ist, und woher.
Ob die Markierung beim Extrahieren von ZIP-Dateien "vererbt" wird, hängt von der Software und deren Einstellungen ab.
Der Windows-eigene Entpacker vererbt das Flag, WinZIP und WinRAR in aktuellen Versionen auch, 7Zip nur wenn man das in den Settings explizit aktiviert.