__declspec(naked)



  • mir sind die meisten __declspec Attribute verständlich, nur den Sinn von naked verstehe ich nicht ganz.
    In der MSDN steht dazu:

    "For functions declared with the naked attribute, the compiler generates code without prolog and epilog code. You can use this feature to write your own prolog/epilog code sequences using inline assembler code. Naked functions are particularly useful in writing virtual device drivers."

    Als Epilog Code wird doch z.b. die Rücksprung Adresse auf dem Stack gelagert wenn man sich noch in einer call Funktion befindet, oder sehe ich das falsch?

    Dieses Attribut fand ich bei einer Anwendung in Benutzung wo ziemlich viel ASM Code in einen Remote Thread injiziert wurde um diesen zu erweitern. Nur war der Autor der Ansicht "desto härter der Code zu lesen ist, desto besser", somit konnte ich daraus nicht viel Wissen rauskitzeln 🙄

    Wäre nett wenn mir jemand beim Verständnis helfen würde 😋





  • eventuell habe ich mir gedacht das man mit dem Schlüsselwort 'naked' das C++ Problem beim kopieren und wiederverwenden von Hex(/binär)-Code nützlich wäre, wobei ich mir nicht sicher war.

    z.b.

    401000: call 604000
    ...
    604000: ret

    das da oben stellt einen Code dar wie ihn C++ erzeugt.
    Nehmen wir mal an man man würde den Code zwischen dem Offset 401000-604000 kopieren und in einer anderen Anwendung unter dem Offset 501000 reinpushen, den Speicher hat man sich vorher mit VirutalAllocEx reserviert.
    Das würde dann im Speicher so aussehen:

    501000 : call 604000
    ...
    704000: ret

    wie man sieht hat sich der Offset verändert aber der call zeigt immernoch auf 604000. Nur führt das später zu einem ACCESS_VIOLATION da womöglich Code ausgeführt wird der gar nicht vorgesehen war da der Code jetzt an 704000 steht und nicht bei 604000.

    Jedoch wäre das eventuell durch sowas gelöst(ASM Macros makros generieren sowas ähnliches):

    401000: call [EIP+200000]
    ...
    704000: ret

    wenn man diesen Code jedoch rauskopiert und unter einem anderen Offset reinhaut wie:

    501000 : call [EIP+200000]
    ...
    704000: ret

    würde er immernoch funktionieren. Ich habe keine Probleme ASM Makros in Echtzeit mit GetContext u. SetContext irgendwo "reinzuinjizieren", die Funktionen funktionieren immernoch da sie nach diesem Prinzip arbeiten. Aber die C++ compiler erzeugen einen kranken Code der dafür ungeeignet ist 😞

    Ich dachte nur, ob das "naked" Attribut nicht dem Compiler sagt das er es in der unteren Möglichkeit seine Funktionen oder was auch immer kompilieren soll.
    Damit wäre mir stark geholfen 😃

    Die Anwendung die ich gesehen habe, nutzt zumindest sowas ähnliches und es funktioniert.


  • Mod

    mir ist nicht ganz klar, wozu das gut sein soll. da es keine relativen calls gibt, müsstest du entweder den code zur laufzeit patchen, oder ein indirektes call über einen pointer durchführen.
    der zweck von naked besteht eigentlich darin, unnötigen code zu vermeiden wenn der inline assembler verwendet wird, oder um geeigneten prolog/epilog zu schreiben, wie er z.b. für gerätetreiber benötigt wird.

    ein call [eip+ xxx ] oder ähnlich ist im übrigen unsinn; eip kann NIE direkt gelesen oder beschrieben werden - dafür sind ja eben jmp/call/ret usw. zuständig



  • Als Epilog Code wird doch z.b. die Rücksprung Adresse auf dem Stack gelagert wenn man sich noch in einer call Funktion befindet, oder sehe ich das falsch?

    Ich bin jetzt nicht der ASM proger, aber das pushen der Rücksprung Adresse ist Teil des Calls und nicht des Epilog. Ich glaub damit ist eher

    ;...
    push ebp
    mov ebp esp
    ;...
    pop ebp
    ;...
    

    gemeint, hier wird ja ebp und esp verändert also wird in gewissermasen die Möglichkeiten die du mit inline ASM hast eingeschränkt. Desweiteren ist für so manche Funktion dies nur Overheat, zu Beispiel wenn es weder lokale Variablen noch Parameter gibt. Normalerweise wird der Compiler das dann weg optimiren, allerdings ASM kann ja darauf bauen, dass es diesen Code gibt und daher muss du exblicit angeben, dass diese Optimirung stattfinden soll. Zum Beispiel eine Funktion die Werte die sie über CPUID bekommen hat zurück gibt.



  • verstanden, danke! 🙄


Anmelden zum Antworten