Сделайте свой язык * в основном * непригодным для использования! (Нить ментов)


61

Вдохновленный этим комментарием ...

Спасибо пользователям Step Hen , Wheat-Wizard и Dennis за помощь в разработке спецификации этого задания перед его публикацией!

Это нить ментов. Для нити грабителей, иди сюда


В этом задании перед вами стоит запуск некоторого кода, который делает его таким, чтобы ваш язык больше не удовлетворял нашим критериям языка программирования. В этом вызове это означает сделать так, чтобы язык больше не мог ...

  • Возьмите числовой ввод и вывод

  • Добавьте два числа вместе

  • Проверьте, является ли определенное число простым или нет.

Это задача , где есть две разные задачи с двумя разными целями: копы попытаются написать некоторый код, который делает язык в основном непригодным для использования, и грабители попытаются найти скрытый обходной путь, который позволяет копам восстановить свой язык.

Как полицейский, вы должны написать два фрагмента кода:

  1. Тот, который делает ваш язык в основном непригодным, например, удаляя встроенные функции для ввода / вывода и числовые операции. Чем больше функций вы удалите, тем лучше. Этот код не может произойти сбой или выход. Должна быть возможность добавить код в конец этого фрагмента, и этот код будет оценен . А также...

  2. ... фрагмент кода, который принимает два неотрицательных целых числа в качестве входных данных, складывает их вместе и выводит их сумму. Этот фрагмент должен работать правильно даже после запуска первого фрагмента. Когда два фрагмента объединены вместе, они должны сформировать полную программу, которая добавляет два числа, или определить функцию, которая добавляет два числа. В идеале этот фрагмент должен опираться на очень неясное поведение, чтобы его было труднее найти.

Вы можете выбрать любой стандартный метод ввода и вывода . Однако вы должны точно указать, какой формат (входной и выходной) вы используете. Грабитель не может взломать ваш ответ, если он не использует тот же формат, что и вы.

После написания обоих этих фрагментов вы должны опубликовать первый ответ, не раскрывая второй. Ваш ответ должен содержать всю следующую информацию:

  • Первый фрагмент (явно не второй).

  • Язык (включая минорную версию, так как большинство представлений, вероятно, будет опираться на странные крайние случаи)

  • Формат ввода-вывода, в том числе ли это функция или полная программа. Грабители должны использовать тот же формат, чтобы их трещина была действительной.

  • Любые странные крайние случаи, необходимые для вашего ответа на работу. Например, работает только на Linux или требует подключения к Интернету . Очевидно, это немного субъективно, но если у полицейского есть какой-то крайний крайний случай, который предотвращает его взлом, а затем обнаруживает это только в безопасности, я считаю это плохим спортивным мастерством. У потенциального грабителя должна быть вся информация, необходимая для взлома вашего ответа, прежде чем он будет взломан.

Вам не нужно раскрывать количество байтов, пока ваш ответ не будет безопасным.

Вот пример. Для первого фрагмента вы можете отправить следующую программу на Python 3:

Python 3

print=None

Принимает ввод из STDIN и вывод в STDOUT

И тогда, как ваш второй фрагмент, вы можете написать:

import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

Это верно, потому что он будет принимать два числа в качестве входных данных и выводить их сумму, даже если вы соедините два фрагмента вместе, например

print=None
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

Однако для грабителя будет очень легко найти решение. Поскольку это было бы очень легко взломать, вы можете попытаться исправить этот конкретный подход следующим образом:

import sys
sys.stdout=None
print=None

Однако даже у этого есть очень легкий обходной путь:

del print
a,b=int(input()),int(input())
print(a+b)

Как полицейский, ваша цель - сделать скрытый обходной путь как можно более скрытным, чтобы не дать грабителям найти его.

В разбойниках будут смотреть на один из ваших ответов, и попытаться взломать его. Они могут взломать его, написав любой допустимый фрагмент кода, который может работать как фрагмент 2 (сложение двух чисел после того, как язык становится в основном непригодным для использования). Это не обязательно должен быть тот же фрагмент, который вы изначально предполагали. Если грабитель взломает ваш ответ, он оставит комментарий к вашему ответу, а затем вы должны отредактировать его, чтобы указать, что он был взломан. Если ваш пост взломан, вы должны отредактировать свой ответ, чтобы показать решение (фрагмент 2), которое вы изначально планировали. Это не правило как таковое , просто дружеское предложение, чтобы игра оставалась веселой. Ты не должен.

Если ответ остается без изменений в течение одной недели, вы можете отредактировать свой второй фрагмент и указать, что ваш ответ теперь безопасен . Если вы не редактируете его по истечении недели, другие пользователи все равно могут его взломать, пока вы не сделаете это. Если вы не раскрываете свой второй фрагмент, вы не можете требовать баллы за ваш ответ или называть его безопасным.

Победителем в потоке полицейских является самый короткий безопасный ответ, включающий оба фрагмента , подсчитанные в байтах, и этот ответ будет принят после того, как пройдет достаточно времени. Вам не нужно раскрывать количество байтов до тех пор, пока ваш ответ не будет безопасным, поскольку количество байтов не имеет отношения к вашему счету, пока ваш ответ не будет безопасным. В случае, если прошло достаточно времени, а ответы не остались без изменений, победителем будет тот ответ, который оставался без изменений в течение самого длительного периода времени.

Веселиться!

Разъяснения правил

  • Первый фрагмент должен работать правильно, без каких-либо входных данных . Он может выводить все, что угодно, и этот вывод будет игнорироваться - до тех пор, пока после создания фрагмента второй фрагмент работает правильно.

  • Второй фрагмент должен быть действительно выполнен, чтобы ваш ответ был действительным. Это означает, что ответ как

    import sys
    sys.exit()
    

    недопустимо, потому что это не нарушает язык. Это просто выходит. Точно так же ввод бесконечного цикла недопустим, так как второй фрагмент никогда не будет выполнен.

  • После того, как вы в безопасности, ваш счет - это количество байтов обоих фрагментов .

  • Это восходит к Пожалуйста , выявить какие - либо странные случаи краев , необходимые для ответа на работу ... Ваша заявка должна содержать достаточно информации , прежде чем раскрываются воспроизводимыми после раскрываются. Это означает, что если ваш ответ станет безопасным, а затем вы отредактируете в: Вот мой ответ. Да, кстати, это работает, только если вы запускаете его на Solaris, шутка над вами! Ваш ответ недействителен и будет удален и не будет признан приемлемым для победы.

  • Второй фрагмент кода может потерпеть крах после вывода суммы - до тех пор, пока вывод остается верным (например, если вы выберете вывод в STDERR, а затем получите кучу информации о сбое, это недопустимо).

  • Вы не можете редактировать свой код после отправки ответа.

  • Вы не можете полагаться на криптографические функции, такие как шифрование, хэш-функции, CSPRNG и т. Д.

Фрагмент, чтобы найти непроверенные представления:


3
Что нужно сделать для таких языков, как C? Конкатенация допускает только один «основной фрагмент», и любая логика должна идти туда. Например, если у меня есть, int main(){ do_evil_stuff(); }куда должен идти код пользователя? В функции? После всех заявлений в main?
Конор О'Брайен

1
Можно ли разместить второй фрагмент в любом месте первого фрагмента?
LegionMammal978

1
Я ничего не знаю о кодировании, но этот вызов выглядит потрясающе,
Притт Балагопал

2
Я отредактировал в удивительном фрагменте jimmy23013 . Не стесняйтесь возвращаться, но я все равно использовал его сам, чтобы найти материалы и подумал, что это может помочь другим.
Дом Гастингс

