Ich löse eine binäre Exploitation-Herausforderung auf picoCTF und bin auf diesen Code gestoßen:
((void (*)())buf)();
Wo buf
ist ein Zeichenarray?
Ich habe die Herausforderung gelöst, kann aber nicht verstehen, was genau es tut. Ich habe mir diesen Thread angesehen, konnte ihn aber nicht erkennen.
Was heißt ((void (*)())buf)();
das
c
function
pointers
function-pointers
sh.3.ll
quelle
quelle
((void (*)())buf)();
das Es bedeutet, dass der Autor nicht verstehttypedef
.typedef void (*voidFuncPtrType)();
würde diesen Code klar machen.Antworten:
void (*)()
ist ein Typ, wobei der Typ "Zeiger auf eine Funktion ist, die unbestimmte Argumente akzeptiert und keinen Wert zurückgibt".(void (*)())
ist eine Typumwandlung zum obigen Typ.(void (*)())buf
wirftbuf
auf den oben genannten Typ.((void (*)())buf)()
ruft die Funktion auf (ohne Argumente).Kurz gesagt: Er weist den Compiler an,
buf
als Zeiger auf eine Funktion zu behandeln und diese Funktion aufzurufen.quelle
cdecl
Dienstprogramm (oder die Website ) hilfreich, um die komplexeren C-Ausdrücke ins Englische zu übersetzen.buf
odercopy
an einer ausführbaren Adresse befindet und der Code selbst positionsunabhängig ist, funktioniert dies. 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, in denen das No-Execute-Bit (NX) für Stack und Heap nicht gesetzt ist.Der Zeiger
buf
wird unter Verwendung einer nicht spezifizierten Anzahl von Parametern in die Zeigerfunktion für ungültig konvertiert und dann dereferenziert (dh die aufgerufene Funktion).quelle
Es ist eine Typumwandlung, gefolgt von einem Funktionsaufruf. Zunächst
buf
wird auf den Zeiger auf eine Funktion umgewandelt, die zurückgibtvoid
. Das letzte Klammerpaar bedeutet, dass die Funktion dann aufgerufen wird.quelle
Es wandelt das Zeichenarray in einen Zeiger auf eine Funktion um, die keine Argumente akzeptiert und zurückgibt
void
, und ruft es dann auf. Eine Dereferenzierung des Zeigers ist aufgrund der Funktionsweise von Funktionszeigern nicht erforderlich.Eine Erklärung:
Dieses "Zeichenarray" ist eigentlich ein Array von Maschinencode. Wenn Sie das Array in a
void (*)()
umwandeln und es aufrufen, wird der Maschinencode innerhalb des Arrays ausgeführt. Wenn Sie den Inhalt des Arrays bereitstellen würden, könnte ich es für Sie zerlegen und Ihnen sagen, was es tut.quelle