<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Daily Llama &#187; /packer/</title>
	<atom:link href="http://llamaslayers.net/daily-llama/tag/packer/feed" rel="self" type="application/rss+xml" />
	<link>http://llamaslayers.net</link>
	<description>The ramblings on of a cat loving programmer</description>
	<lastBuildDate>Fri, 03 Sep 2010 23:04:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Unpacking /packer/</title>
		<link>http://llamaslayers.net/daily-llama/553/unpacking-packer</link>
		<comments>http://llamaslayers.net/daily-llama/553/unpacking-packer#comments</comments>
		<pubDate>Sat, 02 Aug 2008 00:40:57 +0000</pubDate>
		<dc:creator>Ben L.</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[/packer/]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://llamaslayers.net/daily-llama/?p=553</guid>
		<description><![CDATA[Ever since I started working on the mostly Ajax app &#8220;VKitty&#8220;, I&#8217;ve been looking into JavaScript compression, and trying to figure out how it works.  Most compressors have very simple ways to compress JavaScript, by simply removing whitespace, but Dean &#8230; <a href="http://llamaslayers.net/daily-llama/553/unpacking-packer">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ever since I started working on the mostly Ajax app &#8220;<a href="http://vkitty.co.cc/">VKitty</a>&#8220;, I&#8217;ve been looking into JavaScript compression, and trying to figure out how it works.  Most compressors have very simple ways to compress JavaScript, by simply removing whitespace, but Dean Edwards&#8217;s <em>/packer/</em> defies the simplicity of most compressors by making an unreadable function that acts the same as the JavaScript you feed it, also known as obfusication.</p>
<p>I&#8217;ve decided to find out how it works, and I&#8217;m starting with something very simple.  &#8220;<span style="font-family: courier new,courier;">alert(&#8216;STUFF GOES HERE&#8217;)</span>&#8220;.</p>
<p>First, I packed it in <a href="http://dean.edwards.name/packer/"><em>/packer/</em></a>.  I got back the code &#8220;<span style="font-family: courier new,courier;">eval(function(p,a,c,k,e,r){e=String;if(!&#8221;.replace(/^/,String)){while(c&#8211;)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return&#8217;\\w+&#8217;};c=1};while(c&#8211;)if(k[c])p=p.replace(new RegExp(&#8216;\\b&#8217;+e(c)+&#8217;\\b&#8217;,'g&#8217;),k[c]);return p}(&#8217;0(\&#8217;1 2 3\&#8217;)',4,4,&#8217;alert|STUFF|GOES|HERE&#8217;.split(&#8216;|&#8217;),0,{}))</span>&#8220;, which is really unreadable.</p>
<h3>Let&#8217;s unpack the <em>/packer/</em>.</h3>
<p>I did a bit of formatting on the function returned by <em>/packer/</em>:<span style="color: #888888;"> (it&#8217;s an image because I couldn&#8217;t get syntax highlighting to work on my blog)</span></p>
<div id="attachment_554" class="wp-caption alignnone" style="width: 471px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center;"><a href="http://llamaslayers.net/daily-llama/wp-content/uploads/2008/08/packer-unpacked-1.png"><img class="size-medium wp-image-554" title="/packer/: Unpacked" src="http://llamaslayers.net/daily-llama/wp-content/uploads/2008/08/packer-unpacked-1.png" alt="/packer/: Unpacked" width="461" height="196" /></a><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">/packer/: Unpacked (Click for a bigger view)</p></div>
<p>If you can&#8217;t already see what&#8217;s happening, I&#8217;ll walk you through it.  It basically creates a function, calls itself, and evaluates the result as JavaScript.  Here it is, line by line:</p>
<p>Line 1: <span style="font-family: courier new,courier;">eval(</span><br />
Evaluates the code that is created by the function.</p>
<p>Line 2: <span style="font-family: courier new,courier;">function (p, a, c, k, e, r) {</span><br />
Starts the declaration of a function, via shameless plug.</p>
<p>Line 3: <span style="font-family: courier new,courier;">e=String;</span><br />
Makes the variable <span style="font-family: courier new,courier;">e</span> into a function that returns whatever it is given as a string.</p>
<p>Line 4: <span style="font-family: courier new,courier;">if (!&#8221;.replace(/^/, String)) {</span><br />
This seems pointless to me, because evaluating the code inside the if statement would always return true.  I even removed the code, and it kept working!  The code is probably for compliance with less-up-to-date JavaScript implementations.</p>
<p>Line 5: <span style="font-family: courier new,courier;">while(c&#8211;) r[c] = k[c] || c;</span><br />
While the <span style="font-family: courier new,courier;">c</span> variable is above zero, reducing <span style="font-family: courier new,courier;">c</span> by 1 every time, the <span style="font-family: courier new,courier;">r</span> variable (an empty object) gets a new variable inside it: one of the words contained in <span style="font-family: courier new,courier;">k</span>, or <span style="font-family: courier new,courier;">&#8216;alert|STUFF|GOES|HERE&#8217;</span>, split at the <span style="font-family: courier new,courier;">|</span>&#8216;s.  If the variable doesn&#8217;t exist (which shouldn&#8217;t happen), it puts the key into the array so it will replace with itself.</p>
<p>Line 6: <span style="font-family: courier new,courier;">k = [function (e) {</span><br />
The variable <span style="font-family: courier new,courier;">k</span> is turned into an array with a function inside it.</p>
<p>Line 7: <span style="font-family: courier new,courier;">return r[e]</span><br />
Return the <span style="font-family: courier new,courier;">x</span><span style="font-family: courier new,courier;"><sup>th</sup></span> word in <span style="font-family: courier new,courier;">r</span>. (<span style="font-family: courier new,courier;">x</span> is the variable <span style="font-family: courier new,courier;">e</span>)</p>
<p>Line 8: <span style="font-family: courier new,courier;">}];</span><br />
Closing the function-in-an-array statement.</p>
<p>Line 9: e = <span style="font-family: courier new,courier;">function () {</span><br />
The variable <span style="font-family: courier new,courier;">e</span> is now another function, not the String function, let&#8217;s see what it does:</p>
<p>Line 10: <span style="font-family: courier new,courier;">return &#8216;\\w+&#8217;</span><br />
In <a href="http://en.wikipedia.org/wiki/Regular_expression">regex</a>, this means &#8220;find as many alphanumeric characters as possible&#8221;.</p>
<p>Line 11: <span style="font-family: courier new,courier;">};</span><br />
Closing a function.</p>
<p>Line 12: <span style="font-family: courier new,courier;">c=1</span><br />
We are no  longer looking for words 4 (in this case) times, but 1.  This is only possible because of the stuff inside the if statement.</p>
<p>Line 13: <span style="font-family: courier new,courier;">};</span><br />
Ending an if statement.  Note the unnecessary semicolon.</p>
<p>Line 14: <span style="font-family: courier new,courier;">while (c&#8211;)</span><br />
While the variable <span style="font-family: courier new,courier;">c</span> is nonzero, reducing it by 1 <em>after</em> we test for nonzero-ness.</p>
<p>Line 15: <span style="font-family: courier new,courier;">if (k[c])</span><br />
Make sure <span style="font-family: courier new,courier;">k</span> has <span style="font-family: courier new,courier;">c</span> as one of its keys.</p>
<p>Line 16: <span style="font-family: courier new,courier;">p = p.replace(new RegExp(&#8216;\\b&#8217;+e(c)+&#8217;\\b&#8217;,'g&#8217;), k[c]);</span><br />
Replace the p variable with the <span style="font-family: courier new,courier;">k[c]</span> variable instead of the <span style="font-family: courier new,courier;">c</span> variable&#8217;s value.</p>
<p>Line 17: <span style="font-family: courier new,courier;">return p</span><br />
Return the final value.</p>
<p>Line 18: <span style="font-family: courier new,courier;">} (&#8217;0(\&#8217;1 2 3\&#8217;)', 4, 4, &#8216;alert|STUFF|GOES|HERE&#8217;.split(&#8216;|&#8217;), 0, {})</span><br />
Set the <span style="font-family: courier new,courier;">p, a, c, k, e, r</span> variables.</p>
<p>Line 19: <span style="font-family: courier new,courier;">)</span><br />
Close the eval statement.</p>
]]></content:encoded>
			<wfw:commentRss>http://llamaslayers.net/daily-llama/553/unpacking-packer/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