2
@DomHastings Это очень полезно! Большое спасибо :)
DJMcMayhem

Ответы:


2

Gforth 0,7,3 (TIO) , 231 байт [SAFE]

Этот код переопределяет как бесполезные некоторые необходимые методы вывода, а также сложение и что-то важное для объявления функций. Удачи!

: . ;
: dec. ;
: u. ;
: .r ;
: u.r ;
: d. ;
: ud. ;
: d.r ;
: ud.r ;
: emit ;
: type ;
: + postpone 2drop ;
: ; + + + postpone exit reveal postpone [ ;

Входными данными будут два целых числа со знаком, взятых из верхней части стека в качестве параметров функции Вывод на STDOUT.

Таким образом, вы должны исправить нанесенный ущерб и определить функцию, которая берет два верхних значения из стека и печатает результат в виде целого числа (не с плавающей запятой) в STDOUT без дополнительного вывода (без конечного пробела).

Вот шаблон , если ваша целевая функция названа f.

Решение:

79 байт.

Я фактически удалил immediateключевое слово в конце переопределения ;, поэтому в ответ нужно было включить его в начало. Функция, которую я определил, в основном эквивалентна внутреннему определению ., но она не печатает пробел в конце, и сначала выполняется сложение путем перемещения чисел в стек с плавающей запятой и обратно.

immediate : f s>f s>f f+ f>d swap over dabs <<# #s rot sign #> (type) #>> 0 0 ;

Попробуйте онлайн


1
Это очень хороший ответ. С такой скоростью, похоже, что это может оказаться единственным ответом без трещин!
DJMcMayhem

:) Я объединил пару разных препятствий. На данный момент, мне интересно, если бы я мог сделать только один, чтобы улучшить свой счет. Но возможно, что наличие более одного - вот почему оно еще не взломано.
mbomb007

21

Haskell, взломанный Кристианом Сиверсом

import Prelude(getLine,print)
a=a

Полная программа, считывающая два целых числа (включая отрицательные) из стандартного ввода и запись в стандартный вывод.

Я только что отключил Prelude, так что почти ничего не находится в области видимости, а затем добавил определение; дальнейший импорт синтаксически недействителен. Я дал тебе getLineи printхотя.


Отредактировано, чтобы добавить мое оригинальное решение. Взлом Кристиана был другим, но он использовал те же базовые функции (вы можете получить удивительное количество вычислений, выполняя доступ к функциям, которые имеют синтаксический сахар, даже когда вы не можете вызвать что-либо встроенное напрямую или даже назвать используемые типы).

import Prelude(getLine,print)
a=a
(x:l)!0=x
(x:l)!n=l!d[0..n]
d[x,y]=x
d(x:l)=d l
x^y=[x..]!y
x+y=f[0..y](x^y)(-((-x)^(-y)))
f[]x y=y
f _ x y=x
f.g= \x->f(g x)
f&0= \x->x
f&n=f.(f&d[0..n])
x*y=((+x)&y)0
x%[]=x
x%('-':s)= -(x%s)
x%(c:s)=x*10+i c%s
i c=l['1'..c]
l[]=0
l(x:s)=1+l s
main=do
 x<-getLine
 y<-getLine
 print((0%x)+(0%y))

Который, вероятно, не супер-гольф в любом случае, но здесь это более наглядно:

import Prelude(getLine,print)
a=a

-- List indexing
(x : _) !! 0 = x
(_ : xs) !! n = xs !! (sndLast [0..n])

-- sndLast [0..n] lets us decrement a positive integer
sndLast [x, _] = x
sndLast (_ : xs) = sndLast xs

-- Pseudo-addition: right-operator must be non-negative
x +~ y = [x..] !! y

-- Generalised addition by sign-flipping if y is negative
x + y = switch [0..y] (x +~ y) (-((-x) +~ (-y)))
  where switch [] _ empty = empty   -- [0..y] is null if y is negative
        switch _ nonempty _ = nonempty

f . g = \x -> f (g x)

-- compose a function with itself N times
composeN f 0 = \x -> x
composeN f n = f . (composeN f (sndLast [0..n]))

-- multiplication is chained addition
x * y = composeN (+x) y 0

strToNat acc [] = acc
strToNat acc ('-' : cs) = -(strToNat acc cs)
strToNat acc (c : cs) = strToNat (acc * 10 + charToDigit c) cs

charToDigit c = length ['1'..c]

length [] = 0
length (_ : xs) = 1 + length xs

main = do
  x <- getLine
  y <- getLine
  print (strToNat 0 x + strToNat 0 y)


17

Python 2 , треснувший

Реализует сложение как именованную функцию

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
f=lambda\

Попробуйте онлайн!

Что это делает?

