Почему эта команда возвращает "ПОЛУЧИТЕ ЖИЗНЬ!"?
Я просматривал список Забавных Команд UNIX, когда наткнулся на эту:
$ echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc
GET A LIFE!
Я никогда не читал о dc
команда, поэтому я прошел страницу вики и сумел научиться делать такие мелочи, как:
$ echo "4 5 + p" | dc
9
$ echo "2 10 ^ p" | dc
1024
Тем не менее, команда [q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq
звучит слишком много для меня. Есть ли способ объяснить это понятным образом (и вернуть мою жизнь)?
1 ответ
… команда
[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq
звучит слишком много для меня. Есть ли способ объяснить это понятным образом...
Соответствующие части man dc
:
Ввод числа помещает его в стек.
- [ персонажи ]
- Создает строку, содержащую символы (содержащиеся между сбалансированными символами [ и ]), и помещает ее в стек.
- с р
- Выкиньте значение из верхней части стека и сохраните его в регистре r.
- л р
- Скопируйте значение в регистр r и поместите его в стек.
- Икс
- Вытаскивает значение из стека и выполняет его как макрос.
- = г
- Вытаскивает два значения из стека и сравнивает их, предполагая, что они являются числами, выполняя содержимое регистра r как макрос, если два выдвинутых числа равны.
- /
- Выдвигает два значения, делит второе, извлеченное из первого, и выталкивает результат.
- %
- Получает два значения, вычисляет остаток от деления, которое будет выполнять команда /, и выталкивает это.
- п
- Выскакивает значение в верхней части стека. Если это строка, она просто печатается без завершающей строки. В противном случае это число, и целочисленная часть его абсолютного значения выводится в виде потока байтов "base (UCHAR_MAX+1)".
- Q
- выходит из макроса, а также из макроса, который его вызвал. При вызове с верхнего уровня или из макроса, который был вызван непосредственно с верхнего уровня, команда q вызовет выход dc.
Так,
[q]sa
хранит строкуq
в реестрa
,[ln0=aln256%Pln256/snlbx]sb
хранит строкуln0=aln256%Pln256/snlbx
в реестрb
,3135071790101768542287578439sn
хранит номер3135071790101768542287578439
вn
,lbx
выполняет строкуln0=aln256%Pln256/snlbx
из реестраb
,ln0=a
выполняет, еслиn
равно нулю, строкаq
из реестраa
т.е. выходит из макроса.ln256%P
распечатывает байтn
мод 256, сначала 71, что является ASCIIG
,ln256/sn
водоразделыn
на 256, тем самым обрезая последний байт.lbx
периодически выполняет строкуln0=aln256%Pln256/snlbx
из реестраb
, Повторяющиеся исполнения дают байты ASCIIE
T
A
L
I
F
E
!
\n
последовательно.
В увлекательных материалах UNIX - echo и dc - obfuscate/garble - строка, в которой вы можете найти скрипт для обфускации строк, например, вместе с объяснением того, как его использовать:
Если вы сохраните следующий скрипт в файле с именем obfuscate:
#!/bin/ksh # NAME: obfuscate -- obfuscate text read from one or more files into a # string that can be decrypted by the dc utility # # SYNOPSIS: obfuscate file... # # OPERANDS: file The name of a text file containing text to be # obfuscated or "-" to obfuscate text read from # standard input. # # APPLICATION USAGE: # To decrypt the obfuscated string produced by obfuscate, use: # obfuscate file | read string # Get obfuscated text # Note: Do not use "read -r string" in the above command! # printf '%s\n' "$string" # Show obfuscated text # echo "$string" | dc # Decrypt obfuscated text # # Although dc can produce artibrary length output, feeding the objuscated # string back into dc for decryption may be limited by {LINE_MAX} and/or # {ARG_MAX} restrictions. # Initialize a to ASCII character set (skipping NUL)... a='\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33' a="$a"'\34\35\36\37 !"#$%&'"'"'()*+,-./0123456789:;<=>?@' a="$a"'ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\377' awk -v A="$a" ' function cline(inline, i) { printf("256*%d+\n", index(A, "\n")) for(i = length(inline); i; i--) { printf("256*%d+\n", index(A, substr(inline, i, 1))) } } BEGIN { print 0 } { line[NR] = $0 } END { for(i = NR; i; i--) cline(line[i]) printf("[[q]sa[ln0=aln256%%Pln256/snlbx]sb]Pn[snlbxq\n]Pq\n") }' "$@" | tee .dc_input | dc
сделать его исполняемым с помощью:
chmod +x obfuscate
и выполните команду:
printf "Hello World.\nAre we there yet?\nLet's go home, now!\n" | ./obfuscate - | read string
тогда команда:
echo "$string"
дам тебе:
[q]sa[ln0=aln256%Pln256/snlbx]sb26160072918627741401952510855241017735603346265259888938898171600856988789569756293233903076568696999873394858335331444040snlbxq
и команда:
echo "$string"|dc
дам тебе:
Hello World. Are we there yet? Let's go home, now!
(...) Если не будет работать с символами, которых нет в 7-битном наборе символов ASCII, и не будет работать, если текст, который вы хотите обфусцировать, содержит байты NUL, а во многих системах он не будет сработает, если строка в файлах, которые вы хотите запутать, длиннее, чем байты LINE_MAX, и если вывод, созданный obfuscate, создает строку длиннее, чем LINE_MAX, dc может не иметь возможности расшифровать ее для вас в некоторых системах.