Hintergrund
Wir haben bereits eine Herausforderung beim Werfen von SIGSEGV . Warum also nicht eine Herausforderung beim Werfen von SIGILL?
Was ist SIGILL?
SIGILL ist das Signal für eine illegale Anweisung beim Prozessor, was sehr selten vorkommt. Die Standardaktion nach dem Empfang von SIGILL ist das Beenden des Programms und das Schreiben eines Core-Dumps. Die Signal-ID von SIGILL ist 4. Sie begegnen SIGILL sehr selten, und ich habe absolut keine Ahnung, wie Sie es in Ihrem Code generieren sollen, außer über sudo kill -s 4 <pid>
.
Regeln
Sie haben root in Ihren Programmen, aber wenn Sie dies aus irgendwelchen Gründen nicht möchten, können Sie auch einen normalen Benutzer verwenden. Ich bin auf einem Linux-Computer mit deutschem Gebietsschema und kenne den englischen Text nicht, der angezeigt wird, nachdem ich SIGILL abgefangen habe, aber ich denke, es ist so etwas wie 'Illegale Anweisung'. Das kürzeste Programm, das SIGILL wirft, gewinnt.
raise(SIGILL)
?Illegal instruction (core dumped)
.Antworten:
PDP-11-Assembler (UNIX Sixth Edition), 1 Byte
Anweisung 9 ist keine gültige Anweisung auf dem PDP-11 (in oktaler Form
000011
, die nicht in der Anweisungsliste (PDF) enthalten ist). Der mit UNIX Sixth Edition gelieferte PDP-11-Assembler gibt anscheinend alles, was er nicht versteht, direkt in die Datei ein. In diesem Fall ist 9 eine Zahl, sodass eine wörtliche Anweisung 9 generiert wird. Die Eigenschaft odd (in Assemblersprachen heutzutage ungewöhnlich), dass Dateien von Anfang an ausgeführt werden, ist ebenfalls vorhanden. Daher benötigen wir keine Deklarationen, um das Programm zu erstellen Arbeit.Sie können das Programm mit diesem Emulator testen , obwohl Sie etwas damit kämpfen müssen, um das Programm einzugeben.
Die folgenden Dinge enden, sobald Sie herausgefunden haben, wie Sie das Dateisystem, den Editor, das Terminal und ähnliche Dinge verwenden, von denen Sie dachten, dass Sie bereits wussten, wie man sie verwendet:
Ich habe mit der Dokumentation bestätigt, dass dies ein echtes
SIGILL
Signal ist (und es hatte sogar die gleiche Signalnummer, 4, bis dahin!)quelle
a.out
enthält tatsächlich mehrere Bytes (die9
Anweisung wird zu zwei Bytes kompiliert, und der Assembler fügt auch einen Header und einen Footer hinzu, um das Programm ausführbar zu machen). Deshalb habe ich das Programm in Assembler geschrieben, nicht in Maschinencode. Das Assembler-Programm hat nur ein Byte und wird zu einem Programm mit mehr Byte kompiliert. Dies ist ein Code-Golf- Problem (minimieren Sie die Größe der Quelle), kein Größenkodierungsproblem (minimieren Sie die Größe der ausführbaren Datei), daher ist es die 1-Byte-Größe der Quelle, auf die es ankommt.C (x86_64, tcc ), 7 Bytes
Inspiriert von dieser Antwort .
Probieren Sie es online!
Wie es funktioniert
Die generierte Assembly sieht folgendermaßen aus.
Beachten Sie, dass TCC findet nicht die definierte „Funktion“ in einem Datensegment.
Nach dem Kompilieren zeigt _start wie gewohnt auf main . Wenn das resultierende Programm ausgeführt wird, erwartet es Code in main und findet die Little-Endian (!) 32-Bit-Ganzzahl 6 , die als 0x06 0x00 0x00 0x00 codiert ist . Das erste Byte - 0x06 - ist ein ungültiger Opcode, daher wird das Programm mit SIGILL beendet .
C (x86_64, gcc ), 13 Bytes
Probieren Sie es online!
Wie es funktioniert
Ohne den const- Modifikator sieht die generierte Assembly folgendermaßen aus.
Der Linker von GCC behandelt die letzte Zeile als Hinweis darauf, dass das generierte Objekt keinen ausführbaren Stapel benötigt. Da Haupt explizit in einem platziert Datenabschnitt, ist der Opcode enthält es nicht ausführbar, so wird das Programm beendet SIGSEGV (Segmentierungsfehler).
Wenn Sie entweder die zweite oder die letzte Zeile entfernen, funktioniert die generierte ausführbare Datei wie beabsichtigt. Die letzte Zeile könnte mit dem Compiler-Flag ignoriert werden
-zexecstack
( online ausprobieren! ), Dies kostet jedoch 12 Byte .Eine kürzere Alternative besteht darin, main mit dem Modifikator const zu deklarieren , was zu der folgenden Assembly führt.
Dies funktioniert ohne Compiler-Flags. Beachten Sie, dass
main=6;
die definierte "Funktion" in Daten geschrieben wird , aber der const- Modifikator bewirkt , dass GCC sie stattdessen in rodata schreibt , was (zumindest auf meiner Plattform) Code enthalten darf.quelle
main
es sich um eine 6 handelt, und versucht er, sie aufzurufen (was wahrscheinlich dazu führen würde, dass er aufgibt und die Anweisung versucht)?main
nicht um eine Funktion handelt, sondern nur, wenn Sie die Warnungen einschalten (entweder-Wall
oder-pedantic
werden es tun)..rodata
Abschnitt innerhalb des Textsegments der ausführbaren Datei, und ich gehe davon aus, dass dies auf so ziemlich jeder Plattform der Fall sein wird. (Der Programmlader des Kernels kümmert sich nur um Segmente, nicht um Abschnitte).06
in x86-64 nur eine ungültige Anweisung ist. Im 32-Bit-Modus ist dies der FallPUSH ES
, daher funktioniert diese Antwort nur mit Compilern, die standardmäßig den Wert "" haben-m64
. Siehe ref.x86asm.net/coder.html#x06 . Die einzige Byte - Sequenz , die als illegale Anweisung auf alle zukünftigen x86 - CPUs ist die 2 - Byte zu dekodieren garantiert wird UD2 :0F 0B
. Alles andere könnte ein zukünftiges Präfix oder eine Befehlskodierung sein. Trotzdem wurde es für eine coole Methode empfohlen, einen C-Compiler dazu zu bringen, einmain
Label auf einige Bytes zu kleben !Schnell, 5 Bytes
Greifen Sie auf Index 0 eines leeren Arrays zu. Dieser ruft auf
fatalError()
, der eine Fehlermeldung ausgibt und mit einem SIGILL abstürzt. Sie können es hier ausprobieren .quelle
fatalError()
stürzt absichtlich beim rennen abud2
. Warum sie sich dafür entschieden haben, weiß ich nicht, aber vielleicht fanden sie die Fehlermeldung "Illegal instruction" sinnvoll, weil das Programm etwas Illegales tat.nil!
, aber der Compiler konnte nicht auf den Ergebnistyp schließen. (Auch Hallo JAL!)GNU C, 25 Bytes
GNU C (ein spezifischer Dialekt von C mit Erweiterungen) enthält eine Anweisung, das Programm absichtlich zum Absturz zu bringen. Die genaue Implementierung variiert von Version zu Version, aber die Entwickler versuchen oft, den Absturz so billig wie möglich zu implementieren, was normalerweise die Verwendung einer illegalen Anweisung beinhaltet.
Die spezielle Version, die ich zum Testen verwendet habe, ist
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0
; Dieses Programm verursacht jedoch ein SIGILL auf einem ziemlich breiten Bereich von Plattformen und ist daher ziemlich portabel. Darüber hinaus erfolgt dies durch die tatsächliche Ausführung einer unzulässigen Anweisung. Hier ist der Assembler-Code, den das oben Genannte mit den Standard-Optimierungseinstellungen kompiliert:ud2
ist eine Anweisung, für die Intel garantiert, dass sie immer undefiniert bleibt.quelle
main(){asm("ud2");}
00 00 0f 0b
dieud2
00
Bytes haben; Sie sind nicht Teil des Maschinencodes für UD2. Übrigens, wie ich Dennis 'Antwort kommentiert habe , gibt es derzeit in x86-64 unzulässige 1-Byte-Anweisungen, aber das kann nicht garantiert werden.00 00
decodiert dasselbe in x86-64 (alsadd [rax], al
).00 00 0f 0b
würde normalerweise SIGSEGV vor SIGILL sein, es sei denn, Sie haben zufällig einen beschreibbaren Zeiger inrax
.C (x86_64), 11, 30, 34 oder 34 + 15 = 49 Bytes
Ich habe ein paar Lösungen vorgelegt, die Bibliotheksfunktionen verwenden, um
SIGILL
mit verschiedenen Mitteln zu werfen , aber das ist wohl Betrug, da die Bibliotheksfunktion das Problem löst. Hier finden Sie eine Reihe von Lösungen, die keine Bibliotheksfunktionen verwenden und unterschiedliche Annahmen darüber treffen, wo das Betriebssystem bereit ist, Sie nicht ausführbaren Code ausführen zu lassen. (Die Konstanten hier sind für x86_64 ausgewählt, aber Sie können sie ändern, um funktionierende Lösungen für die meisten anderen Prozessoren mit ungültigen Anweisungen zu erhalten.)06
ist das niedrigstnumerierte Byte des Maschinencodes, das keinem definierten Befehl auf einem x86_64-Prozessor entspricht. Also müssen wir es nur ausführen. (Alternativ2F
ist auch undefiniert und entspricht einem einzelnen druckbaren ASCII-Zeichen.) Keines dieser Zeichen ist garantiert immer undefiniert, aber sie sind ab heute nicht definiert.Das erste Programm hier wird
2F
vom Nur-Lese-Datensegment ausgeführt. Die meisten Linker sind nicht in der Lage, einen Sprung von.text
zu.rodata
(oder das Äquivalent zu ihrem Betriebssystem) zu erzeugen, da dies in einem korrekt segmentierten Programm niemals nützlich sein würde. Ich habe noch kein Betriebssystem gefunden, auf dem dies funktioniert. Sie müssten auch die Tatsache berücksichtigen, dass viele Compiler möchten, dass die fragliche Zeichenfolge eine breite Zeichenfolge ist, für die eine zusätzliche erforderlich wäreL
; Ich gehe davon aus, dass jedes Betriebssystem, auf dem dies funktioniert, eine ziemlich veraltete Sicht der Dinge hat und daher standardmäßig auf einen Standard vor C94 aufbaut. Es ist möglich, dass dieses Programm nirgendwo funktioniert, aber es ist auch möglich, dass dieses Programm irgendwo funktioniert, und daher liste ich es in dieser Sammlung von zweifelhafteren bis weniger zweifelhaften möglichen Antworten auf. (Nachdem ich diese Antwort gepostet hatte, erwähnte Dennis auch die Möglichkeitmain[]={6}
im Chat, die die gleiche Länge hat und die keine Probleme mit der Zeichenbreite verursacht, und wies sogar auf das Potenzial für hinmain=6
. Ich kann diese Antworten nicht als vernünftig bezeichnen meins, da ich selbst nicht an sie gedacht habe.)Das zweite Programm wird hier
06
vom Lese- / Schreibdatensegment ausgeführt. Auf den meisten Betriebssystemen führt dies zu einem Segmentierungsfehler, da beschreibbare Datensegmente als schlechter Konstruktionsfehler angesehen werden, der Exploits wahrscheinlich macht. Dies war jedoch nicht immer der Fall, so dass es wahrscheinlich auf einer ausreichend alten Linux-Version funktioniert, aber ich kann es nicht einfach testen.Das dritte Programm wird
06
vom Stapel ausgeführt. Auch dies führt heutzutage zu einem Segmentierungsfehler, da der Stack aus Sicherheitsgründen normalerweise als nicht beschreibbar eingestuft wird. Die Linker-Dokumentation, die ich stark gesehen habe, impliziert, dass es früher legal war, vom Stapel auszuführen (im Gegensatz zu den beiden vorhergehenden Fällen ist dies gelegentlich nützlich). Obwohl ich es nicht testen kann, bin ich mir ziemlich sicher, dass es einige gibt Linux-Version (und wahrscheinlich auch andere Betriebssysteme), auf denen dies funktioniert.Wenn Sie
-Wl,-z,execstack
( wenn Siegcc
GNUld
als Teil des Backends verwenden) mit (15-Byte-Strafe) belegen, wird der Schutz für ausführbare Stapel explizit deaktiviert, sodass das dritte Programm wie erwartet funktionieren und ein ungültiges Betriebssignal ausgeben kann. Ich habe diese 49-Byte-Version getestet und verifiziert, damit sie funktioniert. (Dennis erwähnt im Chat, dass diese Option anscheinend funktioniertmain=6
, was eine Punktzahl von 6 + 15 ergeben würde. Ich bin ziemlich überrascht, dass dies funktioniert, da die 6 offensichtlich nicht auf dem Stack ist; die Link-Option macht anscheinend mehr als der Name weist darauf hin.)quelle
const main=6;
funktioniert dies ebenso wie verschiedene Variationen. Dieser Linker (was ich vermute auch , Ihre Linker ist) ist der Lage , einen Sprung von Erzeugung.text
zu.rodata
; Das Problem, das Sie hatten, ist, dass Sie ohneconst
in das beschreibbare Datensegment (.data
) springen , das auf moderner Hardware nicht ausführbar ist. Es hätte auf älteren x86-Versionen funktioniert, bei denen die Speicherschutzhardware Seiten nicht als lesbar, aber nicht ausführbar markieren konnte.main
eine Funktion sein muss (§5.1.2.2.1) - Ich weiß nicht, warum gcc die Deklarationmain
als Datenobjekt in Betracht zieht, um nur eine Warnung zu verdienen, und zwar nur-pedantic
in der Befehlszeile. Jemand in den frühen neunziger Jahren dachte vielleicht, dass niemand das versehentlich tun würde, aber es ist nicht so, als wäre es eine nützliche Sache, die man absichtlich machen könnte, außer für diese Art von Spiel.main[]="/"
Lesen wird erwartet, dass Sie in das schreibgeschützte Datensegment springen, da String-Literale in rodata geschrieben werden. Sie wurden vom Unterschied zwischenchar *foo = "..."
und überraschtchar foo[] = "..."
.char *foo = "..."
ist syntaktischer Zucker fürconst char __inaccessible1[] = "..."; char *foo = (char *)&__inaccessible1[0];
, daher geht das String-Literal in rodata undfoo
ist eine separate , beschreibbare globale Variable, die darauf verweist. Mitchar foo[] = "..."
geht jedoch das gesamte Array in das beschreibbare Datensegment.GNU as (x86_64), 3 Bytes
$ xxd sigill.S
$ as --64 sigill.S -o sigill.o; ld-sigill.o -o sigill
$ ./sigill
$ objdump -d Sigill
quelle
asm-link
) für Spielzeugprogramme mit einer einzelnen Datei würde eine ausführbare Datei aus dieser Quelle auf die gleiche Weise erstellen, dald
der Einstiegspunkt standardmäßig auf den Anfang des Textsegments oder so ähnlich festgelegt ist. Ich habe nur nicht daran gedacht, hier die Quellgröße zu wählen: PBash auf Raspbian auf QEMU, 4 (1?) Bytes
Nicht meine Arbeit. Ich berichte nur die Arbeit eines anderen. Ich bin nicht einmal in der Lage, die Behauptung zu testen. Da ein entscheidender Teil dieser Herausforderung darin zu bestehen scheint, eine Umgebung zu finden, in der dieses Signal ausgelöst und abgefangen wird, schließe ich die Größe von QEMU, Raspbian oder Bash nicht ein.
Am 27. Februar 2013, 20:49 Uhr, berichtete der Benutzer emlhalac in den Raspberry Pi-Foren , dass er " illegale Anweisungen erhalten" habe, wenn er versucht zu chrooten .
produzieren
Ich stelle mir zum Beispiel vor, dass viel kürzere Befehle diese Ausgabe erzeugen
tr
.BEARBEITEN: Auf der Grundlage des Kommentars von @ fluffy wurde die mutmaßliche Untergrenze für die Eingabelänge auf "1?"
quelle
[
Kommando würde gewinnen. :)x86-MS-DOS-COM-Datei, 2 Byte
BEARBEITEN: Wie in den Kommentaren erwähnt, wird DOS selbst die CPU-Ausnahme nicht abfangen und einfach hängen bleiben (nicht nur die App, das gesamte Betriebssystem). Die Ausführung auf einem 32-Bit-NT-basierten Betriebssystem wie Windows XP löst in der Tat ein ungültiges Anweisungssignal aus.
Aus der Dokumentation :
Welches ist ziemlich selbsterklärend. Als .com-Datei speichern und
in einem DOS-Emulator ausführenDOS-Emulatoren stürzen einfach ab. Laufen Sie unter Windows XP, Vista oder 7 32-Bit.quelle
#UD
stoppen. (Außerdem habe ich beschlossen, es tatsächlich zu testen, und es schien, als würde mein DOS-Emulator in eine EndlosschleifeC (32-Bit-Windows): 34 Byte
Dies funktioniert nur, wenn das Kompilieren nicht optimiert wurde (ansonsten ist der ungültige Code in der
f
Funktion "optimiert").Die Demontage der
main
Funktion sieht folgendermaßen aus:Wir können sehen, dass es einen
push
Befehl mit einem Literalwert verwendet0b0f
(Little-Endian, also werden seine Bytes ausgetauscht). Dercall
Befehl sendet eine Rücksprungadresse (des...
Befehls), die sich auf dem Stapel in der Nähe des Parameters der Funktion befindet. Bei Verwendung einer[-1]
Verschiebung überschreibt die Funktion die Rücksprungadresse, sodass sie 9 Bytes früher zeigt, wo sich die Bytes0f 0b
befinden.Diese Bytes verursachen eine "undefinierte Anweisungs" -Ausnahme, wie vorgesehen.
quelle
Java,
504324 BytesDies ist eine
java.util.function.Consumer<Runtime>
1, deren Befehl aus Fluffys Antwort gestohlen wird . Es funktioniert, weil Sie es so nennen müssenwhateverNameYouGiveIt.accept(Runtime.getRuntime())
!Beachten Sie, dass dadurch ein neuer Prozess erstellt und ein SIGILL ausgelöst wird, anstatt ein SIGILL selbst auszulösen.
1 - Technisch gesehen kann es sich auch um ein
java.util.function.Function<Runtime, Process>
becauseRuntime#exec(String)
return a handelnjava.lang.Process
, mit dem Sie den Prozess steuern können, den Sie gerade durch Ausführen eines Shell-Befehls erstellt haben.Um etwas Beeindruckenderes in solch einer wortreichen Sprache zu tun, gibt es hier einen Bonus von
726048 Byte:Dieses ist ein anderes
Consumer<Runtime>
, das ALLE Prozesse durchläuft (einschließlich sich selbst), wobei jeder von ihnen ein SIGILL wirft. Besser auf einen heftigen Sturz gefasst.Und noch ein Bonus (a
Consumer<ANYTHING_GOES>
), der zumindest vorgibt , ein SIGILL in 20 Bytes zu werfen:quelle
Perl, 9 Bytes
Ruft einfach die entsprechende Bibliotheksfunktion zur Signalisierung eines Prozesses auf und veranlasst das Programm, sich selbst zu signalisieren
SIGILL
. Hier handelt es sich nicht um rechtswidrige Anweisungen, sondern um das entsprechende Ergebnis. (Ich denke, das macht die Herausforderung ziemlich billig, aber wenn irgendetwas erlaubt ist, ist dies die Lücke, die Sie nutzen würden ...)quelle
+
. :)+
. Nachdem sie eine Weile Golf gespielt haben+
, zeigen sie sich gelegentlich. Schließlich haben sie genug Programme geschrieben, um Leerzeichen aus irgendeinem Grund zu vermeiden, der+
zur Gewohnheit wird. (Es analysiert auch weniger mehrdeutig, da es den Sonderfall im Parser für KlammernARM Unified Assembler Language (UAL), 3 Byte
Zum Beispiel:
Nach der Ausführung
nop
interpretiert der Prozessor den.ARM.attributes
Abschnitt als Code und trifft irgendwo dort auf eine unzulässige Anweisung:Getestet auf einem Raspberry Pi 3.
quelle
Microsoft C (ab Visual Studio 2005), 16 Byte
Ich kann das nicht einfach testen, aber laut Dokumentation sollte es eine illegale Anweisung erzeugen, indem absichtlich versucht wird, eine Nur-Kernel-Anweisung von einem Benutzermodus-Programm auszuführen. (Beachten Sie, dass wir nicht versuchen müssen, zurückzukehren, da der illegale Befehl das Programm zum Absturz bringt.
main
Dies bedeutet, dass diese K & R-main
ähnliche Funktion gültig ist. Visual Studio, das nie von C89 übergegangen ist, ist normalerweise eine schlechte Sache, aber sie ist eingegangen nützlich hier.)quelle
Ruby, 13 Bytes
Ich denke, es ist sicher anzunehmen, dass wir dies von einer * nix-Shell ausführen. Die Backtick-Literale führen den angegebenen Shell-Befehl aus.
$$
ist der laufende Ruby-Prozess und der#
für die String-Interpolation.Ohne die Shell direkt aufzurufen:
Ruby, 17 Bytes
quelle
Beliebige Shell (sh, bash, csh usw.), beliebiges POSIX (10 Byte)
Triviale Antwort, aber ich hatte niemanden gesehen, der sie gepostet hat.
Sendet einfach SIGILL an den aktuellen Prozess. Beispielausgabe unter OSX:
quelle
kill -4 1
wenn die Frage nicht spezifisch ist, welches Programm SIGILLYou will have root in your programs
- Schlagen Sie ein Byte von Ihrer Antwort ab und werfen Sie gleichzeitig einen leichten Blick auf die Frage: D. BONUS: Du darfst töteninit
init
ist es eigentlich immun gegen Signale, die es selbst mit root nicht speziell angefordert hat. Sie können dies möglicherweise umgehen, indem Sie ein anderes POSIX-Betriebssystem verwenden.kill -4 2
dann: DELF + x86-Maschinencode, 45 Byte
Dies sollte das kleinste ausführbare Programm auf einem Unix-Rechner sein, das SIGILL auslöst (da Linux die ausführbare Datei nicht erkennt, wenn sie verkleinert wird).
Kompilieren Sie mit
nasm -f bin -o a.out tiny_sigill.asm
, getestet auf einer virtuellen x64-Maschine.Tatsächliche 45 Bytes binär:
Montageliste (siehe Quelle unten):
Haftungsausschluss: Code aus dem folgenden Tutorial zum Schreiben des kleinsten Assembler-Programms, um eine Zahl zurückzugeben. Verwenden Sie jedoch opcode ud2 anstelle von mov: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
quelle
AutoIt , 93 Bytes
Verwendung der Flatassembler-Inline-Montage:
Wenn es im interaktiven SciTE-Modus ausgeführt wird, stürzt es sofort ab. Der Windows-Debugger sollte für den Bruchteil einer Sekunde angezeigt werden. Die Konsolenausgabe sieht ungefähr so aus:
Wo
-1073741795
wird der undefinierte Fehlercode von der WinAPI ausgegeben? Dies kann eine beliebige negative Zahl sein.Ähnlich mit meinem eigenen Assembler LASM :
quelle
NASM, 25 Byte
Ich weiß nicht, wie das funktioniert, nur dass es auf meinem Computer funktioniert (Linux x86_64).
Kompilieren und ausführen wie:
quelle
ja 0
ud2
TI-83 Hex Assembly, 2 Byte
Führen Sie so
Asm(prgmI)
. Führt den ungültigen 0xed77-Opcode aus. Ich zähle jedes Paar hexadezimaler Ziffern als ein Byte.quelle
Python, 32 Bytes
quelle
import os;os.kill(os.getpid(),4)
x86.COM, 1 Byte
ARPL
Ursachen#UD
im 16-Bit-Modusquelle
Linux-Shell, 9 Bytes
Sendet
SIGILL
an den Prozess mit PID 0. Ich weiß nicht, welcher Prozess PID 0 hat, aber er existiert immer.Probieren Sie es online!
quelle
man kill
:0 All processes in the current process group are signaled.
GNU C,
241918 Bytes-4 dank Dennis
-1 dank ceilingcat
Probieren Sie es online! Dies setzt ASCII und x86_64 voraus. Es wird versucht, den Maschinencode auszuführen
27
, der ... unzulässig ist.shortC ,
1054 BytesEntspricht dem obigen GNU C-Code. Probieren Sie es online!
quelle
L"\6"
ist auch illegal, vorausgesetzt x86_64.L
ist nicht nötig.'
ist 39 = 0x27 , nicht 0x39 .MachineCode auf x86_64,
21 BytesProbieren Sie es online!
0x07
Ruft einfach die Anweisung x86_64 auf (Ceilingcat schlug 0x07 anstelle von 0x27 vor)quelle