С целью помочь вам немного я объясню, что это делает. Этот код открывает исходный файл и проверяет, соответствует ли остальная часть кода следующим критериям:

  • Не содержит строку import
  • Сделано исключительно из персонажей &)(,.:[]a`cdfijmonrt~

Если он не выполняется ни по одному из критериев, предел рекурсии устанавливается 1равным значению, что любой код, который вы пишете, достигнет предела рекурсии.

Здесь нет хитростей, я написал решение, которое использует только эти символы и не импортирует, я не делаю ничего подрывного, но скажу, что думаю, что это будет довольно сложно взломать.

Чтобы сэкономить ваше время, вот краткий список полезных вещей, которые вы не можете сделать с этим ограничением.

  • + ну да,

  • eval/ execНе собирался позволить вам сойти с рук с этим

  • Числа, они могут быть более полезными, чем вы думаете

  • Строковые литералы

  • len

  • =, Не назначая переменные

  • >, <, ==. , , Я оставил тебя без сравнения

  • *, -, /, %, ^, |, >>, << Единственные операторы Доступные ~и&

  • __foo__, Ни один из этих причудливых методов двойного подчеркивания не допускается.


1
Вау, это довольно зло. Приятно!
HyperNeutrino

Фантастический ответ, чтобы все начать :)
DJMcMayhem

Хе-хе, это, возможно, было вдохновлено тем тупым испытанием царя-холма, которое я
Стивен

4
Я думаю, что это действительный треск: codegolf.stackexchange.com/a/133209/68942
HyperNeutrino

RE первый фрагмент: This code is not allowed to crash or exit.(см. Чат для обсуждения)
Стивен

12

Python 2 , треснувший

Это четвертая итерация этого ответа. Каждый из последних ответов был взломан путем сброса глубины рекурсии.

Реализует сложение как именованную функцию

import sys
if set("".join(open(__file__).read().split('\n')[4:]))-set(' &)(,.:[]a`cdfijmonrt~'):sys.setrecursionlimit(1)
for m in sys.modules:sys.modules[m]=None
del sys;f=lambda\

Попробуйте онлайн!

Что это делает?

С целью помочь вам немного я объясню, что это делает. Этот код открывает исходный файл и проверяет, состоит ли остальная часть кода исключительно из символов. &)(,.:[]a`cdfijmonrt~

В случае неудачи для предела рекурсии устанавливается 1значение, означающее, что любой код, который вы пишете, достигнет предела рекурсии.

Я также отключил все модули, поэтому вы ничего не можете импортировать.

Здесь нет хитростей, я написал решение, которое использует только эти символы и не импортирует, я не делаю ничего подрывного, но скажу, что думаю, что это будет довольно сложно взломать.

Чтобы сэкономить ваше время, вот краткий список полезных вещей, которые вы не можете сделать с этим ограничением.

  • + ну да,

  • eval/ execНе собирался позволить вам сойти с рук с этим

  • Числа, они могут быть более полезными, чем вы думаете

  • Строковые литералы

  • len

  • =, Не назначая переменные

  • >, <, ==. , , Я оставил тебя без сравнения

  • *, -, /, %, ^, |, >>, << Единственные операторы Доступные ~и&

  • __foo__, Ни один из этих причудливых методов двойного подчеркивания не допускается.

Мое решение

Так что теперь, когда xnor взломал его так, что я достаточно доволен, я собираюсь раскрыть свое решение

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

Сюрприз, сюрприз его огромная куча тарабарщины. Вместо того, чтобы разбить это, я собираюсь пройти через процесс того, как я сделал это.

Я начал с довольно стандартного алгоритма сложения

r,o:(o and f(r^o,r&o<<1))or r

Тогда я использовал побитовый трюк для представления ^с |, &, ~.

r,o:(o and f((r|o)&~(r&o),r&o<<1))or r

Я использовал еще один побитовый трюк, чтобы избавиться от |

r,o:(o and f(~(~r&~o)&~(r&o),r&o<<1))or r

Теперь все, что осталось, это <<, не должно быть слишком сложно, верно? Ну, будьте готовы к ухабистой поездке. Чтобы заменить битовое смещение, я использовал строки, чтобы добавить ноль в конец его двоичного представления.

r,o:(o and f(~(~r&~o)&~(r&o),int(bin(r&o)[2:]+"0",2)))or r

У этого есть несколько проблем, но основной является использование сложения , поэтому я решил обойти это, используя вместо этого формат

r,o:(o and f(~(~r&~o)&~(r&o),int("{}0".format(bin(r&o)[2:]),2)))or r

Нам не разрешено использовать bin, поэтому я использовал форматирование строки для преобразования в двоичный файл.

r,o:(o and f(~(~r&~o)&~(r&o),int("{0:b}0".format(r&o),2)))or r

Поскольку строковые литералы запрещены, я должен построить строку {0:b}0из частей, сделанных с помощью обратных тиков и joinих вместе.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join(["{","0",":","b","}","0"]).format(r&o),2)))or r

Пустая строка довольно проста, вы можете просто сделать

`r`[:0]

Нули были

`0`

и {:}все они были взяты из словарей.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],"b",`dict()`[-1],`0`]).format(r&o),2)))or r

bкажется довольно трудно получить, его нет в нашем наборе символов, так как мы можем получить объект, который имеет bего repr? Ну вот как: когда вы используете reprвстроенную функцию, вы получаете что-то похожее

<built-in function name>

И вот откуда мы возьмем наши b.

r,o:(o and f(~(~r&~o)&~(r&o),int("".join([`dict()`[0],`0`,`dict([(0,0)])`[2],`min`[1],`dict()`[-1],`0`]).format(r&o),2)))or r

Теперь все, что осталось, это числа, мне нужны только -1, 0, 1 и 2, вот как я их представлял:

-1 = ~(r&~r)
 0 = r&~r
 1 = []in[[]]
 2 = `~([]in[[]])`[[]in[[]]:]

2 может быть на байте короче, как

```r&~r```.find(`r&~r`)

основанный на предложениях @ Blender в комментариях, но я не думал об этом до тех пор, пока после факта.

Таким образом, мы подставляем эти числа в

r,o:(o and f(~(~r&~o)&~(r&o),int(`r`[:r&~r].join([`dict()`[r&~r],`r&~r`,`dict([(r&~r,r&~r)])`[int(`~([]in[[]])`[[]in[[]]:])],`min`[[]in[[]]],`dict()`[~(r&~r)],`r&~r`]).format(r&o),int(`~([]in[[]])`[[]in[[]]:]))))or r

И это трещина.


Этот фрагмент кажется ошибочным сам по себе.
ATaco

@ATaco Я думаю, что это обсуждалось в чате, и было решено, что это нормально.
Пшеничный волшебник

В правилах прямо указано иное. «Этот код не может произойти сбой или выход.»
ATaco

@ATaco Вот сообщение, которое он сказал, что он обновит его, когда получит шанс.
Пшеничный волшебник


10

C (GCC) треснул!

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}

Попробуйте онлайн!

Ввод из STDIN и вывод в STDOUT.

Это работает без ошибок. Хахаха, это довольно зло. Я только протестировал это на GCC TIO. Как правило, вы должны добавить свой код после этого фрагмента, чтобы он заработал :) Комментарий - средний, не слушайте его.

Проверено на gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1). Должно работать на любой системе Linux.

Оригинальное решение

#define D(f)void f(void);
D(printf)D(fprintf)D(putc)D(puts)D(getchar)D(putc)D(fputc)D(ferror)D(feof)D(read)D(fclose)D(fread)D(wr1te)D(fgets)D(fgetc)D(popem)D(gets)D(read)D(scanf)D(setbuf)D(execl)D(execlp)D(putchar)D(execle)D(execv)D(malloc)D(execvp)D(execvpe)D(exec)D(system)D(close)D(fwrite)D(open)D(free)
int stdin;
int main(){
//your code goes here...hehe
}
void __attribute__ ((destructor)) dtor() {
    int a,b,c,d;a=b=c=0;
    struct FILE* z = popen("cat", "r");
#define q(x)for(;(c=getc(z))^32&&c^-1;)x=10*x+c-48;
q(a);q(b);
    char*y=calloc(c=a+b,1);
    for(a=0;c;){y[a++]=(48+(c%10));c=c/10;}
    for(b=0;b<a/2;b++){d=y[b];y[b]=y[a-b-1];y[a-b-1]=d;}
    write(1,y,a);
}

@ LegionMammal978 Ах, да
Конор О'Брайен

2
Укажите вашу платформу!
Иисус Навин

@ Джошуа Я добавил некоторую информацию
Конор О'Брайен


Ну, __asm__и у вас есть множество функций на выбор :) не думайте, что C и C ++ здесь хорошие враги.
edmz

10

C (GCC в Linux) (взломан)

Вместо использования глупых методов песочницы для чтения файлов, мы делаем это надлежащим образом - с помощью белого списка SECCOMP!

Ваша задача: реализовать сложение с вводом из STDIN и выводом в STDOUT.

#include <stdlib.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/seccomp.h>
#include <syscall.h>
#include <stdio.h>
void sandbox();
__attribute__ ((constructor(0))) int s() {
    close(0);
    close(1);
    close(2);
    prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
}
int main() {
    sandbox();
    syscall(SYS_exit, EXIT_SUCCESS);
}
void sandbox() {
    // Your code here!
}

Попробуйте онлайн!

Что это за хрень!?

Чтобы помочь вам в вашей непреодолимой задаче, я объясню, что делает этот код.

__attribute__ ((constructor(0)))гарантирует, что sфункция запускается первой. Функция закрывает все открытые файловые дескрипторы для STDIN, STDOUT и STDERR. Затем программа ограничивается строгим белым списком SECCOMP, который ограничивает ваши системные вызовы следующим:

read(2)
write(2)
_exit(2)
sigreturn(2)

Поэтому вы не можете открывать какие-либо новые файлы (или вообще ничего не делать). Затем мы подходим к main и вызываем ваш код, красиво завернутый в sandboxфункцию.

В syscall(SYS_exit, EXIT_SUCCESS);конце это просто для того, чтобы убедиться, что программа завершается корректно - по умолчанию GCC завершит работу, exit_group(2)что не разрешено в белом списке SECCOMP. Эта функция выхода вызывается после запуска вашего кода.

Таким образом, у вас нет открытых дескрипторов файлов, и вы не можете открыть ничего нового. Невозможно, верно? ;)



9

Хаскелл , взломанный Беном

main=main--

Попробуйте онлайн! Это должна быть полная программа, считывающая два числа из стандартного ввода и выводящая сумму в стандартный вывод.

Каждая полная программа начинается с запуска mainфункции, но здесь mainвызывает себя и вызывает бесконечный цикл. Что еще хуже, строковый комментарий начинается --непосредственно за рекурсивным вызовом, чтобы предотвратить его изменение, например, main2и затем определение его для суммирования.


Предполагаемое решение:

main=main--$()
_ --$ _ = do
     x <- readLn
     y <- readLn
     print $ x+y

Попробуйте онлайн!

--начинает комментарий строки, если он не может быть проанализирован как часть оператора. (Подсветка синтаксиса, кажется, не знает об этом факте.) --$Является допустимым инфиксным оператором, который принимает в mainкачестве первого аргумента и некоторый фиктивный второй аргумент (). Затем определяется, чтобы игнорировать оба аргумента и вместо этого выполнять требуемую задачу.



5
Вы можете просто добавить «где главное = ...»
michi7x7

+1 за решение Haskell, которое работает только из-за ленивой оценки Haskell.
Жюль

8

Сборка 16 бит в реальном режиме x86 ( Cracked )

_main:
    call l
    cli
    hlt
l:  pop si
    xor ax, ax
    mov bp, cs
    mov es, ax
    mov di, 12
    mov [di], si
    mov [di + 2], bp
    pushf
    mov bp, sp
    or word [bp], 256
    popf

Легко, если знаешь трюк.


1
Как вы принимаете вход? В стеке или в регистрах? (Кроме того, похоже, что это должна быть 16-битная сборка, но если это так, or [bp], 256она недействительна. Это должно быть or WORD PTR [bp], 256?)
Коди Грей,

1
Кроме того, вы должны указать, какой процессор вы используете; Есть много версий и клонов для x86, а также множество неопределенных инструкций. Если бы я написал код для «малопонятного клона 80186», который, как оказалось, имел неопределенную инструкцию, которая принимала несколько аргументов, и тому подобное. Нам также может потребоваться среда. 16-битная Windows дала SS == DS гарантию, что другие системы, например, не могут.
Орион

1
Вам нужно только указать , какой процессор , если вы на самом деле являетесь использовать некоторый трюк , который работает только на одной конкретной модели (или одного конкретного поколения). Этот код не такой, поэтому я думаю, что "x86-16" достаточно. На мой взгляд, чем больше общего, тем лучше. Согласились, что реальный или защищенный режим должен быть указан, хотя наличие hltинструкции (кольцо 0) сильно подразумевает, что это не защищенный режим.
Коди Грей

3
@ Джошуа, если он работает не на каждой платформе, я должен, по крайней мере, указать платформу, на которой он будет работать. Your submission must contain enough information before being revealed to be reproducible after being revealed
Стивен

1
@StepHen: решение для разрыва языка является независимым от платформы, если указан реальный режим x86-16, но ввод / вывод не зависит от платформы. Тот, кто взломает его, может указать ОС, для которой он прорвался. Я добавил метку _main поздно, чтобы кто-то теоретически мог сделать почти безразличный разрыв, связавшись с libc.
Джошуа

4

Javascript, трещины

Эта задача построена на основе решения Гранта Дэвиса , но исправляет решение, которое он имел в виду (которое создает iframe и использует iframe window). Решение запускается в консоли javascript на chrome about:blank pageи занимает две input()секунды, складывает их вместе и возвращает console.logрезультат. Поместите ваш код после:

d=prompt=console=document;new MutationObserver(s=>s.forEach(e=>{t=e.target;t.parentNode.removeChild(t)})).observe(d,{"childList":d, "subtree":d})

Сначала мы сжимаем promptи consoleи устанавливаем ярлык d. Затем мы создаем наблюдателя мутаций с обратным вызовом, который удаляет каждую цель мутированную. Мы установили , что мутации наблюдатель соблюдать документ, и уведомить об childListи subtreeмодификации. Вместо литерала trueмы используем наш ярлык для истинного значения document( спецификация не позволяет этого, но Chrome делает).

После того, как я написал это, я понял, что гораздо более элегантный клоббер. Мое намеченное решение все еще работает, но опубликованный треск не делает:

 h=document.querySelector("html");h.parentNode.removeChild(h);

Добро пожаловать на сайт! Мне интересно посмотреть, каким будет решение :)
DJMcMayhem


4

Perl 5, взломанный Ильмари Каронен

$_=<DATA>;
s/[+'{dPz|K.UD!_ iJ;o}e6tjWb7253k@%&Iq4l0AN:?\$8B`Yywn9^pfmZQTF"M#-]//g;
eval;
print@_,$!,pop,shift,<>,eval"@>",$\,@ARGV,eval"@$",$@,eval"@@",$,,eval"@,",$/
__DATA__

Ввод принимается в отдельных строках, STDINа вывод выводится на STDOUT.

Весь код идет после __DATA__маркера. При этом используется метод, аналогичный решению @ WheatWizard, в котором анализируется код и удаляются непригодные символы.

Это было протестировано в версиях 5.8, 5.10 и 5.16 и не требует флагов командной строки.

Попробуйте онлайн!


2
Не могли бы вы указать способ и формат ввода / вывода?
Ильмари

@IlmariKaronen Извинения, это STDINс символами на отдельных строках и STDOUT. Я добавлю это в основной корпус.
Дом Гастингс

Трещины , я думаю.
Ильмари

4

Python 3, взломанный zbw

import sys
for mod in sys.modules.values():mod.__dict__.clear()
1+1

Все модули были удалены, что означает, что встроенные функции отсутствуют, и ничего больше не поделаешь. Вывод в STDOUT, ввод из STDIN. Это вторая итерация этого ответа после того, как предыдущий был разорван тривиальной трещиной путем добавления оператора разрыва.


Мне действительно любопытно увидеть фрагмент, который работает после этого
NickA

Что ж, вам придется ждать семь дней или нетривиальную трещину, в зависимости от того, что наступит раньше ...
pppery


Ну, ну, такие задачи очень трудно выполнить хорошо
pppery

4

APL (ngn-apl) , взломанный ngn

Сделано в сотрудничестве с моим коллегой Маршаллом .

Ввод через левый и правый аргументы для +. Т.е. ваша цель - вставить код после следующего, чтобы ваша последняя строка читала ⎕←3+2и выводила 5в STDOUT.

+←-←−←⍴←≢←≡←⊥←⊤←⍟←○←⍳←⌹←~←∈←∊←⍷←<←≤←=←≥←>←≠←,←⍪←⌷←⌽←⍉←⊖←{}⋄⍣←∘

Попробуйте онлайн!

Работает, устанавливая все полезные функции, для {}которых принимает один или два аргумента и возвращает пустой числовой список. Также устанавливает просто составлять функции.


трещина

+←{⌈/⍋⍺⍵1/0}

⍺⍵1/0 повторить 0 с помощью левого аргумента и правого аргумента и 1

 получить индексы, которые бы сортировали это (поскольку все элементы равны нулю, это дает 0 1 2… (a + b)

⌈/ максимальное значение (а + б)


ngn / apl включает в себя возможность выполнения произвольного JavaScript. Я не считаю такое решение допустимым, так как тогда речь идет об отключении JavaScript, а не APL. Действительно, существует верный (хотя и неясный) способ сброса +с использованием только чистого APL и без грязных трюков.
Адам

3

Python 2 , треснувший

Это вторая итерация ответа, который один раз был взломан @HyperNuetrino с помощью метода, которого я не ожидал. Я теперь исправил это так, надеюсь, единственные оставшиеся решения должны будут соблюдать ограничения, которые я намеревался.

Реализует сложение как именованную функцию

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
sys.modules['sys'],sys.modules['os']=None,None;del sys;f=lambda\

Попробуйте онлайн!


Я думаю, я мог бы сделать это, если бы у меня было u, но я застрял без этого.
Исаак

@isaacg Просто из любопытства, с чем бы ты хотел u?
Пшеничный волшебник

.count, Я могу получить строку до тех пор, пока желаемый результат, но у меня нет возможности взять ее длину.
Исаак

__import__('sys').setrecursionlimit(100)... и ничего на самом деле не было исправлено. Я не очень хочу публиковать его в ветке грабителя, но мне кажется, что это измена. Попробуйте онлайн
Value Ink


3

Java 8, взломано @ OlivierGrégoire

Вот моя попытка. Идея состоит в том, чтобы просто перегрузить все пространства имен, которые вы можете использовать для вывода (и, я надеюсь, отразить). Выход предназначен для sdout (System.out).

class java {
    public static void main(String[]s){
       //there is no executable code in snippet one.
       //your code here.
    }
    class Class{}
    class Method{}
    class System{}
    class FileDescriptor{}
    class Logger{}
    class Runtime{}
    class Scanner{}
}

Чёрный список обычно хуже, чем белый, поэтому я уверен, что это просто вопрос времени, когда кто-то придумает подход, который я не рассматривал.


1
Это не исполняемый класс ...
Оливье Грегуар

1
@ OlivierGrégoire Извините, я добавил class String{}после тестирования, даже не подозревая, что это может выбить main(String[] ...). Это должно сработать сейчас
лорд Фаркуаад

1
Да, это будет делать, спасибо! :) Это не меняет трещины, которые я собираюсь сделать, однако: p
Оливье Грегуар

1
Трещины! Мне очень понравилось это :)
Оливье Грегуар

