Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Step № 1 to understand obfuscated Perl: run it through <code>-MO=Deparse</code>. Then, we get this output: (with a small syntax error removed)</p> <pre><code>use warnings; use strict; my($japh, $q, $qq, %b) = "Just another Perl hacker\n"; $_ = join('', (1045737470, 21650696, 478656270, 205562730, 602861636, 965627100)); s/9/f/; s/9/b/; $q = $_; *9 = sub { $japh = ''; print $japh; } ; map {m{^((?i)(?#q#; print \$japh;#()[^ for (my $(b) = 1; $(b) &lt; $(q); \$b++;) { /g])+[\](^.^)\[ } ]*$}x ? do { $qq = ord($_) - 96 . (~~%b - $?); $/ = $+; $q =~ s[$qq][$/]g } : 9-&gt;({});} 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'; $qq = [$q, %b]; $\ = pack('h*', '' . $$qq[0]); 9-&gt;(); </code></pre> <p>Still not pretty, but better. Especially, this regex looks interesting:</p> <pre><code>m{^((?i)(?#q#; print \$japh;#()[^ for (my $(b) = 1; $(b) &lt; $(q); \$b++;) { /g])+[\](^.^)\[ } ]*$}x </code></pre> <p>The <code>(?# ... )</code> is an embedded comment, which we can remove. Next on are the character classes</p> <pre><code>[^ for (my $(b) = 1; $(b) &lt; $(q); \$b++;) { /g] </code></pre> <p>and</p> <pre><code>[\](^.^)\[ } ] </code></pre> <p>Here, they are equivalent to <code>[^bfgmoqry]</code> and <code>[\[\]()^.}\s]</code>, but as the regex will only ever be matched against single chars, the <code>[...]*</code> will match zero characters.</p> <p>Thus, the regex is equivalent to</p> <pre><code>m/^([^bfgmoqry])$/ </code></pre> <p>in this <em>special case</em> (being matched against <code>"a" .. "z"</code>).</p> <p>The <code>*9 = sub {...}</code> assigns a coderef to a glob. Because <code>9</code> isn't a valid subroutine name, but can still be used with the <code>-&gt;</code> operator, <code>9-&gt;()</code> invokes that coderef. This is just like with <code>sub foo {...}</code>, <code>foo()</code> and <code>"foo"-&gt;()</code> are the same thing.</p> <p>The char <code>a</code> is encoded as decimal <code>97</code> as ASCII, so <code>ord("a")-96</code> is <code>1</code>, for <code>z</code>, that would be 26.</p> <p>The <code>$?</code> is the last child error, and should be zero. <code>$+</code> is the value of the last capture group (ergo, <code>$_</code>). The <code>~~%b</code> double-negates an empty hash. The scalarification of an empty hash is <code>0</code>, so double bitwise negation produces zero again.</p> <p>The <code>$/ = $+; $q =~ s[$qq][$/]g</code> is just a bit obfuscation; as <code>$+</code> is <code>$_</code>, we could directly write <code>$q =~ s/$qq/$_/g</code>.</p> <p>The <code>$qq = [$q, %b]; ... $$qq[0]</code> is lame, a <code>$\ = pack('h*', $q)</code> suffices.</p> <p>In the <code>9</code> sub, the empty string will be printed, followed by <code>$\</code>, which is set to the empty string up to the penultimate line. Removing this level of indirection, and any now unused variables, as well as the simple substitutions, we get:</p> <pre><code>use warnings; use strict; my $q = '1045737470216506f6478656270205562730602861636b65627100'; for ("a" .. "z") { m/^([^bfgmoqry])$/ or next; my $qq = ord($_) - 96; $q =~ s/${qq}0/$_/g; } print pack('h*', $q); </code></pre> <p>The <code>s/${qq}0/$_/g</code> substitution can only match at zeros, and we know that the output will be some hex-number for the <code>pack</code>. Possible positions for matching are:</p> <pre><code>1045737470216506f6478656270205562730602861636b65627100 *^ *^ *^ *^*^ *^*^ *^^ a g e g b c f a </code></pre> <p>of which <code>b, f, g</code> is forbidden due to the regex. The resulting string is</p> <pre><code>a45737470216e6f64786562702055627c602861636b65627a0 </code></pre> <p>Which decodes to the JAPH.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload