Inspiriert von einer nun gelöschten StackOverflow-Frage . Können Sie einen Weg finden, eine bestimmte Methode auszuführen, ohne sie explizit aufzurufen? Je indirekter es ist, desto besser.
Folgendes meine ich genau (C dient nur zur Veranschaulichung, alle Sprachen werden akzeptiert):
// Call this.
void the_function(void)
{
printf("Hi there!\n");
}
int main(int argc, char** argv)
{
the_function(); // NO! Bad! This is a direct call.
return 0;
}
Ursprüngliche Frage:
popularity-contest
function
Gemeinschaft
quelle
quelle
Antworten:
C
Wenn mit GCC kompiliert, ersetzt die Compiler
printf("Goodbye!\n")
mitputs("Goodbye!")
, was einfacher ist , und sollte gleich sein. Ich habe meine benutzerdefinierteputs
Funktion im Handumdrehen bereitgestellt , sodass sie stattdessen aufgerufen wird.quelle
Wie kann Malware Funktionen ausführen, die nicht im Code aufgerufen werden? Durch überlaufende Puffer!
Auf meinem System wird die Rücksprungadresse von
main
zufällig 3 Wörter über der ersten lokalen Variablen gespeichert. Durch Verwürfeln dieser Rücksprungadresse mit der Adresse einer anderen Funktionmain
"kehrt" zu dieser Funktion zurück. Wenn Sie dieses Verhalten auf einem anderen System reproduzieren möchten, müssen Sie möglicherweise 3 auf einen anderen Wert einstellen.quelle
<!-- language: lang-c -->
zwei Zeilen vor Ihrem Code, um ihn hervorzuheben.Bash
quelle
Python 2
Hier sind einige von den anderen Antworten inspirierte Möglichkeiten:
Code direkt ausführen
Dies ist die beste Möglichkeit, die Funktion wirklich nicht aufzurufen.
mit dem Destruktor
Verwenden der Standard-E / A
Verwenden von Attributsuchen
Der Importmechanismus
Naja ich denke das ist alles .. ich kann jetzt nichts importieren. Nein warte ..
Verwenden der get-item-Klammern
[]
Globale Variablen verwenden. Mein Favorit!
hello
ist ein Zugang zud['hello']
. Danach scheint die Welt grau.Meta Klassen;)
Verwenden von Iteratoren (Sie können jeden Operator überladen und verwenden)
Fehler!
Frameworks rufen Sie zurück. Fast jede GUI verfügt über diese Funktionalität.
Führe den Quelltext aus (func muss in einer Datei sein)
Dekorateure
mit Pickle-De-Serialisierung (die wenigsten Favoriten kommen)
Serialisierung verwenden
Weitere Python-Antworten:
hasattr
globals()
und__call__
indirektreprlib
quelle
Javascript
Dieser benutzt JSFuck , um die Drecksarbeit zu erledigen.
quelle
""
ist eine Zeichenfolge und wird[]
mit 0 ausgewertet,""[[]]
ist also undefiniert und""[[]]+""
ist "undefiniert". Von dort können Sie einzelne Buchstaben herausziehen:(""[[]]+"")[[]]
ist "u". Es ist also eher ein Hack, exec mit beliebigem Code aufzurufen. Ich denke das zählt?function anonymous() { x() }
.Python
Dies wird
the_function
als Profilierungsfunktion festgelegt, die bei jedem Funktionsaufruf und bei jeder Rückkehr ausgeführt wird.quelle
C #
Wir können das DLR missbrauchen, um immer Code auszuführen, wenn Sie versuchen, eine Methode für eine Klasse aufzurufen . Dies ist etwas weniger billig / offensichtlich als Lösungen wie Delegates, Reflections, statische Konstruktoren usw., da die ausgeführte Methode nicht nur nie aufgerufen, sondern auch nie referenziert wird , auch nicht nach ihrem Namen.
Dieses druckt immer "Ha! Sie betrogen!" egal worauf du dich berufen willst
a
. Also könnte ich genauso gut schreibena.SuperCaliFragilisticExpiAlidocious()
und es würde dasselbe tun.quelle
GNU C
Dies ist sehr direkt, aber sicherlich kein Aufruf an
hello_world
, obwohl die Funktion ausgeführt wird.quelle
Rubin
Inspiriert von wat .
quelle
C
Sie können eine Funktion, die am Ende des Programms aufgerufen werden soll, in C registrieren, wenn dies Ihren Anforderungen entspricht:
quelle
Java
Versuchte dies mit Java:
Die Methode
secretMethodNotCalledInMain
wird nur durch Reflektion aufgerufen und ich suche nicht nach etwas, das aufgerufen wirdsecretMethodNotCalledInMain
(stattdessen suche ich nach etwas, das nicht aufgerufen wirdmain
). Darüber hinaus wird der reflektierende Teil des Codes außerhalb dermain
Methode aufgerufen , wenn der nicht erfasste Ausnahmehandler des JDK aktiviert wird.Hier ist meine JVM-Info:
Hier ist die Ausgabe meines Programms:
Ich hatte nicht damit gerechnet, dass diese
NullPointerException
aus dem nativen Code geworfen werden, um die Reflektion zu handhaben. Aber, wie von @ johnchen902 erwähnt, weil es einige Methoden von erbtjava.lang.Object
und ich sie schließlich aufnull
s aufrief .quelle
NPE
sind keine JDK-Fehler. Sie werden ausgelöst, weil Sie versucht haben, Instanzmethoden aufzurufen, diejava.lang.Object
wietoString()
mit deklariert wurdennull
.C ++
Eine Möglichkeit in C ++ besteht im Konstruktor und / oder Destruktor eines statischen Objekts:
quelle
new
, und daher wäre es eine interessante Antwort, eine Möglichkeit zu haben , einen Konstruktor ohne aufzurufennew
. Aber ich weiß nicht, statische Konstruktoren fühlen sich wie ein Betrüger an.new (p) foo()
. Und Sie können ein Objekt zerstören, ohne den Speicher über freizugebenp->~foo()
.C: Hallo Welt
Ausgabe:
Um die Methode zu verlinken, muss printf () irgendwo im Programm kompiliert werden, muss aber nicht aufgerufen werden. Die Funktionen printf () und main () befinden sich im Codesegment 276 Byte voneinander entfernt. Dieser Wert ändert sich je nach Betriebssystem und Compiler. Mit diesem Code können Sie die tatsächlichen Adressen auf Ihrem System finden und sie dann einfach subtrahieren:
quelle
*
Vorhermain
ist wirklich verwirrend und unnötig.main
Ist eine Funktion, die Sie nicht dereferenzieren können. Sie verfällt implizit in einen Funktionszeiger, der dann dereferenziert wird, um wieder eine Funktion zu erhalten. Sie können ein int nicht von einer Funktion subtrahieren, daher verwandelt es sich wieder in einen Funktionszeiger. Du könntest genauso gut schreiben(*****main-276)
;) Du wolltest wahrscheinlich schreiben(&main-276)
oder(*(main-276))
stattdessen.The * before main is really confusing and unnecessary.
- Ist das nicht generell eine gute Sache auf dieser Seite?main
, es aber jetzt nicht finden kann ...C (mit GCC inline asm)
Dies führt dazu, dass ein Teil des von GCC ausgegebenen Codes in einem anderen Segment der Objektdatei landet, wodurch der Steuerungsfluss durch die Funktion "fallen" kann. Beachten Sie, dass dies nicht funktioniert, wenn GCC die Funktionen offensichtlich neu anordnet. Getestet mit GCC 3.4.6 auf MirBSD-current / i386 unter Verwendung von
-O2
. (Außerdem bricht es das Debuggen ab und kompiliert mit-g
Fehlern heraus ☺)quelle
PHP ≥5.4.0
Diese Lösung ist zwar ein schreckliches Durcheinander, erfüllt aber die ihr übertragene Aufgabe (es gab keine Vorgabe, wie gut sie zu erfüllen ist).
Die Funktion zum Aufrufen ohne Aufrufen :
Die lösung :
Beispiel :
Mögliche Ausgaben:
Erklärung :
Liest beim Aufruf
executeFunction()
den Inhalt der aktuell ausgeführten Datei (was bedeutet, dass dies nur von CLI ausgeführt werden soll, wie es verwendet wird$argv
), parst die Argumente und den Hauptteil der angegebenen Funktion aus und zerhackt alles wieder in einen neuen Block Code,eval()
alles und das Ergebnis zurück. Das Ergebnis ist, dassgetRandomString()
weder direkt noch indirekt tatsächlich aufgerufen wird, der Code im Funktionskörper jedoch weiterhin ausgeführt wird.quelle
__construct()
Methoden in PHP, da Sie die Funktion nie direkt aufrufen, sondernnew Something()
stattdessen verwenden?register_tick_function()
,register_shutdown_function()
oderspl_autoload_register()
ähnlich wie @ grc Python Antwort, aber ich fühle mich wie das ist ‚Betrug‘ und die einfache Art und Weise herausnimmt.Perl
Ja, das ist alles was dazu gehört. Nicht alle Unterprogramme sind gleich.
quelle
T-SQL
Es ist eine eingebaute Funktion. Auslöser für den Gewinn!
Wenn Sie wirklich Spaß damit haben möchten, erstellen Sie am Aprilscherz eine Reihe von INSTEAD OF-Triggern.
Ergebnisse:
Sehr Streich. Solcher Lulz. Beeindruckend.
Bastel es auf SQLFiddle.
quelle
JavaScript
In der Firefox-Konsole:
Geben Sie dann einfach etwas in die Konsole ein - Firefox ruft
.toString()
mehrmals auf, wenn Sie in die Konsole tippen.Ein ähnlicher Ansatz ist:
quelle
C
Plattform der Wahl ist Linux. Wir können unsere Funktion nicht aufrufen, also lassen wir sie stattdessen von unserem Linker ausführen:
Wie erhalte ich die magische Adresse?
Wir verlassen uns auf die Linux Standard Base Core-Spezifikation, die besagt:
Kompilieren Sie den Code:
gcc but_for_what_reason_exactly.c -o but_for_what_reason_exactly
Überprüfen Sie die Adresse von
.fini_array
:objdump -h -j .fini_array but_for_what_reason_exactly
Finden Sie die VMA davon:
und ersetze diesen Wert für
ADDRESS
.quelle
VB6 und VBA
Nicht sicher, ob dies qualifiziert ist oder nicht, da es eine Methode einer Klasse aufruft:
Dies geht in einem Klassenmodul:
Und das ist der "aufrufende" Code:
Dies funktioniert durch Austauschen der Funktion vptr für die beiden Subs in der vtable für die Klasse.
quelle
Haskell
In haskell, wenn Sie:
Es wird sofort ausgeführt, ohne seinen Namen zu nennen, wenn Sie es ausführen. Magie!
quelle
Javascript
Einfach, verwenden Sie einfach
on___
Ereignisse in JS. Zum Beispiel:quelle
Java
Andere Java-Antwort von mir. Wie Sie im Code sehen, ruft es direkt auf
theCalledMethod
, aber die MethodenotCalledMethod
wird stattdessen ausgeführt.Am Ende mache ich also zwei Dinge:
Laufen es:
quelle
getBytes()
Methode übergeben und diese aktivierengetBytes("UTF-8")
. Könnten Sie testen, ob dies funktioniert, da ich kein OS X besitze?Python
quelle
Java
Ja, Müllabfuhr!
Eine Version für diejenigen, die unweigerlich sagen, dass
System.gc()
das unzuverlässig ist:quelle
Ziel c
(Wahrscheinlich nur, wenn unter Mac OS X mit Clang kompiliert)
Dieser Code verwendet mehrere Tricks, um zur nicht verwendeten Funktion zu gelangen. Erstens ist der Wert 0x2A27. Dies ist ein markierter Zeiger für die Ganzzahl 42, die den Wert im Zeiger codiert, um die Zuweisung eines Objekts zu vermeiden.
Weiter ist
MyClass
. Es wird nie verwendet, aber die Laufzeit ruft die+load
Methode beim Laden vorher aufmain
. Dadurch wird dynamisch eine neue Klasse erstellt und registriert, dieNSValue
als Oberklasse verwendet wird. Es wird auch eine+load
Methode für diese Klasse hinzugefügt, dieMyClass
's-unusedMethod
als Implementierung verwendet. Nach der Registrierung wird die load-Methode für die neue Klasse aufgerufen (aus irgendeinem Grund wird sie nicht automatisch aufgerufen).Da die Lademethode der neuen Klasse dieselbe Implementierung wie verwendet
unusedMethod
, wird dies effektiv aufgerufen. Es nimmt die Superklasse von sich und fügt sieunusedFunction
als Implementierung für diedoesNotRecognizeSelector:
Methode dieser Klasse hinzu . Diese Methode war ursprünglich eine Instanzmethode vonMyClass
, wird jedoch als Klassenmethode für die neue Klasse aufgerufen, ebenso wieself
das neue Klassenobjekt. Daher ist die SuperklasseNSValue
, für die auch die Superklasse istNSNumber
.Endlich
main
läuft. Es nimmt den Zeigerwert und speichert ihn in einerNSString *
Variablen (die__bridge
und erste Umwandlung,void *
um dies mit oder ohne ARC zu ermöglichen). Dann wird versucht,stringByAppendingString:
diese Variable aufzurufen . Da es sich tatsächlich um eine Zahl handelt, die diese Methode nicht implementiert,doesNotRecognizeSelector:
wird stattdessen die Methode aufgerufen, die durch die Klassenhierarchie dahin wandert,NSValue
wo sie mit implementiert wirdunusedFunction
.Hinweis: Die Inkompatibilität mit anderen Systemen ist auf die Verwendung von getaggten Zeigern zurückzuführen, die meines Erachtens nicht von anderen Implementierungen implementiert wurden. Wenn dies durch eine normal erstellte Nummer ersetzt wird, sollte der Rest des Codes einwandfrei funktionieren.
quelle
0x2A27
Wert, daher weiß ich nicht, ob das irgendwo anders implementiert ist. ObjFW ist auf jeden Fall interessant.0x2A27
is tagged pointerJavascript
Ich habe das Gefühl, dass dies nicht explizit so aussieht, als würde es die Funktion aufrufen
quelle
C # (via
using
)quelle
Java
Ich nutze eine Besonderheit der Java-Serialisierung. Die
readObject
Methode wird aufgerufen, wenn ein Objekt deserialisiert wird, aber nicht direkt aufgerufen wird - weder von meinem Code noch von der Deserialisierungsbibliothek. Wenn Sie tief in die Quelle eintauchen, werden Sie feststellen, dass die Methode auf niedriger Ebene intern über Reflektion aufgerufen wird.quelle
Perl
Das ist so einfach. Der folgende Code führt automatisch Code im Unterprogramm aus, auch ohne expliziten Aufruf.
Auch wenn Sie den Anruf auskommentieren, wird er nur einmal aufgerufen.
quelle