1
Я смотрел на что-то вроде этого (извините, это трудно отформатировать код в комментариях), но я думаю, что ваше решение намного чище:int sum = 0; new Exception("" + sum) { public void printStackTrace() { ClassLoader cl = ClassLoader.getSystemClassLoader(); try { printStackTrace(new PrintStream((PrintStream)cl.loadClass("java.lang.System").getDeclaredField("out").get(null))); } catch (Exception e){} } }.printStackTrace();
Лорд Фаркуаад

3

cQuents, взломанные Mayube

#|1,1:A

Это должно быть довольно легко, но вы никогда не знаете.

«Проблема» заключалась в том, что без Cв вашем коде вы получили ошибку.

Решение Mayube:

#|1,1:A+BC

Каждый элемент в последовательности является первым входом плюс второй раз третий (он же 1)

Мои решения:

#1,1:A+B,C

Последовательность циклически переключается между первым входом плюс вторым входом и третьим входом (1). Первый пункт во втором есть A+B.

#1,1:A+B+C-C

Аналогично решению Mayube - вместо умножения B*Cпросто складывает, Cа затем вычитает.

Попробуйте онлайн!

объяснение

#|1,1      Append 1 and 1 to the end of the user's input
     :     Set mode to : (sequence 1: if given n, output nth term in sequence; if given no n, output whole sequence)
      A    Each item in the sequence equals the first input

