Вдохновлен удаленным вопросом 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;
}
Оригинальный вопрос:
popularity-contest
function
Сообщество
источник
источник
Ответы:
С
При компиляции с GCC компилятор заменяется
printf("Goodbye!\n")
наputs("Goodbye!")
, что проще и должно быть эквивалентным. Я украдкой предоставил свою пользовательскуюputs
функцию, так что вместо этого вызывается.источник
Итак, как вредоносная программа может выполнять функции, которые не вызываются в коде? Переполнением буферов!
В моей системе адрес возврата
main
хранится на 3 слова выше первой локальной переменной. Скремблируя этот адрес возврата с адресом другой функции,main
«возвращается» к этой функции. Если вы хотите воспроизвести это поведение в другой системе, вам, возможно, придется настроить 3 на другое значение.источник
<!-- language: lang-c -->
две строки перед вашим кодом, чтобы выделить его.удар
источник
Python 2
Вот несколько способов, вдохновленных другими ответами:
выполнение кода напрямую
Это лучший способ не вызывать функцию.
используя деструктор
Использование стандартного ввода-вывода
используя поиск атрибутов
Механизм импорта
Ну, я думаю, что все .. Я не могу ничего импортировать сейчас. Нет, подождите..
Использование скобок get-item
[]
Использование глобальных переменных. Мой любимый!
hello
это доступ кd['hello']
. После этого мир кажется серым.Мета-классы;)
Использование итераторов (вы можете перегрузить любой оператор и использовать его)
Ошибки!
Рамки перезвонят. Почти каждый графический интерфейс имеет эту функциональность.
Выполнить исходную строку (func должен быть в файле)
Декораторы
с десериализацией рассола (наименьшее количество фаворитов)
Использование сериализации
Больше ответов Python:
hasattr
globals()
и__call__
косвенноreprlib
источник
Javascript
Этот использует JSFuck для грязной работы.
источник
""
строка и имеет[]
значение 0, поэтому""[[]]
не определено и""[[]]+""
не определено. Оттуда вы можете вытащить отдельные буквы:(""[[]]+"")[[]]
это «и». Так что это больше похоже на хак для вызова exec с произвольным кодом. Я думаю, что имеет значение?function anonymous() { x() }
.питон
Это устанавливает
the_function
в качестве функции профилирования, вызывая ее выполнение при каждом вызове функции и возврате.источник
C #
Мы можем использовать DLR, чтобы всегда выполнять некоторый код всякий раз, когда вы пытаетесь вызвать какой-либо метод в классе. Это немного менее дешево / очевидно, чем решения, такие как делегаты, отражения, статические конструкторы и т. Д., Потому что выполняемый метод не только никогда не вызывается, но даже не упоминается даже по его имени.
Это всегда печатает "Ха! Обманули тебя!" независимо от того, что вы пытаетесь вызвать
a
. Так что я мог бы так же легко написать,a.SuperCaliFragilisticExpiAlidocious()
и это сделало бы то же самое.источник
GNU C
Это очень прямой, но, конечно , не призыв к
hello_world
, даже если функция делает выполнение.источник
Рубин
Вдохновленный Ват .
источник
С
Вы можете зарегистрировать функцию, которая будет вызываться в конце программы на C, если это соответствует вашим потребностям:
источник
Ява
Попробовал это с Java:
Метод
secretMethodNotCalledInMain
вызывается только отражением, и я не ищу ничего вызываемогоsecretMethodNotCalledInMain
(вместо этого я ищу ничего не вызванногоmain
). Кроме того, отражающая часть кода вызывается внеmain
метода, когда включается обработчик необработанных исключений JDK.Вот моя информация о JVM:
Вот вывод моей программы:
Я не ожидал, что они
NullPointerException
будут выброшены из нативного кода для обработки отражения. Но, как упомянуто @ johnchen902, это потому, что он наследует некоторые методы от,java.lang.Object
и в итоге я вызвал их наnull
s.источник
NPE
не ошибка JDK. Они выброшены, потому что вы пытались вызвать методы экземпляра, объявленные в,java.lang.Object
например,toString()
сnull
.C ++
Одним из способов в C ++ является использование конструктора и / или деструктора статического объекта:
источник
new
, и поэтому было бы интересно получить способ вызвать его безnew
. Но я не знаю, статические конструкторы кажутся обманом.new (p) foo()
. И вы можете уничтожить объект, не освобождая память черезp->~foo()
.C: Hello World
Выход:
Чтобы связать метод, нам нужно, чтобы printf () был скомпилирован где-то в программе, но на самом деле его не нужно вызывать. Функции printf () и main () расположены на расстоянии 276 байтов друг от друга в сегменте кода. Это значение будет меняться в зависимости от ОС и компилятора. С помощью этого кода вы можете найти фактические адреса в вашей системе, а затем просто вычесть их:
источник
*
, Прежде чемmain
действительно сбивает с толку и ненужным.main
это функция, которую вы не можете разыменовать, поэтому она неявно распадается на указатель функции, который затем разыменовывается, чтобы снова вызвать функцию. Вы не можете вычесть int из функции, поэтому он снова распадается на указатель на функцию. Вы могли бы также написать(*****main-276)
;) Вы вероятно хотели написать(&main-276)
или(*(main-276))
вместо этого.The * before main is really confusing and unnecessary.
- Разве это не хорошо на этом сайте?main
, но не могу ее найти сейчас ...C (с встроенным ассемблером GCC)
Это приведет к тому, что некоторый код, испускаемый GCC, окажется в другом сегменте объектного файла, в результате чего поток управления «провалится» через функцию. Обратите внимание, что это не работает, если GCC решает изменить порядок функций, очевидно. Протестировано с GCC 3.4.6 на MirBSD-current / i386, используя
-O2
. (Кроме того, это прерывает отладку, компиляцию с-g
ошибками ☺)источник
PHP ≥5.4.0
Это решение, по общему признанию, представляет собой ужасный беспорядок, но оно выполняет поставленную перед ним задачу (не было оговорено, насколько хорошо оно должно выполнять).
Функция для вызова без вызова :
Решение :
Пример :
Возможные выводы:
Пояснение :
При вызове
executeFunction()
прочитает содержимое исполняемого в данный момент файла (что означает, что он предназначен только для запуска из CLI, как он использует$argv
), проанализирует аргументы и тело указанной функции, взломает все обратно вместе в новый кусок код,eval()
все это и вернуть результат. В результатеgetRandomString()
фактически никогда не вызывается, ни прямо, ни косвенно, но код в теле функции все еще выполняется.источник
__construct()
метод число в PHP, так как вы никогда не вызываете функцию напрямую, а используетеnew Something()
вместо этого?register_tick_function()
,register_shutdown_function()
илиspl_autoload_register()
похож на ответ на Python @ GRC, но я чувствую, что это «обман» и принимая легкий путь.Perl
Да, это все, что нужно сделать. Не все подпрограммы созданы равными.
источник
T-SQL
Это встроенная функция. Триггеры на победу!
Если вы действительно хотите повеселиться с ним, создайте кучу триггеров INSTEAD OF в День первоапрельского праздника.
Результаты:
Очень шутка. Такой лулз. Ух ты.
Тинкер видел это на SQLFiddle.
источник
JavaScript
В консоли Firefox:
Тогда просто начните набирать что-нибудь в консоли - Firefox вызывает
.toString()
несколько раз, когда вы печатаете в консоли.Подобный подход:
источник
С
Платформа выбора - Linux. Мы не можем вызвать нашу функцию, поэтому мы сделаем так, чтобы наш компоновщик сделал это:
Как получить волшебный адрес?
Мы полагаемся на стандартную базовую базовую спецификацию Linux, которая гласит:
Скомпилируйте код:
gcc but_for_what_reason_exactly.c -o but_for_what_reason_exactly
Изучите адрес
.fini_array
:objdump -h -j .fini_array but_for_what_reason_exactly
Найдите VMA этого:
и заменить это значение для
ADDRESS
.источник
VB6 и VBA
Не уверен, имеет ли это право или нет, потому что он вызывает метод класса:
Это идет в модуле класса:
И это «вызывающий» код:
Это работает путем замены функции vptr для двух Subs в vtable для класса.
источник
Haskell
В Haskell, если вы делаете:
Он будет выполнен немедленно, без вызова его имени, когда вы запустите его. Магия!
источник
Javascript
Легко, просто используйте
on___
события в JS. Например:источник
Ява
Другой ява ответ от меня. Как вы видите в коде, он напрямую вызывает
theCalledMethod
, ноnotCalledMethod
вместо этого выполняется метод .Итак, в конце я делаю 2 вещи:
Запуск это:
источник
getBytes()
методу, включив егоgetBytes("UTF-8")
. Поскольку у меня нет OS X, не могли бы вы проверить, работает ли это?питон
источник
Ява
Уу, сборка мусора!
Версия для тех, кто неизбежно скажет, что
System.gc()
это ненадежно:источник
Objective-C
(Вероятно, только если скомпилировано с Clang на Mac OS X)
Этот код использует несколько приемов, чтобы добраться до неиспользуемой функции. Во-первых, это значение 0x2A27. Это помеченный указатель для целого числа 42, который кодирует значение в указателе, чтобы избежать выделения объекта.
Дальше есть
MyClass
. Он никогда не используется, но среда выполнения вызывает+load
метод при его загрузке ранееmain
. Это динамически создает и регистрирует новый класс, используяNSValue
его как суперкласс. Он также добавляет+load
метод для этого класса, используяMyClass
«S в-unusedMethod
качестве реализации. После регистрации он вызывает метод load для нового класса (по некоторым причинам он не вызывается автоматически).Так как метод загрузки нового класса использует ту же реализацию
unusedMethod
, что и, он эффективно вызывается. Он берет суперкласс сам по себе и добавляетunusedFunction
в качестве реализацииdoesNotRecognizeSelector:
метод этого класса . Этот метод изначально был методом экземпляраMyClass
, но вызывается как метод класса для нового класса, так жеself
как и новый объект класса. Следовательно, суперкласс естьNSValue
, который также является суперклассом дляNSNumber
.Наконец-то
main
работает. Он принимает значение указателя и помещает его вNSString *
переменную (__bridge
и первое приведение, чтобыvoid *
позволить использовать его с ARC или без него). Затем он пытается вызватьstringByAppendingString:
эту переменную. Поскольку на самом деле это число, которое не реализует этот метод,doesNotRecognizeSelector:
вместо этого вызывается метод, который перемещается вверх по иерархии классов туда,NSValue
где он реализован с использованиемunusedFunction
.Примечание. Несовместимость с другими системами связана с использованием тегового указателя, который, как я полагаю, не был реализован другими реализациями. Если это было заменено на обычно создаваемый номер, остальная часть кода должна работать нормально.
источник
0x2A27
значение, поэтому я просто не знаю, реализовано ли это где-нибудь еще. ObjFW определенно интересен, хотя.0x2A27
является меченый указательJavascript
Я чувствую, что это явно не похоже на вызов функции
источник
C # (через
using
)источник
Ява
Я пользуюсь особенностью сериализации Java.
readObject
Метод вызывается , когда объект десериализации, но это не так прямо и называется - не мой код, ни библиотеки десериализации. Если вы углубитесь в источник, вы увидите, что на низком уровне метод вызывается изнутри посредством отражения.источник
Perl
Это так просто. Код ниже автоматически выполняет код в подпрограмме, даже без явного вызова.
Даже если вы раскомментируете вызов, он все равно будет вызван только один раз.
источник