Dies ist eine Standard-Tail-Call-Sequenz auf x86-64, wie sie durch den Microsoft-Compiler erzeugt werden würde.
Ja, wie Sie gesagt haben, es ist ein indirekter Sprung zu einer 64-Bit-Speicheradresse, 0x75768
. An dem Punkt, an dem dieser Code ausgeführt wird, ist gleich 7, also rip + 0x75761
== == 0x75768
. Der Code überträgt die Kontrolle bedingungslos an die Anweisungen unter der Adresse 0x75768
.
Die nachfolgende ist nur Polsterung, dient aber auch als Ziegelmauer. Die Ausführung sollte wegen des unbedingten Zweigs in der vorherigen Anweisung niemals diesen Punkt erreichen. Wenn dies der Fall wäre, würde die CPU einfangen, da dies der "Unterbrechungs" -Interrupt ist.
Wie für die REX.W-Präfix, Harold ist technisch korrekt, dass es unnötig ist, aber nicht aus dem Grund, die Sie vielleicht denken. Etwas überraschend, wenn ein indirekter Sprung durch ein Register auf x86-64 verwendet wird, benötigt Windows das Präfix REX.W, um sicherzustellen, dass der Stack-Abbau erfolgreich ist. Der Stapelabwicklungscode verwendet dies intern als Signal. Ross Ridge hat an excellent answer über den Zweck von REX-Präfix-JMP-Anweisungen in Windows x64 geschrieben.
Dies ist in diesem Fall nicht unbedingt notwendig, da es sich um einen indirekten Sprung mit einem IP-relativen Operanden handelt, aber der Compiler gibt es anscheinend trotzdem ab. Seine Logik für die Handhabung ist wahrscheinlich nicht so komplex, und vielleicht erzeugt es diesen Code immer aus Konsistenzgründen. Oder vielleicht ist die offizielle Dokumentation nicht umfassend, wie genau der Stapelabwicklungscode implementiert wird. Lieber sicher als Nachsicht, da es in einem zusätzlichen REX.W-Präfix keinen wirklichen Nachteil gibt.
Ja, übrigens ist der REX.W redundant. – harold
Danke! Leider ist der Code auf einer x64 Windows 10-Installation eines Kunden für eine der user32.dll-Funktionen. Keine Ahnung, wie dieser Code dort angekommen ist, weil es kein Standard-MS-Code ist. Also muss ich dafür sorgen. – user118708
Sind Sie sicher, dass dies 64-Bit-Maschinencode ist? Wenn es als 32-Bit-Code demontiert wurde, wäre das Byte "0x48" ein "dec" oder "inc". ('dec eax' denke ich). –