В настоящее время эта программа выводит данные 1, так как при отсутствии пользовательского ввода первый вход является первым 1в вводе по умолчанию ( #).


Документы кажутся действительно неловко сформулированными, я не могу понять для себя, что это означает, когда это говоритDefault input is combined with user input to form the total input, which must align with the expected input (which is based on the highest input requested by the Sequence Definition)
Skidsdev

@ Mayube, это странно, мне нужно найти способ сказать это правильно. По сути, ваш ввод в программу может быть равен максимальному вводу, запрашиваемому переменными A,B,C,D,Eв коде. Например, если в какой-то момент Dв вашей программе есть переменная , синтаксический анализатор ожидает, что будет 4 входа, но если он также есть E, анализатор ожидает, что будет 5 входов. Там не может быть меньше, чем ожидаемая сумма. Однако всегда есть необязательный последний вход n, который по-разному используется в разных режимах.
Стивен

@Mayube фрагмент, который я разместил выше, содержит A, поэтому он ищет один вход. Так как есть два, оба из #которых указывают вход по умолчанию, он использует первый как Aзначение, а второй как n.
Стивен

Итак, если бы я дал 2 входа и добавил BC, A был бы первым входом, B был бы вторым, C был бы 1, а n был бы вторым 1?
Скидсдев

@Mayube точно, извините за мои дерьмовые документы. TMI: если начало выглядело как #1,1(без полосы), это было бы: A как первая 1, B как вторая 1, C как первый вход и n как второй вход. Вы также можете сделать #1|1, где A является первым 1, B является первым входом, C является вторым входом, а n является вторым 1.
Стивен

3

Node.JS версия 7.3.0 (взломано Домом Гастингсом)

var p=process,f;(_=>{var w=p.stdout.write,n='f'+(Math.random()*1e7|0),l=1
f=p.stdout.write=a=>eval(`(function ${n}(a){while(l&&((typeof a)[0]!='s'||'f'+a!=n));a=l?l="":a;w.apply(p.stdout,arguments);})`)(a)})();

Разместите второй блок кода после первого.

Отказ от ответственности: второй блок кода не будет функционировать сам по себе (без размещения после первого). Если это не разрешено, я могу изменить второй фрагмент.

Это полная программа. Вывод process.stdout(STDOUT), ввод process.argv(аргументы командной строки)

Это мои первые полицейские и грабители, надеюсь, это хороший вызов :)

Попробуйте онлайн!


Задача объяснена

Генерирует случайную величину nот 0 до 1e7. Если вы вызываете write с правильным значением n, ничего не печатается, а устанавливается lв 0, что «разблокирует» функцию записи, что позволяет вам печатать что угодно. Если вы попытаетесь вызвать write с ненулевой строкой, вы попадете в бесконечный цикл. Если вы попытаетесь вызвать write с чем-либо, кроме правильного, в nто время как запись «заблокирована», отправьте вас в бесконечный цикл, чтобы предотвратить угадывание.

Предполагаемое решение

Пробирается мимо typeof, который, по-видимому, проверяет строки только с помощью Symbol, который также начинается с s. Это приводит к ошибке в функции, вызванной вызовом eval, потому что вы не можете добавить строку "f" в Symbol. Мы отлавливаем ошибку и используем регулярное выражение для восстановления nиз трассировки стека, где она находится в имени функции. Затем мы пытаемся написать, nкоторый ничего не печатает, но устанавливает переменную «lock» lв 0, чтобы «разблокировать» функцию записи. Теперь, когда функция записи разблокирована, мы просто выводим сумму.

try{f(Symbol())}catch(e){f(e.stack.match(/f(\d+)/)[1])
f(+p.argv[2]+ +p.argv[3]+"")}


Это гений ... Я тогда был на правильном пути! Спасибо за тренировку мозга!
Дом Гастингс

3

RProgN2 , Трещины на Арнольд Палмер

