Zainspirowany usuniętym pytaniem StackOverflow . Czy potrafisz wymyślić sposób wykonania określonej metody bez wyraźnego jej wywołania? Im bardziej pośredni, tym lepiej.
Oto, o co mi dokładnie chodzi (C użyte tylko do zilustrowania, wszystkie języki są akceptowane):
// 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;
}
Oryginalne pytanie:
popularity-contest
function
Społeczność
źródło
źródło
Odpowiedzi:
do
Po kompilacji za pomocą GCC kompilator zamienia
printf("Goodbye!\n")
się naputs("Goodbye!")
, co jest prostsze i powinno być równoważne. Podstępnie podałem swoją niestandardowąputs
funkcję, więc zamiast niej jest wywoływana.źródło
Jak złośliwe oprogramowanie może wykonywać funkcje, które nie są wywoływane w kodzie? Przepełnione bufory!
W moim systemie adres zwrotny
main
zdarza się przechowywać 3 słowa nad pierwszą zmienną lokalną. Mieszając ten adres zwrotny z adresem innej funkcji,main
„wraca” do tej funkcji. Jeśli chcesz odtworzyć to zachowanie w innym systemie, może być konieczne dostosowanie 3 do innej wartości.źródło
<!-- language: lang-c -->
dwóch linii przed kodem, aby go podświetlić.Grzmotnąć
źródło
Python 2
Oto kilka sposobów inspirowanych innymi odpowiedziami:
wykonanie kodu bezpośrednio
Jest to najlepszy sposób, aby naprawdę nie wywoływać funkcji.
za pomocą destruktora
Korzystanie ze standardowego wejścia / wyjścia
za pomocą wyszukiwania atrybutów
Mechanizm importu
Myślę, że to wszystko .. Nie mogę teraz niczego importować. Nie, czekaj..
Korzystanie z nawiasów get-item
[]
Korzystanie ze zmiennych globalnych. Mój ulubiony!
hello
jest dostępem dod['hello']
. Po tym świat wydaje się szary.Klasy Meta;)
Korzystanie z iteratorów (możesz przeciążyć dowolnego operatora i użyć go)
Błędy!
Ramy oddzwonią. Prawie każdy GUI ma tę funkcjonalność.
Wykonaj łańcuch źródłowy (func musi znajdować się w pliku)
Dekoratorzy
z serializacją pikle (najmniej ulubionych)
Korzystanie z serializacji
Więcej odpowiedzi na Python:
hasattr
globals()
i__call__
pośrednioreprlib
źródło
JavaScript
Ten używa JSFuck do brudnej roboty.
źródło
""
jest łańcuchem i przyjmuje[]
wartość 0, więc""[[]]
jest niezdefiniowany i""[[]]+""
jest „niezdefiniowany”. Stamtąd możesz wyciągać pojedyncze litery:(""[[]]+"")[[]]
jest „u”. Bardziej przypomina to hack, aby wywołać exec z dowolnym kodem. Myślę, że to się liczy?function anonymous() { x() }
.Pyton
Ustawia się to
the_function
jako funkcję profilowania, powodując, że będzie wykonywana przy każdym wywołaniu funkcji i powrocie.źródło
DO#
Możemy nadużywać DLR, aby zawsze uruchamiał jakiś kod za każdym razem, gdy próbujesz wywołać dowolną metodę w klasie. Jest to nieco mniej tani / oczywiste niż rozwiązań takich jak delegatów, odbicia, konstruktorów statycznych, itp, ponieważ metoda wykonywany jest nie tylko nigdy wywoływany ale nigdy nawet odwoływać , nawet jego imienia.
To zawsze drukuje „Ha! Oszukał cię!” bez względu na to , co próbujesz wywołać
a
. Więc mógłbym równie łatwo napisaća.SuperCaliFragilisticExpiAlidocious()
i zrobiłbym to samo.źródło
GNU C
To jest bardzo bezpośredni, ale z pewnością nie jest wezwanie do
hello_world
, nawet jeśli funkcja ma wykonać.źródło
Rubin
Zainspirowany przez wat .
źródło
do
Możesz zarejestrować funkcję, która ma być wywoływana na końcu programu w C, jeśli pasuje to do twoich potrzeb:
źródło
Jawa
Próbowałem tego z java:
Metoda
secretMethodNotCalledInMain
jest wywoływana tylko przez odbicie i nie szukam niczego, co się nazywasecretMethodNotCalledInMain
(zamiast tego szukam czegoś, co nie jest wywoływanemain
). Ponadto odblaskowa część kodu jest wywoływana pozamain
metodą, gdy uruchamia się nieprzechwycony moduł obsługi wyjątków JDK.Oto moje informacje o JVM:
Oto wynik mojego programu:
Nie spodziewałem się,
NullPointerException
że zostaną one wyrzucone z natywnego kodu do obsługi refleksji. Ale, jak wspomniano w @ johnchen902, to dlatego, że dziedziczy on niektóre metodyjava.lang.Object
i ostatecznie wywołałem je nanull
s.źródło
NPE
nie są błędy JDK. Są wyrzucane, ponieważ starał się wywołać metody instancji zgłoszonejava.lang.Object
takie jaktoString()
znull
.C ++
Jednym ze sposobów w C ++ jest konstruktor i / lub destruktor obiektu statycznego:
źródło
new
, więc byłoby ciekawą odpowiedzią na sposób wywołania go bez niegonew
. Ale nie wiem, statyczni konstruktorzy czują się trochę oszukani.new (p) foo()
. I możesz zniszczyć obiekt bez zwalniania pamięci przezp->~foo()
.C: Hello World
Wynik:
Aby połączyć metodę, potrzebujemy skompilować printf () gdzieś w programie, ale nie trzeba go tak naprawdę wywoływać. Funkcje printf () i main () znajdują się 276 bajtów od siebie w segmencie kodu. Ta wartość zmieni się w zależności od systemu operacyjnego i kompilatora. Możesz znaleźć rzeczywiste adresy w systemie za pomocą tego kodu, a następnie po prostu je odejmij:
źródło
*
wcześniej,main
jest naprawdę mylące i niepotrzebne.main
jest funkcją, której nie można wyrejestrować, więc domyślnie rozpada się na wskaźnik funkcji, który jest następnie wyłuskany w celu uzyskania funkcji ponownie. Nie można odjąć liczby całkowitej od funkcji, więc ponownie rozpada się na wskaźnik funkcji. Równie dobrze możesz pisać(*****main-276)
;) Prawdopodobnie chciałeś pisać(&main-276)
lub(*(main-276))
zamiast tego.The * before main is really confusing and unnecessary.
- Czy to ogólnie nie jest dobra rzecz na tej stronie?main
, ale nie może go teraz znaleźć ...C (z wbudowanym asmem GCC)
Spowoduje to, że część kodu emitowanego przez GCC znajdzie się w innym segmencie pliku obiektowego, co sprawi, że przepływ sterowania „spadnie” przez funkcję. Zauważ, że to nie działa, jeśli GCC zdecyduje się zmienić kolejność funkcji, oczywiście. Testowane z GCC 3.4.6 na MirBSD-current / i386, przy użyciu
-O2
. (Poza tym przerywa debugowanie, kompiluje się z-g
błędami ☺)źródło
PHP ≥5.4.0
To rozwiązanie jest wprawdzie okropnym bałaganem, ale wykonuje powierzone mu zadanie (nie było mowy o tym, jak dobrze ma się wykonać).
Funkcja wywoływania bez wywoływania :
Rozwiązanie :
Przykład :
Możliwe wyniki:
Objaśnienie :
Po wywołaniu
executeFunction()
odczyta zawartość aktualnie wykonywanego pliku (co oznacza, że ma on być uruchamiany tylko z CLI, jak używa$argv
), przeanalizuje argumenty i treść określonej funkcji, zhakuje wszystko z powrotem do nowej części kod,eval()
to wszystko i zwróć wynik. W rezultaciegetRandomString()
nigdy nie jest wywoływana, bezpośrednio ani pośrednio, ale kod w treści funkcji jest nadal wykonywany.źródło
__construct()
metod ma znaczenie w PHP, ponieważ nigdy nie wywołujesz funkcji bezpośrednio, alenew Something()
zamiast tego używasz ?register_tick_function()
,register_shutdown_function()
lubspl_autoload_register()
podobne do @ GRC w Pythonie odpowiedź, ale czuję, że jest „oszustwo” i biorąc łatwe wyjście.Perl
Tak, to wszystko. Nie wszystkie podprogramy są sobie równe.
źródło
T-SQL
To wbudowana funkcja. Wyzwalacze do wygranej!
Jeśli naprawdę chcesz się z tym dobrze bawić, utwórz kilka INSTEAD OF trigerów w Prima Aprilis.
Wyniki:
Bardzo dowcip. Taki lulz. Łał.
Tinker rozszerzył to na SQLFiddle.
źródło
JavaScript
W konsoli Firefox:
Następnie po prostu zacznij pisać w konsoli - Firefox wywołuje
.toString()
wiele razy podczas pisania w konsoli.Podobne podejście to:
źródło
do
Platformą z wyboru jest Linux. Nie możemy wywołać naszej funkcji, więc zamiast tego będziemy mieli naszego linkera:
Jak zdobyć magiczny adres?
Opieramy się na standardowej podstawowej specyfikacji rdzenia systemu Linux, która mówi:
Skompiluj kod:
gcc but_for_what_reason_exactly.c -o but_for_what_reason_exactly
Sprawdź adres
.fini_array
:objdump -h -j .fini_array but_for_what_reason_exactly
Znajdź VMA tego:
i zamień tę wartość na
ADDRESS
.źródło
VB6 i VBA
Nie jestem pewien, czy to się kwalifikuje, czy nie, ponieważ wywołuje metodę klasy:
Dotyczy to modułu klasowego:
A to jest kod „wzywający”:
Działa to poprzez zamianę funkcji vptr na dwa Subs w tabeli vt dla klasy.
źródło
Haskell
W haskell, jeśli:
Zostanie wykonany natychmiast, bez wywoływania jego nazwy po uruchomieniu. Magia!
źródło
JavaScript
Łatwe, wystarczy użyć
on___
wydarzeń w JS. Na przykład:źródło
Jawa
Inna odpowiedź od javy. Jak widać w kodzie, wywołuje on bezpośrednio
theCalledMethod
, alenotCalledMethod
zamiast tego metoda jest wykonywana.W końcu robię 2 rzeczy:
Uruchamianie:
źródło
getBytes()
metody, włączając jągetBytes("UTF-8")
. Ponieważ nie mam systemu OS X, czy możesz przetestować, czy to działa?Pyton
źródło
Jawa
Tak, wywóz śmieci!
Wersja dla tych, którzy nieuchronnie powiedzą, że
System.gc()
jest niewiarygodna:źródło
Cel C
(Prawdopodobnie tylko jeśli jest skompilowany z clang na Mac OS X)
Ten kod wykorzystuje kilka sztuczek, aby dostać się do nieużywanej funkcji. Pierwsza to wartość 0x2A27. Jest to oznakowany wskaźnik dla liczby całkowitej 42, który koduje wartość we wskaźniku, aby uniknąć przydzielenia obiektu.
Dalej jest
MyClass
. Nigdy nie jest używany, ale środowisko wykonawcze wywołuje+load
metodę po jej załadowaniu, wcześniejmain
. To dynamicznie tworzy i rejestruje nową klasę, wykorzystującNSValue
jako jej nadklasę. Dodaje również+load
metody dla tej klasy, używającMyClass
„s-unusedMethod
jak wdrożenie. Po rejestracji wywołuje metodę load na nowej klasie (z jakiegoś powodu nie jest wywoływana automatycznie).Ponieważ metoda ładowania nowej klasy wykorzystuje tę samą implementację co
unusedMethod
, jest to skutecznie wywoływane. Pobiera samą nadklasę i dodajeunusedFunction
jako implementacjędoesNotRecognizeSelector:
metody tej klasy . Ta metoda była pierwotnie metodą instancjiMyClass
, ale jest wywoływana jako metoda klasy w nowej klasie, podobnieself
jak obiekt nowej klasy. W związku z tym nadklasa jestNSValue
, która jest również nadklasąNSNumber
.Wreszcie
main
działa. Pobiera wartość wskaźnika i umieszcza ją wNSString *
zmiennej (__bridge
i pierwszy rzut, abyvoid *
umożliwić użycie z ARC lub bez). Następnie próbuje wywołaćstringByAppendingString:
tę zmienną. Ponieważ w rzeczywistości jest to liczba, która nie implementuje tej metody,doesNotRecognizeSelector:
metoda jest wywoływana zamiast niej, która przechodzi przez hierarchię klas do miejsca, wNSValue
którym jest implementowanaunusedFunction
.Uwaga: niekompatybilność z innymi systemami wynika z użycia oznakowanego wskaźnika, który, jak sądzę, nie został zaimplementowany przez inne implementacje. Jeśli zostałby zastąpiony normalnie utworzoną liczbą, reszta kodu powinna działać poprawnie.
źródło
0x2A27
wartość, więc po prostu nie wiem, czy jest ona zaimplementowana gdzie indziej. ObjFW jest zdecydowanie interesujący.0x2A27
jest oznaczony wskaźnikiemJavaScript
Wydaje mi się, że to nie wygląda na wywołanie funkcji
źródło
C # (przez
using
)źródło
Jawa
Korzystam ze specjalnej funkcji serializacji Java.
readObject
Metoda jest wywoływana, gdy obiekt jest rozszeregować, ale nie jest bezpośrednio nazywa - nie przez mojego kodu, ani przez bibliotekę deserializacji. Jeśli zagłębisz się głęboko w źródło, zobaczysz, że na niskim poziomie metoda jest wywoływana wewnętrznie przez odbicie.źródło
Perl
To takie proste. Poniższy kod automatycznie uruchamia kod w podprogramie, nawet bez wyraźnego wywołania.
Nawet jeśli anulujesz połączenie, połączenie zostanie nawiązane tylko raz.
źródło