2016-03-23 17 views
1

Können wir kürzer (zeichenweise) oder eleganter als:Shortest C++ Code eine Zugriffsverletzung verursachen

*(int*)0=0; 

Das Ziel ist, eine Zugriffsverletzung zu erhöhen. Plattformunabhängige Lösungen sind bevorzugt.

+2

Wenn Sie ein einzelnes Zeichen typedef an anderer Stelle verstecken (möglicherweise ein Vorlagenparameter), können Sie 2 Zeichen von Ihrem Weg abspeichern. – o11c

Antwort

2

Angenommen, Sie sind nicht beinhaltet in Ihren Charakter einschließlich zählen

Für Linux:

raise(11); //SIGSEGV 

Für Windows:

raise(SIGSEGV); // I don't know the SIGSEGV value for sure so more characters required 
+1

Für Windows ist es nicht so kurz und knapp: RaiseException (STATUS_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL); https://msdn.microsoft.com/en-us/library/windows/desktop/ms680552(v=vs.85).aspx –

+1

Nun, es ist hier: https://msdn.microsoft.com/en-us /library/dwwzkt4c.aspx – MasterID

+0

Du musst das compat-Team lieben :) –

0

Von einem Unix (hauptsächlich Linux) Perspektive:

Wenn wir "Zugriffsverletzung" als "irgendein Signal" definieren, füllt das si_addr Gebiet der siginfo_t, dann nach sigaction(2), die: SIGILL, SIGFPE, SIGSEGV, SIGBUS, and SIGTRAP. durch Ausführen jede ungültige Anweisung erzeugt werden, einschließlich permanent ungültige Befehle wie ud2 auf x86 (codiert als 0x0F 0x0B)

  • SIGILL kann, aber zu einem zufälligen Punkt springt ohnehin oft erzeugt diese.

  • SIGFPE durch Dividieren beliebige ganze Zahl von 0 oder Dividieren der negativsten ganze Zahl von -1

  • SIGSEGV erzeugt werden kann durch eine Lese- oder Schreib auf jede nicht zugeordnete oder PROT_NONE ‚d-Seite oder einer Schreib erzeugt werden, um eine schreibgeschützte Seite

  • SIGBUS habe ich nie herausgefunden, wo es herkommt.

  • SIGTRAP kann vom Bogen des Unterbrechungspunkt-Befehl erzeugt werden, die auf x86 int3 ist, die 0xcc das einzelne Byte ist. Aus einer Perspektive ist das der kürzeste mögliche Code. Wenn Sie auf der shorest möglich beharren C Code würden Sie es in einem asm Block nach Ihren Compiler Launen wickeln müssen.

Es gibt auch andere Beispiele syscalls wie kill beteiligt sind.

+0

erhöhen (SIGSEGV); scheint am nächsten, trotzdem ist der Code nicht kürzer. –

1

Es gibt keine tragbare Art und Weise eine Segmentierungsverletzung oder eine andere ähnliche Fehler zu verursachen.

Compiler können und davon ausgehen, dass nicht definierte Verhalten tritt nie. Wenn sie UB in einem bestimmten Code-Zweig entdecken, haben sie das Recht, den gesamten Zweig zu optimieren.

Ein Compiler kann diesen Codeblock in einen No-Op übersetzen.

raise(SIGSEGV) kann oder auch nicht eine tatsächliche Verletzung verursachen, aber es ist die einzige tragbare Art und Weise der Ursache ein Programm zu verhalten, als ob eine Verletzung aufgetreten ist.

+0

Welcher Compiler würde das tun? Irgendwelche von GCC, MSVC, XCode oder Clang? –

+0

Ich weiß nicht von einem aktuellen Compiler, der genau dies tut, aber einige tun sehr ähnliche Dinge. Schauen Sie [hier] (http://ideone.com/gilyHa). Das Programm sollte in der dritten Iteration abgestürzt sein, oder? Und warum endet die Schleife nicht? –

+0

Clang wird Sie warnen, dass "Indirektion des nichtflüchtigen Nullzeigers wird gelöscht werden, nicht Trap", aber AFAICT es tatsächlich nicht die Indirektion löschen. Siehe [dies] (https://llvm.org/bugs/show_bug.cgi?id=23831) –

1

Hier ist die nächste, die ich aus dem OP und MasterID mit einem anderen Ansatz kommen könnte:

asm("ret");

Die Idee ist, den Stapel so plump wie möglich zu manipulieren. Ich glaube, gcc wird das kompilieren.

Verwandte Themen