"+-/*÷^"{²[[\=};

Записывает все математические операторы, без возможности их восстановления. В частности, он заменяет их функцией, удаляющей два верхних элемента в стеке.

Попробуйте онлайн!

Оригинальное решение

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=

{S]‘[L}`d={0RL}`i=«x=y=x{xd`x=yi`y=x}:y»`+=
{     }`d=                                  #Define a function, "d", which returns n-1
 S                                          #Convert the input to a stack, which, as a number, makes a stack of 1 - n.
  ]‘                                        #Duplicate the stack, and pop the top value off it.
    [                                       #Discard the popped'd value.
     L                                      #Get the length of the stack, which now is n-1.
          {   }`i=                          #Define a function, "i", which returns n+1
           0R                               #Get the range of numbers between 0 and n.
             L                              #Get the length of that stack, which is n+1
                  «                    »`+= #Define a function, "+", which takes two numbers, and outputs their sum. We use «» here, because it localises references, instead of globalising them.
                   x=                       #Set the first input to the value of "x", which by default, is x.
                     y=                     #Ditto for y.
                       x{          x}:      #While x is truthy, which in this case, is non-zero.
                         xd                 #Get x - 1
                           `x=              #Set x to it.
                              yi`y=         #And set y to y + 1
                                      y     #Push y to the output. And we're done.

Попробуйте онлайн!


Я просматриваю вашу документацию и не могу понять, что ²делает этот символ. Хотите просветить меня?
Арнольд Палмер

Эта документация не очень важна для RProgN2, и этот символ берет [[в этом случае следующие два понятия и оборачивает их в функцию @ArnoldPalmer
ATaco


Черт, это намного лучше. Я не знал об операторах стека, которые наверняка были бы полезны. Кроме того, знание «»создает локальные переменные, а не портит глобальные переменные.
Арнольд Палмер

3

Haskell, 161 144 байт, Трещины на славка

{-#OPTIONS_GHC -fth -w#-}
module M where

Вход в STDIN, выход в STDERR. Добавьте в конец программы.

Редактировать: предназначен для компиляции без дополнительных аргументов GHC, только нормальный ghc --make prog.hs.

Отредактировано снова, чтобы уменьшить количество байтов.

Веселиться!


Так что я не могу этого сделать, потому что основная функция не будет вызываться? main = do x <- readLn :: IO Integer; y <- readLn; print $ x + y
BlackCap

@BlackCap Нет, потому что GHC ожидает, что mainфункция будет в модуле, Mainесли -main-isфлаг не указан .
zbw

Это не работает, но я все равно хочу поделиться идеей
BlackCap

Я назову это треснувшим. Здесь было мое намеренное решение, игра в гольф. Он не работает на TIO, потому что оболочка не отправляет входные данные компилятору.
zbw

Если вы опубликуете свое решение, я отмечу, что оно взломано.
zbw

3

Маскарпоне , взломанный Илмари Каронен

[ Make 'i' and 'z' print 'q' ]$
v ['q.]v* 'i<^
v ['q.]v* 'z<^

[ Disable some standard commands ]$
v[]v*   '1<^
v[]v*   '$<^
v[]v*   '@<^
v[]v*   '{<^
v[]v*   '}<^
v[<:]v* '<<^
v[]v*   'v<^$

На входе вводятся церковные цифры, используемые iдля приращения и zдля нуля. Например, 2 + 3 будет:

iiziiiz

С завершающим символом новой строки

вывод должен быть числом на stdout в том же формате, что и на stdio. Например, если ответ пять, вы должны вывести:

iiiiiz

(Маскарпоне не имеет понятия о числах)


Предполагаемое решение:

: '[/''/'i/'./' /':/',/'>/'!/']/* 'i<^
: '[/':/',/'>/'!/']/* 'z<^
: ,>!
'z.

Это не сразу видно из документации, но, как сказал @IlmariKaronen в своем крэке, строковые литералы в маскарпоне на самом деле являются синтаксическим сахаром для проталкивания последовательности символов.

Я намеренно писал комментарии, [this]$чтобы я выглядел так, будто я нажимаю на строку и сразу же высовываю ее. Наивный взломщик мог попробовать что-то вроде [:,>!]/*толкания строки, обмена с интерпретатором и интерпретации.

Я также притворяюсь, что выталкиваю интерпретатор, который оставил в стеке $, но $уже был переопределен в NOP. Вы остаетесь с этим интерпретатором в стеке, и вы должны носить его с собой по всей программе; через каждый символ каждой строки.


Трещины. И нет, я никогда не слышал о Маскарпоне до этого испытания.
Ильмари

@IlmariKaronen Новый любимый язык? Отличная работа!
BlackCap

2

C # (.NET Ядро) Трещины от Илмари Karonen

Также трещины на Навина .

namespace System
{
    class Console
    {
        static void Main()
        {
            //Your code goes here
        }
    }
}

Считывает два значения из стандартного ввода и записывает результат в стандартный вывод. Протестировано на Windows с Framework версии 3, 4.6 и на TIO .

Вот полная программа, которую я намеревался.

namespace System
{
    class Console
    {
        static void Main()
        {
            var t = Reflection.Assembly.Load("mscorlib").GetType("System.Console");
            var r = t.GetMethod("ReadLine");
            int a = int.Parse((string)r.Invoke(null, null));
            int b = int.Parse((string)r.Invoke(null, null));
            var w = t.GetMethod("WriteLine", new[] { typeof(int) });
            w.Invoke(null, new object[] { a + b });
        }
    }
}

Попробуйте онлайн!



codegolf.stackexchange.com/a/133412/14306 Я предполагаю, что это не было предназначенным решением.
Джошуа

@IlmariKaronen: +1. Это было намеченное решение.
Разнагул

@ Джошуа: +1 за нахождение другого решения, чем я планировал.
Разнагул

2

GolfScript , взломанный Деннисом

{}' !$%&()*+,-./<=>?@[\]^`|~'':'*~;

Попробуйте онлайн!

Это является вызов, в конце концов, так почему бы не попробовать GolfScript?

Действительным решением должен быть фрагмент, который считывает два целых числа из стека, складывает их вместе и возвращает результат в стеке. Подвох в том, что он все равно должен работать даже после того, как приведенный выше код переопределил почти все встроенные операторы GolfScript, чтобы ничего не делать. По крайней мере, я оставил ;нетронутым, так что вы все равно можете вытолкнуть значения из стека. ;-) Ваш код должен работать на стандартном интерпретаторе GolfScript, как это реализовано, например, на TIO (см. Ссылку выше).


Решение Дениса , как и мое , опирается на редко используемую функцию GolfScript, которая позволяет интерполировать код Ruby в двойных кавычках. Мы используем эту функцию для определения нового оператора сложения, который работает точно так же, как встроенный +оператор, и затем вызываем его.

(Одна из причин, почему функция интерполяции Ruby в GolfScript так редко используется, заключается в том, что, к сожалению, интерполированный код Ruby выполняется во время синтаксического анализа , и его вывод кэшируется интерпретатором GolfScript. Таким образом, если, например, у вас есть строка с интерполированным кодом Ruby в цикле код будет запускаться только один раз до запуска самой программы и после этого всегда возвращать одно и то же значение на каждой итерации цикла. Вы можете обойти это, используя строку eval для отсрочки синтаксического анализа, но это делает и без того неудобный синтаксис еще более некрасиво и многословно, и в любом случае для этой задачи я также отключил оператор eval ~, но оказалось, что определение новых встроенных операторов GolfScript это то, что эта функция делает довольно красиво и чисто.)



Трещины. Наконец-то разобрался, что я делаю не так.
Деннис

@Dennis: Да, ты прибил его на этот раз. FWIW, мое предполагаемое решение было "#{var'_','gpush a+b'.cc2}";_, которое работает точно так же, как у вас, за исключением того, что на несколько байт короче.
Ильмари

2

Node.js v8.2.0, взломан Домом Гастингсом

let mess = ctx => f => new Proxy (f, {
  has: (t, p) => p in t || p in ctx
, get: (t, p) => {
    let k = p in t? t[p]: ctx[p];

    if (k instanceof Function) return (
      function fetch (_k) {
        return mess (ctx) ( x => ( q => q instanceof Function
                                      ? fetch (q)
                                      : t (q)
                                  ) ( _k(x) )
                          )
      })(k);

    return k;
  }
});

with (mess (global) (x => x)) {
  dot   = f => a => b => f(a(b))
  ap    = f => g => x => f (x) (g (x))
  flip  = f => x => y => f (y) (x)
  Const = a => b => a
  id    = x => x
  num   = n => n (x => x + 1) (0)
  log   = console.log

  let x = flip (Const . id . id)
    , y = flip (Const . id . id . id)
  for (let i = 0; i < process.argv[2]; i++) x = ap (dot) (x)
  for (let i = 0; i < process.argv[3]; i++) y = ap (dot) (y)
  process.argv = [];

  logic = x => y => /* Your code here */;

  log . id . num ( logic (ap (dot) (x))
                         (f => z => (( y(flip (id) . id . flip (dot (id)) (f)) ) (Const (z))) (id) )
                 );
}

Вы должны реализовать logicфункцию. Входные данные - это аргументы (из стандартного ввода), выходные данные - то, что возвращает ваша функция (выводится в стандартный вывод).


Моя кодовая церковь кодирует числа из входных данных. Остальная часть кода просто для того, чтобы запугать вас.
Функция беспорядка делает некоторую хитрость для реализации бессмысленной нотации ( a . b == dot (a) (b)), которую я в основном использую для добавления . id .к случайным местам, которая ничего не делает, но сбивает с толку любого, незнакомого с функциональным программированием.
Преобразование, примененное к числам до того, как я передаю их в logicфункцию, - это x+1и y-1, которое добавляет до 0, так что это еще один NOP, который нужно добавить в неизвестность.

Предполагаемое решение было:

logic = x => y => f => z => x (f) (y (f) (z))


@DomHastings Это не намеченное решение, но я скажу, что вы можете, если программа останавливается без исключения и не выводит дополнительные символы в вывод
BlackCap

Я только что опубликовал альтернативу! (Вы можете увидеть мое предыдущее решение в истории этого ответа!)
Дом Гастингс,

Ого, я был далеко ... Все же это лучше, чем моя первая очень обманчивая попытка! Спасибо за головоломку!
Дом Гастингс

2

Информ 7 , взломанный ppperry

For reading a command: rule fails.

[Your code here.]

Ввод должен быть набран игроком в виде интерактивной команды, например, add 17 to 25или sum 17 25. Вы можете выбрать точную форму команды, которую следует ввести, если она содержит два числа. Сумма чисел (например 42) должна быть напечатана в ответ на команду.

Задача, конечно же, заключается в том, чтобы сделать это, в то время как вся операция «чтение команды» заменяется запретом. Есть, вероятно, несколько способов решить эту проблему, но, по крайней мере, это должно потребовать некоторого знакомства с языком. Тот, который я придумал, на самом деле довольно простой, хотя и немного неожиданный.

Я проверил свое решение в среде GNOME Inform 7, версия 6L38 , в Ubuntu Linux. Предполагаемое решение работает как на бэкэндах Glulx, так и на Z-машине, и должно работать на других последних версиях Inform 7. Обратите внимание, что (без подходящего обходного пути) приведенный выше код приведет к тому, что интерпретатор будет занят циклом при попытке прочитать команду; По-видимому, интерпретатор Z-машины перестает отвечать на запросы, когда это происходит, и не может быть остановлен внутри IDE, поэтому я рекомендую использовать Glulx для тестирования.


треснул , и если вам интересно, я никогда не слышал об
инфе

2

CPython 3 (снова), взломанный Сизифом

import sys,os,functools
def p(f,e,a,_=os._exit):
 if e == "c_call":_(1)
sys.setprofile(p)

Вы можете делать все, что захотите - до тех пор, пока это не будет реализовано в C. Это означает, что нет print, нет input- все они попадут в _(1)очередь и завершатся. Ввод из STDIN с числами в двух отдельных строках, вывод в STDOUT. Интересно, как долго это продлится ... Мне потребовалось немало времени, чтобы найти второй рабочий фрагмент после того, как придумал этот трюк с отключением. Явное указание Cpython, чтобы избежать взлома на основе какой-либо альтернативной реализации sys.setprofile.


Трещины. Я очень мало понимаю, почему это работает.
Сизиф

Наверное, теперь я могу спросить: почему functools?
Деннис

@Dennis Поскольку sispyphus обнаружил лазейку, а не намеченное решение
pppery

@Sisyphus Ваша ошибка
pppery

2

Java 8 ( треснувший )

Вторая попытка На этот раз я потратил две минуты тестирования.

static {

    try {

        System.setIn(null);
        System.setOut(null);
        System.setErr(null);

        for (Method m : System.class.getMethods()) {

            m.setAccessible(false);

        }

        System.class.getMethod("getSecurityManager", new Class[0]).setAccessible(false);

        for (Method m : Class.class.getMethods()) {

            m.setAccessible(false);

        }

        SecurityManager mngr = new SecurityManager() {

            @Override
            public void checkPermission(Permission p) {

                if (p.getName().equals("createSecurityManager")) throw new SecurityException();
                if (p.getActions().startsWith("read")) throw new SecurityException();

            }

        };

        System.setSecurityManager(mngr);

        // Your code goes here.

    } catch (Throwable t) {

    }

}

Большинство вещей должно быть покрыто.


1
Не могли бы вы заключить это в класс с соответствующим импортом? Это своего рода вызов, когда эти небольшие изменения могут сделать или сломать запись. У меня есть несколько решений для этого, как есть, но это резко сокращается, если вы просто заключаете это в класс / интерфейс. Кроме того, формат для удаления всех этих строк был бы неплох для нас, читателей.
Оливье Грегуар

Там взломанный ответ, использующий именно ваш код. И +1, потому что, кажется, я забыл это. Сожалею.
Оливье Грегуар

Вызовы #setAccessible (false) ничего не делают.
Nevay

1

Python 2 взломан

import sys,hashlib
c=open(__file__).read().split()[-1]
if c!='#'and hashlib.sha256(c).hexdigest()!='e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843':sys.exit() #

Попробуйте онлайн!

Я предвосхищу это, сказав, что этот ответ - резкое движение, задуманное как ответ с нижней границей.


Вдохновленный ответами Wheat Wizard и HyperNeutrino .

Фрагмент читает исходный файл и отказывается продолжать, если последний разделенный пробелом фрагмент кода не попадает в25 e6400dd63733d10ec042e3c28033cfa85e1d25fbef80020810c354d7c942e843.

РЕДАКТИРОВАТЬ : Отредактировано немного в ответ на этот комментарий . Основная проблема не меняется, любая попытка взлома не считается недействительной.


1
RE первый фрагмент:This code is not allowed to crash or exit.
Стивен

Это недопустимо, потому что это выходит, что не разрешено для первого фрагмента.
DJMcMayhem


1

Java 8 Трещины на @ OlivierGrégoire

Я пытался сделать это как можно сильнее! :) И, в отличие от другого ответа на Java, вы должны будете следовать точным правилам испытания, поместив его после всего этого фрагмента (так что нет, вы не помещаете свой код вpublic static void main(String[] args) метод, вы помещаете его после всего занятия. :) Удачи!

Я добавил комментарии, чтобы показать, что ограничивается.
( Вдохновленный этим постом, который является менее ограничительным и приемлемым с тем же подходом, который я мог бы использовать в своем ответе. )

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FilePermission;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Main {

  // Put everything in a static block so it is run before the static main method 
  // and any trailing (static) initializer-blocks:
  static {
    try {
      initializing();
    } catch (final Exception e) {
    }
  }

  static void initializing() throws Exception {
    // Overwrite System.out, System.err and System.in:
    System.setOut(new PrintStream(new ByteArrayOutputStream()));
    System.setErr(new PrintStream(new ByteArrayOutputStream()));
    System.setIn(new ByteArrayInputStream(new byte[0]));

    // Enable reflection for System.out, System.err and System.in:
    final Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    final Class<?> fdClass = java.io.FileDescriptor.class;
    final Field outField = fdClass.getDeclaredField("out");
    outField.setAccessible(true);
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    final Field errField = fdClass.getDeclaredField("err");
    errField.setAccessible(true);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    final Field inField = fdClass.getDeclaredField("in");
    inField.setAccessible(true);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);

    // Replace existing System.out FileDescriptor with a new (useless) one:
    outField.set(null, new FileDescriptor());
    // Replace existing System.err FileDescriptor with a new (useless) one:
    errField.set(null, new FileDescriptor());
    // Replace existing System.in FileDescriptor with a new (useless) one:
    inField.set(null, new FileDescriptor());

    // Disable reflection for System.out, System.err, System.in again:
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);
    inField.setAccessible(false);
    errField.setAccessible(false);
    outField.setAccessible(false);
    modifiersField.setAccessible(false);

    // Overwrite the SecurityManager:
    System.setSecurityManager(new SecurityManager() {

      private boolean exitAllowed = false;

      @Override
      public void checkExec(final String cmd) {
        throw new SecurityException();
      }

      @Override
      public void checkPermission(final java.security.Permission perm) {
        final String name = perm.getName();
        // You're not allowed to read/write files:
        if (name.equals("setIO") || name.equals("writeFileDescriptor")
            || name.equals("readFileDescriptor")
            || ((perm instanceof FilePermission) && name.startsWith("/proc/self/fd/"))) {
          throw new SecurityException();
        }
        // You're not allowed to overwrite the Security settings:
        if (name.equals("setSecurityManager") || name.equals("suppressAccessChecks")) {
          throw new SecurityException();
        }
        // You're not allowed to use reflection anymore:
        if (name.equals("getModifiers") || name.equals("get") || name.equals("set")
            || name.equals("setBoolean") || name.equals("setByte")
            || name.equals("setChar") || name.equals("setShort") || name.equals("setInt")
            || name.equals("setLong") || name.equals("setFloat") || name.equals("setDouble")
            || name.equals("setFieldAccessor") || name.equals("setFieldAccessor")) {
          throw new SecurityException();
        }
        // When you try to leave the current VM it will stop the program:
        if (name.startsWith("exitVM") && !this.exitAllowed) {
          this.exitAllowed = true;
          System.exit(0);
        }

        // You know what, nothing is allowed!
        throw new SecurityException("Mhuahahahaha!");
      }
    });
  }

  public static void main(String[] args) {
    // Overwritting all given arguments:
    args = new String[0];

    // Exit the program before you can do anything!
    System.exit(0);
  }
}

// Your code goes below:

Попробуй это здесь. (ideone.com вместо TIO, так как там, похоже, он не работает .. Тестирование было выполнено в Eclipse IDE, но мое намеченное решение действительно работает, если вы используете ideone.com)



1

Желе: трещины

Это будет безумно легко по сравнению с удивительным Python-ответом Wheat Wizard, но здесь мы идем: P

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø<insert code snippet here>

Шестнадцатеричный sha256 моего решения, включая первый фрагмент, есть cfeb1e193ad77f66f039c0d6a792a3e4c311490f6412698e019ca1fae10c0e0a.

Запись

Вы можете не иметь никаких новых строк в коде, кроме строк, в противном случае этот код даже не будет выполняться, что противоречит цели этой задачи.

Взломанный DJMcMayhem

Честно говоря, здесь используется новая строка, поэтому я хотел бы увидеть решение, которое не использует новую строку.

Также решение Джонатана Аллана

Это не использует новую строку, поэтому он был взломан. :П

Мое решение таково:

“for c in code_page:
 if c in atoms:atoms[c].call=None”ŒVø“print(int(input())+int(input()))”ŒV

Первый фрагмент удаляет только односимвольные атомы, что означает, что Python eval все еще работает :)))


