为什么这个命令会回来"获得生命!"?

时间:2016-06-17 11:48:00

标签: unix command dc

当我偶然发现这个时,我正在查看Funny UNIX Commands的列表:

$ echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc
GET A LIFE!

我从未读过关于dc命令的内容,因此我浏览了Wiki页面,并设法学会做一些小事情:

$ echo "4 5 + p" | dc
9
$ echo "2 10 ^ p" | dc
1024

然而,命令[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq听起来对我来说太过分了。有没有办法让它以一种可以理解的方式解释(让我的生活回归)?

1 个答案:

答案 0 :(得分:5)

  

......命令   [q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq   听起来对我来说太过分了。有没有办法解释它   一种可以理解的方式......

man dc的相关部分:

  
  输入一个数字会将其推送到堆栈中。   
[字符
  
创建一个包含字符的字符串(包含在平衡的 [] 字符之间),然后将其推送到堆栈中。
  
取值 [R
  
从堆栈顶部弹出值并将其存储到寄存器 r
  
1 [R
  
复制寄存器 r 中的值并将其推入堆栈。
  
X
  
从堆栈中弹出一个值并将其作为宏执行。
  
= [R
  
从堆栈中弹出两个值,并假设它们是数字进行比较,如果弹出的两个数字相等,则将寄存器 r 的内容作为宏执行。
  
/
  
弹出两个值,将弹出的第二个值除以弹出的第一个值,然后推送结果。
  
  
弹出两个值,计算 / 命令所执行的除法的剩余部分,然后推送它。
  
P
  
弹出堆栈顶部的值。如果它是一个字符串,它只是打印没有尾随换行符。否则它是一个数字和整数   其绝对值的一部分打印为“基础(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,i。即退出宏。
  • ln256%P打印出字段n mod 256,在第71位,即ASCII G
  • ln256/snn除以256,从而切断最后一个字节。
  • lbx重复执行注册表ln0=aln256%Pln256/snlbx中的字符串b。重复执行产生ASCII字节E T A L I F {{1 }} E !先后。

UNIX fun stuff - echo and dc - obfuscate/garble a string sort of中,您可以找到用于混淆这样的字符串的脚本,以及如何使用它的说明:

  

如果将以下脚本保存在名为obfuscate的文件中:

\n
     

使其可执行:

#!/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
     

(...)If不适用于不在7位ASCII中的字符   字符集,如果要混淆的文本,它将无法工作   包含任何NUL字节,并且在许多系统上,如果输入,它将无法工作   您想要混淆的文件长于LINE_MAX字节,如果是   由obfuscate生成的输出产生的字符串长于LINE_MAX,   在某些系统上,dc可能无法为您解密。