Inspiré par une question StackOverflow maintenant supprimée . Pouvez-vous trouver un moyen d’exécuter une méthode particulière sans l’appeler explicitement? Plus c'est indirect, mieux c'est.
Voici ce que je veux dire exactement (C utilisé uniquement à des fins d’exemplification, toutes les langues acceptées):
// 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;
}
Question originale:
popularity-contest
function
Communauté
la source
la source
Réponses:
C
Lorsqu'il est compilé avec GCC, le compilateur remplace
printf("Goodbye!\n")
parputs("Goodbye!")
, ce qui est plus simple et supposé être équivalent. J'ai fourni sournoisement maputs
fonction personnalisée , de sorte que celle-ci soit appelée à la place.la source
Comment un logiciel malveillant peut-il exécuter des fonctions qui ne sont pas appelées dans le code? En débordant de tampons!
Sur mon système, l'adresse de retour de
main
se trouve être stockée 3 mots au-dessus de la première variable locale. En brouillant cette adresse de retour avec l'adresse d'une autre fonction,main
"retourne" à cette fonction. Si vous souhaitez reproduire ce problème sur un autre système, vous devrez peut-être ajuster 3 sur une autre valeur.la source
<!-- language: lang-c -->
deux lignes avant votre code pour le mettre en évidence.Frapper
la source
Python 2
Voici quelques exemples inspirés par les autres réponses:
exécuter le code directement
C'est le meilleur moyen de ne pas appeler la fonction.
en utilisant le destructeur
Utilisation de la std I / O
utiliser des recherches d'attributs
Le mécanisme d'importation
Eh bien, je suppose que c'est tout .. Je ne peux rien importer pour le moment. Non attends..
Utiliser les crochets get-item
[]
Utilisation de variables globales. Mon préféré!
hello
est un accès àd['hello']
. Après cela, le monde semble gris.Méta classes;)
Utilisation d'itérateurs (vous pouvez surcharger n'importe quel opérateur et l'utiliser)
Les erreurs!
Les cadres vous rappellent. Presque toutes les interfaces graphiques ont cette fonctionnalité.
Exécuter la chaîne source (func doit être dans un fichier)
Décorateurs
avec désérialisation des cornichons (moins de favoris à venir)
Utiliser la sérialisation
Plus de réponses Python:
hasattr
globals()
et__call__
indirectementreprlib
la source
Javascript
Celui-ci utilise JSFuck pour faire le sale boulot.
la source
""
est une chaîne,[]
évaluée à 0, donc""[[]]
non définie et""[[]]+""
"non définie". De là, vous pouvez extraire des lettres individuelles:(""[[]]+"")[[]]
est "u". Donc, cela ressemble plus à un hack pour appeler exec avec du code arbitraire. Je pense que ça compte?function anonymous() { x() }
.Python
Cela définit
the_function
comme fonction de profilage, ce qui entraîne son exécution à chaque appel et retour de fonction.la source
C #
Nous pouvons abuser du DLR pour toujours exécuter du code lorsque vous essayez d'appeler une méthode sur une classe. C’est un peu moins cher / évident que des solutions telles que délégués, réflexions, constructeurs statiques, etc., car la méthode en cours d’exécution n’est non seulement jamais invoquée, ni même référencée , pas même par son nom.
Ceci affiche toujours "Ha! Vous a trompé!" peu importe ce que vous essayez d'invoquer
a
. Donc, je pourrais tout aussi bien écrirea.SuperCaliFragilisticExpiAlidocious()
et cela ferait la même chose.la source
GNU C
C'est très direct, mais ce n'est certainement pas un appel à
hello_world
, même si la fonction est exécutée.la source
Rubis
Inspiré par wat .
la source
C
Vous pouvez enregistrer une fonction à appeler à la fin du programme en C, si cela répond à vos besoins:
la source
Java
Essayé avec java:
La méthode
secretMethodNotCalledInMain
est appelée uniquement par réflexion et je ne cherche riensecretMethodNotCalledInMain
(mais je cherche quelque chose qui n’est pas appelémain
). En outre, la partie réfléchissante du code est appelée en dehors de lamain
méthode lorsque le gestionnaire d'exceptions non capturé du JDK entre en jeu.Voici mes informations JVM:
Voici le résultat de mon programme:
Je ne m'attendais pas à ce que ces
NullPointerException
codes soient gérés par le code natif pour gérer la réflexion. Mais, comme mentionné par @ johnchen902, c'est parce qu'il hérite de certaines méthodes dejava.lang.Object
et que j'ai fini par les appeler surnull
s.la source
NPE
ne sont pas des bogues JDK. Ils sont lancés parce que vous avez essayé d'invoquer des méthodes d'instance déclaréesjava.lang.Object
telles quetoString()
withnull
.C ++
Une façon en C ++ est dans le constructeur et / ou le destructeur d'un objet statique:
la source
new
. Ce serait donc une réponse intéressante de pouvoir invoquer un constructeur sansnew
. Mais je ne sais pas, les constructeurs statiques ont l’impression de tricher.new (p) foo()
. Et vous pouvez détruire un objet sans libérer la mémoire viap->~foo()
.C: Bonjour tout le monde
Sortie:
Afin de lier la méthode, nous avons besoin de printf () pour être compilé quelque part dans le programme, mais il n’est pas nécessaire de l’appeler. Les fonctions printf () et main () sont distantes de 276 octets dans le segment de code. Cette valeur changera en fonction du système d'exploitation et du compilateur. Vous pouvez trouver les adresses réelles sur votre système avec ce code, puis les soustraire:
la source
*
avantmain
est vraiment déroutant et inutile.main
est une fonction que vous ne pouvez pas déréférencer, elle se décompose donc implicitement en un pointeur de fonction qui est ensuite déréférencé pour produire à nouveau une fonction. Vous ne pouvez pas soustraire un int d'une fonction, il se décompose alors en un pointeur de fonction. Vous pourriez aussi bien écrire(*****main-276)
;) Vous vouliez probablement écrire(&main-276)
ou à la(*(main-276))
place.The * before main is really confusing and unnecessary.
- N'est-ce pas généralement une bonne chose sur ce site?main
, mais ne le trouve pas maintenant ...C (avec GCC inline asm)
Cela provoquera que du code émis par GCC se retrouve dans un segment différent du fichier objet, ce qui rendra le flux de contrôle «inutilisé» par la fonction. Notez que cela ne fonctionne pas si GCC décide de réorganiser les fonctions, évidemment. Testé avec GCC 3.4.6 sur MirBSD-current / i386, en utilisant
-O2
. (En outre, il interrompt le débogage, la compilation avec des-g
erreurs sur)la source
PHP ≥5.4.0
Cette solution est certes un gâchis horrible, mais elle accomplit la tâche qui lui est confiée (il n’était pas précisé à quel point elle devait bien fonctionner).
La fonction à appeler sans appeler :
La solution :
Exemple :
Sorties possibles:
Explication :
Lorsqu’il est appelé,
executeFunction()
lit le contenu du fichier en cours d’exécution (c’est-à-dire qu’il doit uniquement être exécuté à partir de la CLI, comme il l’utilise$argv
), analyse les arguments et le corps de la fonction spécifiée, scinde tout dans un nouveau bloc code,eval()
tout cela, et retourne le résultat. Le résultat étant qu'ilgetRandomString()
n'est jamais appelé, que ce soit directement ou indirectement, mais le code dans le corps de la fonction est toujours exécuté.la source
__construct()
méthodes compte-t-elle en PHP puisque vous n’appelez jamais la fonction directement, mais utiliseznew Something()
plutôt?register_tick_function()
,register_shutdown_function()
ouspl_autoload_register()
similaire à la réponse Python de @ grc, mais je sens que c'est de la "triche" et une solution de facilité.Perl
Oui, c'est tout ce qu'il y a à dire. Tous les sous-programmes ne sont pas créés égaux.
la source
T-SQL
C'est une fonctionnalité intégrée. Des déclencheurs pour la victoire!
Si vous voulez vraiment vous amuser avec cela, créez un ensemble de déclencheurs INSTEAD OF le jour du poisson d’avril.
Résultats:
Très blague. Tel lulz. Sensationnel.
Tinker élargissez-le sur SQLFiddle.
la source
JavaScript
Dans la console Firefox:
Ensuite, commencez à taper n'importe quoi dans la console - Firefox appelle
.toString()
plusieurs fois lorsque vous tapez dans la console.Approche similaire est:
la source
C
La plate-forme de choix est Linux. Nous ne pouvons pas appeler notre fonction, nous allons donc laisser notre éditeur de liens le faire à la place:
Comment obtenir l'adresse magique?
Nous nous appuyons sur la spécification Linux Standard Base Core, qui dit:
Compilez le code:
gcc but_for_what_reason_exactly.c -o but_for_what_reason_exactly
Examiner l'adresse de
.fini_array
:objdump -h -j .fini_array but_for_what_reason_exactly
Trouvez le VMA de celui-ci:
et remplacez cette valeur pour
ADDRESS
.la source
VB6 et VBA
Je ne sais pas si cela est admissible ou non, car il appelle une méthode d'une classe:
Cela va dans un module de classe:
Et voici le code "appelant":
Cela fonctionne en échangeant la fonction vptr pour les deux sous dans la vtable pour la classe.
la source
Haskell
En haskell si vous le faites:
Il sera exécuté immédiatement sans appeler son nom lorsque vous l'exécutez. La magie!
la source
Javascript
Facile, utilisez simplement des
on___
événements dans JS. Par exemple:la source
Java
Autre réponse java de ma part. Comme vous le voyez dans le code, il appelle directement
theCalledMethod
, mais la méthodenotCalledMethod
est exécutée à la place.Donc, au final, je fais 2 choses:
Le lancer:
la source
getBytes()
méthode, en l'activantgetBytes("UTF-8")
. Puisque je n'ai pas OS X, pourriez-vous vérifier si cela fonctionne?Python
la source
Java
Oui, la collecte des ordures!
Une version pour ceux qui diront inévitablement que ce
System.gc()
n'est pas fiable:la source
Objectif c
(Probablement seulement si compilé avec clang sous Mac OS X)
Ce code utilise plusieurs astuces pour accéder à la fonction non utilisée. Le premier est la valeur 0x2A27. Il s'agit d'un pointeur balisé pour le nombre entier 42, qui code la valeur dans le pointeur pour éviter d'affecter un objet.
Suivant est
MyClass
. Il n'est jamais utilisé, mais le runtime appelle la+load
méthode lorsqu'elle est chargée, avantmain
. Cela crée et enregistre dynamiquement une nouvelle classe en utilisantNSValue
comme super-classe. Il ajoute également une+load
méthode pour cette classe, en utilisantMyClass
s-unusedMethod
comme implémentation. Après l’enregistrement, il appelle la méthode de chargement sur la nouvelle classe (pour une raison quelconque, il n’est pas appelé automatiquement).Étant donné que la méthode de chargement de la nouvelle classe utilise la même implémentation
unusedMethod
, elle est effectivement appelée. Il prend la superclasse de lui-même et ajouteunusedFunction
une implémentation pour ladoesNotRecognizeSelector:
méthode de cette classe . Cette méthode était à l'origine une méthode d'instanceMyClass
, mais elle est appelée en tant que méthode de classe sur la nouvelle classe, de même queself
le nouvel objet de classe. Par conséquent, la super-classe estNSValue
, qui est également la super-classe deNSNumber
.Enfin,
main
court. Il prend la valeur du pointeur et la colle dans uneNSString *
variable (la__bridge
première et la première conversionvoid *
permettant son utilisation avec ou sans ARC). Ensuite, il tente d’appelerstringByAppendingString:
cette variable. Puisqu'il s'agit en fait d'un nombre qui n'implémente pas cette méthode, ladoesNotRecognizeSelector:
méthode est appelée à la place, qui parcourt la hiérarchie des classes jusqu'àNSValue
son implémentationunusedFunction
.Remarque: l'incompatibilité avec d'autres systèmes est due à l'utilisation du pointeur étiqueté, qui, à mon avis, n'a pas été implémentée par d'autres implémentations. Si cela était remplacé par un nombre normalement créé, le reste du code devrait fonctionner correctement.
la source
0x2A27
valeur, donc je ne sais pas si cela est mis en œuvre ailleurs. ObjFW est certainement intéressant cependant.0x2A27
est étiqueté pointeurJavascript
Je sens que cela ne ressemble pas explicitement à l'appel de la fonction
la source
C # (via
using
)la source
Java
Je profite d'une fonctionnalité particulière de la sérialisation Java. La
readObject
méthode est appelée lorsqu'un objet est désérialisé, mais il n'est pas appelé directement - ni par mon code, ni par la bibliothèque de désérialisation. Si vous creusez profondément dans la source, vous verrez que, à un niveau bas, la méthode est appelée en interne par réflexion.la source
Perl
C'est si facile. Le code ci-dessous est automatiquement exécuté dans le sous-programme, même sans appel explicite.
Même si vous décommentez l'appel, il ne sera appelé qu'une seule fois.
la source