Второй фрагмент всегда добавляется в конец первого фрагмента.
Стивен

@StepHen Просто указав: P Но я забыл добавить заметку; это действительно важно.
HyperNeutrino

3
Я не думаю, что вы можете ограничить грабителей таким образом. Если вы можете взломать его с помощью Newlines, это действительный взлом. Есть ли способ предотвратить добавление символов новой строки или принудительное выполнение первой строки?
DJMcMayhem


1
Мне нравится твоя предполагаемая трещина. Очень подлый.
Деннис

1

JavaScript, Cracked

Вход: prompt()дважды

Выход: console.log()

Мое решение не работает в jsfiddle. Работает на странице about: blank с консолью Google Chrome JS.

prompt=console=0

Мое решение:

x=document.createElement("iframe")
x.src="data:text/html,<script>console.log(prompt()-0+(prompt()-0))</script>"
document.body.appendChild(x)

Объяснение:

Я удалил приглашение и консоль, установив их равными 0.

В своем решении я создаю iframe, который создает песочницу, и новый экземпляр окна, в котором приглашение и консоль работают правильно.



@CRDrost Я не верю, что в спецификации есть тестирование на простоту, и вы не показываете оба фрагмента.
Стивен

Извините, вы правы, я неправильно понял.
ЧР Дрост

