Zainspirowany przez tym komentarzem ...
Dziękujemy użytkownikom Step Hen , Wheat-Wizard i Dennis za pomoc w ugruntowaniu specyfikacji tego wyzwania przed jego opublikowaniem!
To jest wątek Rabusia! Przejdź do wątku gliniarzy tutaj
W tym wyzwaniu masz za zadanie uruchomić kod, który sprawia, że Twój język nie spełnia już naszych kryteriów bycia językiem programowania. W tym wyzwaniu oznacza to, że język nie może już ...
Weź numeryczne dane wejściowe i wyjściowe
Dodaj dwie liczby razem
Sprawdź, czy określona liczba jest liczbą pierwszą, czy nie.
Jest to wyzwanie dla gliniarzy i rabusiów , w którym istnieją dwa różne wyzwania o dwóch różnych celach: gliniarze spróbują napisać kod, który sprawi, że język będzie w większości bezużyteczny, oraz złodzieje spróbują znaleźć ukryte obejście, które pozwala glinom odzyskać swój język.
Policjanci napiszą dwa fragmenty kodu:
Taki, który sprawia, że ich język jest w większości bezużyteczny, np. Poprzez usunięcie wbudowanych funkcji do pobierania danych wejściowych / wyjściowych i operacji numerycznych. Ten kod nie może ulec awarii ani wyjść. Powinno być możliwe dodanie kodu na końcu tego fragmentu, a ten kod zostanie poddany ocenie . I
Fragment kodu, który przyjmuje dwie liczby jako dane wejściowe, dodaje je do siebie i generuje ich sumę. Ten fragment kodu musi nadal poprawnie działać, nawet po uruchomieniu pierwszego fragmentu kodu. Gdy oba fragmenty zostaną połączone razem, muszą one utworzyć pełny program, który dodaje dwie liczby lub zdefiniować funkcję, która dodaje dwie liczby. Ten fragment kodu prawdopodobnie będzie polegał na niejasnym zachowaniu i będzie trudny do znalezienia.
Gliniarze również wybiorą dowolne standardową metodę wprowadzania i wyprowadzania . Muszą jednak ujawnić dokładnie, jakiego formatu (wejścia i wyjścia) używają. Aby złamać ich odpowiedź, musisz postępować zgodnie z tym samym formatem wejścia / wyjścia, w przeciwnym razie twój crack się nie liczy.
Odpowiedź gliniarzy zawsze ujawni
pierwszy fragment (oczywiście nie sekundę).
Język (w tym niewielka wersja, ponieważ większość zgłoszeń prawdopodobnie będzie polegać na dziwnych przypadkowych przypadkach)
Format IO, w tym czy jest to funkcja czy pełny program. Rabusie muszą używać tego samego formatu, aby być poprawnym crackem.
Wszelkie dziwne przypadki brzegowe wymagane do odpowiedzi. Na przykład działa tylko na systemie Linux lub wymaga połączenia z Internetem .
Jako złodziej musisz spojrzeć na jedno z oświadczeń gliniarzy i spróbować je złamać. Możesz go złamać, pisząc dowolny prawidłowy fragment, który mógłby działać jako fragment 2 (dodanie dwóch liczb razem po tym, jak język stanie się w większości bezużyteczny). To nie musi być ten sam fragment, który pierwotnie napisał policjant. Gdy masz pękniętą odpowiedź, opublikuj kod jako odpowiedź w tym wątku i opublikuj link do swojej odpowiedzi jako komentarz do odpowiedzi policjanta. Następnie ten post zostanie edytowany, aby wskazać, że został złamany.
Oto przykład. W przypadku pierwszego fragmentu możesz zobaczyć następujący program w języku Python 3 jako odpowiedź gliniarzy:
Python 3
print=None
Pobiera dane wejściowe ze STDIN i dane wyjściowe do STDOUT
Prawidłowy drugi fragment może być
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)
Jest to ważne, ponieważ weźmie dwie liczby jako dane wejściowe i wyświetli ich sumę, nawet jeśli połączysz oba fragmenty razem, np.
print=None
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)
To jest poprawny crack do ich odpowiedzi.
Jeśli odpowiedź gliniarza pozostaje nieprzetarta przez cały tydzień, może edytować w drugim fragmencie i wskazywać, że jego odpowiedź jest teraz bezpieczna . Po edycji jest bezpieczny, nie możesz już próbować go złamać. Jeśli nie będą go edytować jako bezpieczne, możesz próbować go złamać, dopóki nie zrobią tego.
Zwycięzcą wątku złodzieja jest użytkownik, który złamał najwięcej odpowiedzi, a rozstrzygnięciem był czas, w którym osiągnął N pęknięć. (więc jeśli dwóch różnych użytkowników ma na przykład 5 pęknięć, zwycięzcą jest użytkownik, który jako pierwszy opublikował 5. pęknięcie). Po upływie wystarczającego czasu zaakceptuję odpowiedź zwycięzcy największą liczbą głosów.
Baw się dobrze!
Wyjaśnienia zasad
Pierwszy fragment kodu musi działać poprawnie bez żadnych danych wejściowych . Może generować cokolwiek zechcesz, a to wyjście zostanie zignorowane. Tak długo, jak po wykonaniu fragmentu, drugi fragment działa poprawnie.
Drugi fragment musi zostać faktycznie wykonany, aby odpowiedź była poprawna. Oznacza to odpowiedź typu
import sys sys.exit()
nie jest poprawny, ponieważ nie łamie języka. Po prostu odchodzi.
Po zapewnieniu bezpieczeństwa twój wynik jest liczbą bajtów obu fragmentów .
Wróćmy do Proszę ujawnić wszelkie dziwne przypadki brzegowe wymagane do odpowiedzi na twoje pytanie ... Twoje zgłoszenie musi zawierać wystarczającą ilość informacji, zanim zostanie ujawnione, aby było odtwarzalne po ujawnieniu. Oznacza to, że jeśli Twoja odpowiedź stanie się bezpieczna, a następnie edytujesz: Oto moja odpowiedź. O tak, BTW to działa tylko wtedy, gdy uruchamiasz go na Solarisie, żarty na ciebie! Twoja odpowiedź jest nieprawidłowa i zostanie usunięta i nie zostanie uznana za kwalifikującą się do wygranej.
Drugi fragment kodu może ulec awarii po wygenerowaniu sumy. Tak długo, jak dane wyjściowe są nadal poprawne (na przykład, jeśli zdecydujesz się na wyjście do STDERR, a następnie otrzymasz kilka informacji o awarii, jest to nieprawidłowe)
Tabela liderów
Oto lista każdego użytkownika z co najmniej jednym pęknięciem, uporządkowana według wyniku, a następnie nazwy (alfabetycznie). Jeśli zgłosisz crack, zaktualizuj odpowiednio swój wynik.
#User #Score
Ilmari Karonen 8
Dennis 5
Olivier Grégoire 4
Sisyphus 3
Veedrac 3
Arnold Palmer 2
Bruce Forte 2
DJMcMayhem 2
Dom Hastings 2
ppperry 2
1bluston 1
2012rcampion 1
Ben 1
BlackCap 1
Christian Sievers 1
Cody Gray 1
HyperNeutrino 1
Joshua 1
Kaz 1
Mark 1
Mayube 1
Xnor 1
zbw 1
źródło
SecurityManager
w zasięgu ... Możesz również czytaćSystem.in
w tym momencie, ponieważ nie jest jeszcze zamknięty.sun.awt.SecurityManager
i"sun.awt.command"
są zależne od platformy i nie są częścią Java .System.getProperties().get("blah")
(ponieważ tylko zablokowałem dostęp , aleSystem.getProperty
nieSystem.getProperties
), ale to wystarczy! Dobra robota!C (GCC / Linux) autorstwa Syzyfa
Ten fragment kodu zamyka podaną funkcję i uruchamia nową (klasyczny wstrzyknięcie kodu), która sama się redefiniuje,
close
tak że zamiast zamykać fd, uruchamia pożądany kod.źródło
Python, rozwiązanie Wheat Wizard tutaj
To znaczy, możesz po prostu cofnąć limit rekurencji i nic złego się nie dzieje ...
Działa na TIO
Uwaga
To jest moje pierwsze zgłoszenie CnR, więc jeśli to złamie jakiekolwiek zasady, powiedz mi, a ja to usunę.
źródło
os.sys
, jeśli to robi różnicę: PHaskell Ben
Nadal mam numery dosłownym i znaki (używam
0
,'0'
i'-'
), a[a..]
i[a..b]
które są bardzo przydatne. I mam jedno-
, ale mógłbym się obejść.I ponownie
++
do wdrożeniar
(reverse
) i określićt
, ats
które sątail
itails
.x a b
zwracan
element thb
, gdzien
jest długościąa
minus jeden.x
zwykle można zdefiniować jakosnd.last.zip
. Funkcjad
pobiera listę i zwraca listę z elementami z pozycji, które są wielokrotnościami dziesięciu.l!!s
zwracan
element thl
, gdzies
jest odwróconą reprezentacją ciągun
.+
zwraca jako liczbę całkowitą sumę dwóch liczb naturalnych podanych jako ciągi odwrócone, podobnie-
dla różnicy.add
zwraca jako liczbę całkowitą sumę dwóch możliwie ujemnych liczb całkowitych podanych jako łańcuchy.Zastanawiam się, czy jest to trochę podobne do tego, co Ben miał na myśli.
źródło
:
jest w zasięgu, nawetNoImplicitPrelude
bez importowania czegokolwiek.C (gcc) Conora O'Briena
Wypróbuj online!
źródło
Python 2 by Wheat Wizard (czwarta iteracja)
Wypróbuj online!
Bez exploitów, tylko funkcja do dodania przy użyciu tylko znaków
' &)(,.:[]a`cdfijmonrt~'
, zgodnie z przeznaczeniem (właściwie tylko'(),.:[]`acdfijmnort'
).Nie starałem się streścić; Właśnie napisałem podwyrażenia dla wartości pośrednich, takich jak 0, i pusty ciąg i te zastąpione ciągiem.
Wypróbuj online!
Podstawową ideą jest to, że format ciągu
'{0:5}'.format('1')
dopełnia liczbę od zera do długości5
podobnej'1 '
. Przez połączenie dwóch takich ciągów''.join
, suma ich długości jest sumą liczb wejściowych. Następnie zajmujemy się0
końcem i sprawdzamy.find()
do końcowej pozycji, która jest sumą.Łańcuch
'{0:5}'
do sformatowania jest wytwarzany przez wyodrębnienie{:}
znaków z powtórzeń ciągów słowników utworzonych za pomocądict
. Ciąg repr dla każdego kolejnego summanda jest umieszczany tam, gdzie byłoby 5. Chciałem użyć takiego słownika{0:5}
, ale jego repr zawiera przestrzeń, która go zawiodła.Dane wejściowe 0 zaburzają proces, ponieważ łańcuch podrzędny ma minimalną długość 1. Mamy
and/or
w tym przypadku znaki z, aby dać pusty łańcuch w tym przypadku.źródło
int([]in[])
po prostuint()
zarówno jako wyjście woli 0.Haskell, autor: Laikoni
źródło
16-bitowy montaż w trybie rzeczywistym x86, autor: Joshua
Wyjaśnienie:
„Złamaniem” wprowadzonym przez kod Joshua jest ustawienie flagi pułapki (TF), która przełącza procesor w tryb jednostopniowy. Oznacza to, że tylko jedna instrukcja będzie wykonywana jednocześnie, zanim CPU zatrzyma się (pułapki) z przerwaniem typu 1. To pozwala debugerom na implementację jednego kroku kodu - jest to bardzo przydatne, ale prawdziwa PITA, jeśli chcesz uruchomić kod poza kontekstem debugera!
To jest następująca sekcja kodu, która włącza flagę pułapki:
Wdrożenie flagi pułapki oznacza, że mamy szansę wykonać dokładnie jedną instrukcję przed pułapkami procesora - to jest ta, która pojawia się natychmiast po
POPF
. Więc musimy sprawić, żeby to się liczyło.Sztuką jest
INT 3
instrukcja, która wywołuje przerwanie numer 3. Istnieją dwa powody, dla których działa to w celu „odblokowania” kodu:Flaga pułapki jest usuwana w modułach obsługi przerwań. To tylko część projektu Intela, ale prawdopodobnie zostało to zrobione z podstawowych powodów rozsądku. Pamiętaj, że realizacja flagą pułapek jest, że typ-1 przerwanie jest wywoływane po wykonaniu każdej instrukcji, więc jeśli TF nie zostało wyczyszczone,
INT 1
by sama wywołać przerwanie-byłoby przerwania przez całą drogę w dół. Ponadto przerywanie czyszczenia TF ułatwia debugowanie kodu, podobnie jak IDE, które automatycznie zastępuje wywołania funkcji bibliotecznych.Sposób, w jaki zakłócenia działają, jest zasadniczo taki sam jak daleko
CALL
. Wywołują procedurę obsługi przerwań, której adres jest przechowywany w odpowiedniej pozycji w globalnej tabeli wektorów przerwań. Ponieważ ta tabela zaczyna się pod adresem0x0000:0000
i jest przechowywana w formacie 4-bajtowymsegment:offset
, obliczenie adresu jest tak proste, jak pomnożenie 4 przez wektor / liczbę przerwań. W tym przypadku wywołujemy przerwanie 3, więc byłoby to 4 × 3 = 12.… A zauważysz, że Joshua starannie to dla nas przygotował. Przed włączeniem flagi pułapki ma następujący kod:
która ustawia
0x0000:000C
(moduł obsługi przerwańINT 3
) naBP:SI
. Oznacza to, że przy każdymINT 3
wywołaniu wypycha rejestr FLAGS na stos, a następnie adres zwrotny, a następnie rozgałęzia się doBP:SI
, co pozwala nam ponownie uruchomić wykonywanie kodu, w kontekście, w którym flaga pułapki jest wyłączona.Potem wszystko jest z górki
INT 3
. Wszystko, co musimy zrobić, to dodać dwie liczby razem i wydrukować wynik. Tyle że nie jest to tak proste w języku asemblerowym, jak w innych językach, więc tutaj spędzana jest większość kodu.Joshua jest umożliwienie złodzieja określić dowolny mechanizm I / O (S) chce , więc biorę uproszczone podejście od zakładając, że wartości są przekazywane w
DX
iCX
rejestrów . Jest to rozsądne, ponieważ ich kod „prologu” nie jest nigdzie zablokowany.Dane wyjściowe są następnie wykonywane przez zapisywanie bajtów ASCII bezpośrednio w pamięci wideo. Bufor wideo zaczyna się
0xB800:0000
od CGA, EGA i / lub VGA w trybie tekstowym, więc zaczynamy tam drukować. Format to: znak w niskim bajcie i atrybut koloru w wysokim bajcie. Oznacza to, że każdy znak ma przesunięcie 2-bajtowe. Po prostu iterujemy każdą z cyfr w liczbie (podstawa-10), konwertując je na ASCII i drukując je pojedynczo na ekranie. Tak, to dużo kodu. Brak funkcji bibliotecznych, które pomogłyby nam w asemblerze. Prawie na pewno można to dalej zoptymalizować, ale mam już dość pracy nad tym ...Po wyświetleniu danych wyjściowych kod może ulec awarii lub zrobić cokolwiek innego, więc po prostu usuwamy przerwania i zatrzymujemy procesor.
źródło
INT 3
i natychmiast kończę na instrukcji po nim, więc po prostu poszedłem z nim. Może ma to coś wspólnego z moim środowiskiem testowym?CLI
wyłączałby tylko przerwania sprzętowe, ale nawet gdyby się to udałoHLT
, pomyślałbyś, że wpadnie il
natychmiast wykona kod .Python 2 od TwiNight
Wypróbuj online!
źródło
Pyton 3 , ppperry „S 2. wyzwanie
Wow, było fajnie! Lubię to rozwiązywać.
Edycja: OK, naprawiłem to. Wygląda na to, że klasy znajdowały się pod innym indeksem na liście podklas w TIO niż na moim komputerze, więc sprawiłem, że działa dla obu i dodałem TIO.
Wypróbuj online!
źródło
sys.excepthook is missing
?sys.excepthook
, ale gdzieś tam będzie prawdziwa przyczyna.)IndexError('list index out of range',)
. Jest zgodny z definicją_io_RawIOBase
._io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]
powinien działać wszędzie.Haskell przez zbw
Nie można uruchomić kodu w czasie wykonywania? Uruchom go w czasie kompilacji!
To była świetna zabawa, przed tym wyzwaniem nie wiedziałem, że szablon haskell.
źródło
Galaretka hiperinino
Super proste. Nowa linia powoduje, że pierwszy link nie jest wywoływany.
Wypróbuj online!
źródło
Python 2 autorstwa Wheat Wizard
Wypróbuj online!
źródło
Java autorstwa LordFarquaad
Blokowanie dostępu do obiektów na poziomie źródła było naprawdę sprytne (i denerwujące podczas testowania), dobrze zrobione!
źródło
ClassLoader
było, gdyby ktoś został zacieniony?"".getClass().getClassLoader()
. Zacienianie jest zwykle tylko problemem, o którym musisz pomyśleć raz, a potem jest w porządku. Możesz nawet ocieniaćObject
, wciąż będę w stanie to rozwiązać. Ok, możesz zmusić mnie do rozwiązania 1kb, ale jest to możliwe.Ruby autorstwa histocrat
Wypróbuj online!
źródło
Poinformuj 7, Ilmari Karonen
Rażące nadużycie niejednoznacznych rzeczowników ... Mój kod zaczyna się od
factory is a room
. Poprzedni wiersz to kod policjanta. Wpiszadd 1 and 1
na przykład 2.źródło
Java, Roman Gräf
Zestawy
stdout
istderr
powrót do ich wartości początkowych.Wierzę, że jestem w stanie użyć w pełni kwalifikowanej nazwy zamiast importu, jeśli się mylę, popraw mnie (to mój pierwszy post tutaj). Prawdopodobnie można to zrobić również za pomocą refleksji.
Edycja: oto rozwiązanie odblaskowe wykorzystujące tylko
java.lang.reflect.*
:źródło
stdin
,stdout
istderr
są przechowywane w innym miejscu! Nawet nie trzeba korzystaćsetOut
isetErr
jak można po prostu użyćPrintStream
bezpośrednio.JavaScript autorstwa Daniela Franklina
To może być uważane za nieco podstępne rozwiązanie, ale działa dla mnie na Chromium 59 / Linux, nawet jeśli otrzymam również ostrzeżenie:
Ps. Oto kolejny trzask, tym razem bez ostrzeżeń:
źródło
prompt()- -prompt()
oszczędza dwa bajtyJava 8 autorstwa Oliviera Grégoire'a
Ogromnie verbose crack dla ogromnie verbose wyzwanie. :) Ból związany z pracą pośrednią z klasami, których nie można nazwać, jest wyczuwalny.
Wypróbuj online!
Ps. Oto moja wcześniejsza próba, napisana zanim Olivier wyjaśnił, że dane wejściowe miały być podejmowane za pomocą argumentów wiersza poleceń. W przeciwieństwie do powyższego crack, ten nie jest specyficzny dla Linuksa.
Wypróbuj online!
źródło
String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");
które nie jest specyficzne dla Linuksa, ale wykorzystuje coś, co wydaje się być nieudokumentowaną właściwością ustawioną przez niektóre maszyny JVM.C # (.NET Core) przez raznagul
Zakładam, że to nie było zamierzone rozwiązanie.
źródło
/dev/std*
there. I initially aimed for a similar approach, but couldn't find any easy way to open streams for stdin/out without access to System.Console, so I opted for reflection instead. Of course, your solution presumably only works on Linux and other Unixish systems with the appropriate/dev
entries, but raznagul didn't explicitly say it had to work on Windows. And it does work on TIO.Java, by racer290
This was rather a basic overlook that
static
initializers are called before themain
method. It was a nice try: I was dismayed by thethrow new Error()
at first, but found the way in the end ;)źródło
System.out.println("Hello World!");
Doesn't add two integers?.. "2. A snippet of code that takes two numbers as input, adds them together, and outputs their sum. This snippet must still correctly function even after running the first snippet. When the two snippets are combined together, they must form a full program that adds two numbers, or define a function that adds two numbers. This snippet will probably rely upon obscure behavior, and be hard to find."Java by Kevin Cruijssen
Well constructed. A lot of code to make anyone properly ponder how to solve this challenge. I guess the "put your code afterwards" was a big, big hint.
Try it here.
źródło
JavaScript by Grant Davis
Works in the JS console on the
about:blank
page (as specified in the cop post) on Chromium 59 / Linux.źródło
cQuents, Step Hen, 3 bytes
Try it online!
Took a lot of talking to Step Hen to figure out how the hell his weird language works, but in short:
His code was
#|1,1:A
.#|1,1
is the default input, meaning any input given to the program is appended by 2 1's. (IE if you pass a 47 and a 53, your input is[47, 53, 1, 1]
.:
simply sets the mode, which will output then
th item in the sequence ifn
is set, and otherwise output the entire sequence.Finally
A
gets the first input.Because we have 4 inputs
[47, 53, 1, 1]
, addingBC
to the end would also fetch the 2nd and 3rd input, and the 4th input implicitly becomesn
.Because our sequence is
ABC
, it's parsed algebraically, meaning it becomesA*B*C
. We don't want that, but if we insert a+
between A and B, it becomesA+B*C
, whereA
andB
are our inputs, andC
is 1.źródło
how the hell his weird language works
maybe once I finish it it might make some more senseC# (.NET Core) by raznagul
Try it online!
This would probably have taken less time if I actually knew any C#. However, with some browsing of the documentation and a bit of help from Jon Skeet, I managed to cobble together something that works.
źródło
Vim challenge by @DJMcMayhem
It's been a while since I wasn't able to exit vim, here's my solution (note it's far more than
23
bytes - so it's probably not the intended solution):Try it online!
The idea is simply to pipe the two integers to
awk
viabash
, since=
and+
were disabled I had to use a small work-around. Theawk
line expands to:Edit: The original intention was that the input is already in the buffer, but that wouldn't be more difficult - the main difficulty was to get addition working.
Here's the suggested fix by @DJMcMayhem: Try it online!
źródło
[insert your number here]
in insert mode. Instead, it's just already in the buffer. But you could get around that withOecho "<esc>Go"|awk...
, so I think this counts. Nicely done! This isn't the crack I had in mind (I was hoping for a pure vim answer) so I'll probably post a new answer that patches external commands and!
.Java 7 by Poke
Try it online!
No Linux-specific tricks needed, just simple masking of the unqualified
String
andSystem
class names. This is probably not the intended solution, but it works.źródło
GolfScript by Ilmari Karonen
Try it online!
źródło
RProgN2 by @ATaco
Try it online!
This is by far not the best answer I could've given, but it allows adding numbers together again. Had I actually went through and did proper stack handling, I could probably golf this quite a bit, but as of now I'm happy with the answer.
In ATaco's original post he effectively just reassigned all of the main arithmetic operators to destroy their inputs. To fix this problem I redefined what addition was in terms of its binary operations, which was a pain because RProgN2 doesn't have a binary negation operator or xor.
Note: If you want to test the input, numbers with more than one digit need to be in the form
"XX..." n
to be converted into an actual number since RProgN2 takes each character as is unless it's a concept or string. Edit: @ATaco noted that adding a '$' before a multidigit number will do the same thing.EDIT: Here is the logic for my solution. As you can see, most definitely not the most refined code, but it works.
źródło
56$46$12
will push the numbers 5, 6, 46 and 12. I'll post my actual solution and such tommorowJavaScript (Node.js) by jrich, 298 bytes
I feel like this isn't the intended solution, but if it is, well done, I spent a while trying to figure out how to get the name of the declared function! :)
Try it online!
źródło