这个混淆的 Perl 代码是如何工作的?
这段代码到底是如何工作的?
#!/usr/bin/perl
$i=4;$|=@f=map{("!"x$i++)."K$_^\x{0e}"}
"BQI!\\","BQI\\","BQI","BQ","B","";push
@f,reverse@f[1..5];@f=map{join"",undef,
map{chr(ord()-1)}split""}@f;{;$f=shift@
f;print$f;push@f,$f;select undef,undef,
undef,.25;redo;last;exit;print or die;}
How does this code work at all?
#!/usr/bin/perl
$i=4;$|=@f=map{("!"x$i++)."K$_^\x{0e}"}
"BQI!\\","BQI\\","BQI","BQ","B","";push
@f,reverse@f[1..5];@f=map{join"",undef,
map{chr(ord()-1)}split""}@f;{;$f=shift@
f;print$f;push@f,$f;select undef,undef,
undef,.25;redo;last;exit;print or die;}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
让我们首先通过 perltidy
第一行很明显。
第二行创建一个列表
">>>E!)", ">>>E)", ">>>E", ">>>" 、“>>”、“>”、“”
,并将它们全部间隔为同等长度,并附加一个星号和“Shift Out”(回车符后的字符)。第三行将项目 5 到 1(按该顺序)附加到该列表中,因此它将是
">>>E!)", ">>>E)", "> ;>>E"、">>>"、">>"、">"、""、">"、">>"、">>> ;”,“>>E”
。映射将所有字符减一,从而创建类似
8===D ()
的元素。第二个循环只是每 0.25 秒循环打印一次列表中的元素。回车会使它们相互覆盖,从而看到动画。最后几行永远不会到达,因此是伪造的。
Lets first put this through perltidy
The first line is obvious.
The second line makes a list
">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", ""
, and spaces them all to be equally long and appends an asterisk and a 'Shift Out' (the character after a carriage return).The third line appends items 5 to 1 (in that order) to that list, , so it will be
">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "", ">", ">>", ">>>", ">>>E"
.The map decrements the all characters by one, thus creating elements like
8===D ()
.The second loop simply prints the elements in the list in a loop every 0.25 seconds. The carriage return causes them to overwrite each other, so that an animation is seen. The last couple of lines are never reached and thus bogus.
文件中的数据被加载到称为 Perl 解释器的程序中。解释器解析代码并将其转换为一系列“操作码”——一种介于 Perl 代码和代码运行的机器语言之间的字节码语言。如果转换过程(称为“编译”)中没有错误,则代码将由 Perl 解释器的另一部分执行。在执行过程中,程序可能会改变机器的各种状态,例如分配、解除分配、读取和写入内存,或使用系统的输入/输出和其他功能。
(CW - 欢迎比我更多的铁杆黑客纠正任何错误或误解并添加更多信息)
Data from the file is loaded into a program called a Perl interpreter. The interpreter parses the code and converts it to a series of "opcodes" -- a bytecode language that is sort of halfway between Perl code and the machine language that the code is running on. If there were no errors in the conversion process (called "compiling"), then the code is executed by another part of the Perl interpreter. During execution, the program may change various states of the machine, such as allocating, deallocating, reading, and writing to memory, or using the input/output and other features of the system.
(CW - More hardcore hackers than I are welcome to correct any errors or misconceptions and to add more information)
这里没有发生任何魔法,只是令人困惑。让我们从高层次来看。首先要注意的是,稍后,字符串中的每个字符都会被解释为前一个字符:
因此,像“6qD”这样的字符串将导致“5rC”(“6”、“q”之前的字符)和“D”,分别)。主要的兴趣点是开头附近的字符串数组:
这定义了我们稍后将替换到该字符串中的“掩码”序列:
它们将插入到
$_
点。字符串\x{0e}
表示十六进制控制字符;请注意,其前面的字符\x{0d}
是回车符。当我们执行 [1] 时,这就是将被替换为 [3] 的内容。在组装 [3] 字符串之前,我们在 [2] 中的每个元素前面添加一些等于 i 的
!
。每个连续的元素都比它之前的元素多一个!
。请注意,值位于!
之前的字符是空格。
脚本的其余部分迭代每个组装的数组元素,现在看起来更像是这样:
然后,
reverse
操作反向附加相同的元素,创建一个循环。此时,您应该能够看到生成动画的模式。现在只需在动画中的每个步骤中移动然后再返回即可,这是由脚本的其余部分完成的。每个步骤的时间步延迟由 select 语句控制:
它告诉我们在每次迭代之间等待 250 毫秒。如果您想看到它加速或减慢,您可以更改此设置。
There's no magic going on here, just obfuscation. Let's take a high-level view. The first thing to notice is that later on, every character in strings is interpreted as if it were the previous character:
Thus, a string like "6qD" will result in "5rC" (the characters before '6', 'q', and 'D', respectively). The main point of interest is the array of strings near the beginning:
This defines a sequence of "masks" that we will substitute later on, into this string:
They'll get inserted at the
$_
point. The string\x{0e}
represents a hex control character; notice that\x{0d}
, the character just before it, is a carriage return. That's what'll get substituted into [3] when we do [1].Before the [3] string is assembled, we prepend a number of
!
equal to i to each element in [2]. Each successive element gets one more!
than the element before it. Notice that the character whose value is just before!
is a space.
The rest of the script iterates over each of the assembled array elements, which now look more like this:
Then the
reverse
operation appends the same elements in reverse, creating a loop.At this point you should be able to see the pattern emerge that produces the animation. Now it's just a matter of moving through each step in the animation and back again, which is accomplished by the rest of the script. The timestep delay of each step is governed by the select statement:
which tells us to wait 250 milliseconds between each iteration. You can change this if you want to see it speed up or slow down.