1

Ява, Трещины

import java.lang.reflect.*;
public class Main{
  public static void main(String... args){
    System.setOut(null);
    System.setErr(null);
    /*Your code here*/
  }
}

Это должно было быть очень легко взломать.

Предполагаемое решение

import java.lang.reflect.*;
public class Main{
public static void main(String... args){
  System.setOut(null);
  System.setErr(null);
  try{
    Class<?> cistream = Class.forName("java.io.InputStream");
    Class<?> cfostream = Class.forName("java.io.FileOutputStream");
    Class<?> costream = Class.forName("java.io.OutputStream");
    Class<?> cfdescriptor = Class.forName("java.io.FileDescriptor");
    Object sout = cfostream.getConstructor(cfdescriptor).newInstance(cfdescriptor.getField("out").get(null));
    Class<?> csys = Class.forName("java.lang.System");
    Field mod = Field.class.getDeclaredField("modifiers");
    mod.setAccessible(true);
    Field stdout = csys.getField("out");
    mod.set(stdout,Integer.class.cast(mod.get(stdout) )&~ Modifier.FINAL);
    stdout.set(null,Class.forName("java.io.PrintStream").getConstructor(costream).newInstance(sout));
    Class<?> cscanner = Class.forName("java.util.Scanner");
    Object scanner = cscanner.getConstructor(cistream).newInstance(System.in);
    Method nextInt = cscanner.getMethod("nextInt");
    int f = Integer.class.cast(nextInt.invoke(scanner));
    int s = Integer.class.cast(nextInt.invoke(scanner));
    int sum = s + f;
    System.out.println(sum);
  }catch(Throwable t){t.printStackTrace();}
  }
}

Попробуйте онлайн



Я совсем забыл о java.io.. Но вы все
Роман

Я не вижу здесь никаких проблем. Я на самом деле написал второй фрагмент, просто забыл отредактировать его. По TIO первый snipppet компилируется без какого - либо предупреждения.
Роман Греф

@ OlivierGrégoire Готово. Я думаю, что любая IDE будет кричать на меня за это, но я, по крайней мере, компилятор принимает это ...
Roman Gräf
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.