Ich löse eine binäre Exploitation-Herausforderung auf picoCTF und bin auf diesen Code gestoßen: buf wo
ist ein Zeichenarray.
Ich habe die Herausforderung gelöst, kann aber anscheinend nicht verstehen, was genau sie tut. Ich habe mir diesen Thread angesehen, aber ich konnte es nicht erkennen. ((void (*)())buf)(); Was macht
bedeuten? ((void (*)())buf)(); Was macht bedeuten? typedefEs bedeutet, dass der Autor es nicht versteht typedef void (*voidFuncPtrType)(); .
würde diesen Code klar machen.
– Andreas Henle
14. Januar 2020 um 13:39 Uhr
@AndrewHenle Beim Entwerfen von CTF-Herausforderungen ist Klarheit nicht wirklich das oberste Ziel, und im Rahmen der Herausforderung kann sogar mit einer gewissen Verschleierung gerechnet werden. Höchstwahrscheinlich war sich der Autor bewusst, dass dies nicht die am besten lesbare Vorgehensweise ist.
– ManfP
14. Januar 2020 um 23:19 Uhr
Es bedeutet, dass Ihr Programm UB hat.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
15. Januar 2020 um 20:10 Uhr
Es bedeutet, dass die Deklarationsregel vom Typ “Spirale” von C viel zu kompliziert ist. Es gibt einen Grund dafür, dass praktisch jede andere statisch typisierte Sprache, die nicht direkt von C abstammt, stattdessen Regeln von links nach rechts verwendet.
– Maurer Wheeler
15. Januar 2020 um 22:39 Uhr
@MasonWheeler „Spiral“ ist ein urbaner Mythos. Die Deklaration ist so viel oder so wenig “Spirale”, wie es der entsprechende Ausdruck wäre. Operatoren werden einfach mit Vorrang und von links nach rechts angewendet (was Ihnen hier natürlich nichts Neues sagt): “Ich muss es dereferenzieren, dann aufrufen, und das Ergebnis hat den Typ void”: voila, Zeiger auf void-Funktion .
– Peter – Setzen Sie Monica wieder ein
void (*)() 16. Januar 2020 um 3:47 Uhr
(void (*)()) ist ein Typ, wobei der Typ “Zeiger auf eine Funktion ist, die unbestimmte Argumente annimmt und keinen Wert zurückgibt”.
(void (*)())buf ist eine Typumwandlung in den obigen Typ. buf wirft
((void (*)())buf)() zum oben genannten Typ.
ruft die Funktion auf (es werden keine Argumente übergeben). buf Kurz gesagt: Es sagt dem Compiler, dass er behandeln soll
als Zeiger auf eine Funktion und zum Aufrufen dieser Funktion. cdecl Ich finde die Dienstprogramm (bzwWebseite
) hilfreich, um die komplexeren C-Ausdrücke ins Englische zu übersetzen.
– bta
14. Januar 2020 um 23:49 Uhr
@bta cdecl ist hier nicht nützlich, da die Syntax keine Deklaration ist. Es ist ein Funktionsaufruf über einen Cast auf ein zuvor deklariertes Symbol
– Bolov
15. Januar 2020 um 1:00 Uhr @bolov – Bei der gesamten Aussage nein, aber es tut erkläre das komplexeste Teil
davon. Von dort aus ist die Dekodierung des Rests ziemlich einfach.
– bta
15. Januar 2020 um 1:11 Uhr buf @AvD Wenn wo copy oder
an einer ausführbaren Adresse liegt und der Code selbst positionsunabhängig ist, wird dies funktionieren. Es ist natürlich so nicht portabel wie es nur geht, aber dies sollte in vielen Bare-Metal-Umgebungen sowie in älteren x86-Betriebssystemen funktionieren, die das No-Execute-Bit (NX) nicht auf Stack und Heap setzen.
– wrtlprnft
15. Januar 2020 um 4:39 Uhr
@AvD: Es wird nicht unbedingt abstürzen. Sofern der Datenbereich nicht gegen Ausführung geschützt ist (was von der Architektur und der Laufzeitumgebung abhängt), können Sie mit diesem Trick eine Funktion zur Laufzeit in ein Array kompilieren und im laufenden Betrieb aufrufen. Ich habe diesen Trick zum ersten Mal vor 35 Jahren auf einem DEC Vax verwendet, um Turing-Maschinen für ein fehlgeschlagenes Experiment in der Evolution von Turing-Maschinen zu kompilieren.
– TonyK
15. Januar 2020 um 10:40 Uhr buf Zeiger
Benutzeravatar von lukeg
Lukas buf Es ist eine Typumwandlung, gefolgt von einem Funktionsaufruf. Zuerst, voidwird in den Zeiger auf eine Funktion umgewandelt, die zurückkehrt
. Das letzte Klammerpaar bedeutet, dass die Funktion dann aufgerufen wird. voidEs wandelt das Zeichen-Array in einen Zeiger auf eine Funktion um, die keine Argumente akzeptiert und zurückkehrt
, und ruft es dann auf. Eine Dereferenzierung des Zeigers ist aufgrund der Funktionsweise von Funktionszeigern nicht erforderlich.
Eine Erklärung: void (*)() Dieses “Zeichenarray” ist eigentlich ein Array aus Maschinencode. Wenn Sie das Array in a umwandeln
bedeuten?
((void (*)())buf)();
Was macht bedeuten?typedef
Es bedeutet, dass der Autor es nicht verstehttypedef void (*voidFuncPtrType)();
.würde diesen Code klar machen.
– Andreas Henle
14. Januar 2020 um 13:39 Uhr
@AndrewHenle Beim Entwerfen von CTF-Herausforderungen ist Klarheit nicht wirklich das oberste Ziel, und im Rahmen der Herausforderung kann sogar mit einer gewissen Verschleierung gerechnet werden. Höchstwahrscheinlich war sich der Autor bewusst, dass dies nicht die am besten lesbare Vorgehensweise ist.
– ManfP
14. Januar 2020 um 23:19 Uhr
Es bedeutet, dass Ihr Programm UB hat.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
15. Januar 2020 um 20:10 Uhr
Es bedeutet, dass die Deklarationsregel vom Typ “Spirale” von C viel zu kompliziert ist. Es gibt einen Grund dafür, dass praktisch jede andere statisch typisierte Sprache, die nicht direkt von C abstammt, stattdessen Regeln von links nach rechts verwendet.
– Maurer Wheeler
15. Januar 2020 um 22:39 Uhr
@MasonWheeler „Spiral“ ist ein urbaner Mythos. Die Deklaration ist so viel oder so wenig “Spirale”, wie es der entsprechende Ausdruck wäre. Operatoren werden einfach mit Vorrang und von links nach rechts angewendet (was Ihnen hier natürlich nichts Neues sagt): “Ich muss es dereferenzieren, dann aufrufen, und das Ergebnis hat den Typ void”: voila, Zeiger auf void-Funktion .
– Peter – Setzen Sie Monica wieder ein