……这个命令
[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq
对我来说听起来太过分了。有没有什么办法可以用一种可以理解的方式来解释……</p>
的相关部分man dc
:
输入一个数字会将其推入堆栈。
- [字符]
- 创建一个包含字符的字符串(包含在平衡的[和]字符之间),并将其压入堆栈。
- sr _
- 从堆栈顶部弹出值并将其存储到寄存器r中。
- l r
- 复制寄存器r中的值并将其压入堆栈。
- X
- 从堆栈中弹出一个值并将其作为宏执行。
- = 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
从 register执行字符串b
。
ln0=a
如果n
等于 0,则执行q
register中的字符串a
,即退出宏。
ln256%P
打印出字节n
mod 256,首先是 71,即 ASCII G
。
ln256/sn
除以n
256,从而切断最后一个字节。
lbx
重复执行ln0=aln256%Pln256/snlbx
register中的字符串b
。E
T
A
L
I
F
E
!
\n
重复执行连续产生 ASCII 字节。
在UNIX fun stuff - echo 和 dc - obfuscate/garble a string sort of you can find the script to obfuscate strings like this,以及如何使用它的说明:
如果将以下脚本保存在名为 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 字节,并且如果混淆产生的输出产生的字符串长于 LINE_MAX,则 dc 可能无法在某些系统上为您解密它。