Sir Isaac or: How I Learned to Stop Worrying and Love the Newton Virus

By Stephen Jayna, 1st June 2009

841,464 YouTube views later and Troika's Newton Virus is released into the wild. And here's how it was done. Oh, by the way, it's not really a virus. Silly.


A Screenshot of The Newton Virus In Action
The Newton Virus In Action

Update 4th Sept 2009: I'm working on a version for Snow Leopard almost as I type. Read about it here.

Update 11th June 2009: Added section Auto-running The 'virus' From A USB Stick

Background

Named after the father of modern mechanics, the 'Newton Virus' introduces the concept of gravity causing your desktop to behave exactly as it would in the real physical environment. Desktop icons become susceptible to Newton’s invisible force and fall, roll and tumble in whatever direction gravity pulls them delivering a little bit of reality to your virtual environment. Read more and watch the videos here at Troika's website.

How It Was Done: In Brief

As you've surely guessed your desktop hasn't suddenly taken heed of Newton and decided that its current incumbants should behave accordingly. Nor is it really your icons that are taking a tumble ending in a crumpled heap, looking up in horror as a menu bar bears down on them from above. More's the pity.

— Spoiler Alert —

It turns out that all Mac laptops since October 2006 have included a Sudden Motion Sensor, perhaps better known to you and me as an accelerometer. You know, the sort of thing you'd find in an iPhone or Wii controller. Ostensibly it's to protect your hard disk drive from meeting an untimely demise when dropped. Butterfingers. But thanks to Unimotion that sensor can be harnessed for more, in our case at least, nefarious uses.

So that takes care of how we know that you're turning your laptop round and round trying to knock seven bells out of an otherwise innocent desktop icon. But how do we manipulate your desktop so? We begin by taking screenshots that's how. Lots of them! It's just like hitting Command-Shift-4 then spacebar and saving every object on the desktop indivdually, including your wallpaper. These images are then used in conjunction with Box2D, a piece of software that simulates real world physics. And voilà!

You'll be pleased to hear your desktop is never in any real danger: the 'virus' is just a façade. It's still there - your desktop that is - intact, oblivious to the chaos being meted out above it by the laws of nature. And so there you have it I suppose. I must confess that I hope some of you had your heart in your mouths the first time you saw it.

Credit and thanks to Troika for coming up with such a wonderful concept and for giving me the fun of implementing it.

Watch the original video here

How It Was Done: Not So Brief

A Disclaimer

Some of the techniques employed within are dubious and I wouldn't condone using them but for their artistic effect. A means to an end if you will. Bear that in mind before you recoil in horror at the methods that have been used. Of course if you've any better ideas on how to go about surmounting the challenges within they'd be most gratefully received.

The code was written in a mixture of Objective-C, C++ and a dollop of OpenGL.

Finally before you proceed I assume you've watched this video at the very least!

Auto-running The 'virus' From A USB Stick

Having the 'virus' run the moment the USB stick is inserted into the computer proved impossible. Once upon a time Apple allowed you to auto-run applications from a USB stick, much like you can on Windows. However — in their infinite wisdom — they decided it was potentially dangerous and it was last seen back in Mac System 9. Really some time ago. If we were on Windows, as far as I'm aware, we could have a U3 enabled flash drive emulate a CD-ROM, and configure its autorun.inf to launch the 'virus'.

Ejecting The USB Stick And Keeping The 'virus' Running

Key to the USB version is that the 'virus' continues to lie in wait even after the USB device has been ejected from the laptop. Sure, we could have copied it to your hard disk, but it seemed sensible not to start replicating ourself. It's such terrible PR you understand. Instead the 'virus' continues to run in memory only a reboot (or if I'm honest a page fault) away from oblivion.

First off you can't eject a device which is in use, be it a USB stick, a CD-ROM, or any other kind of removable media. It's naughty, can lead to 'unexpected behaviour', and you generally get a nasty looking warning if you try. Hardly what you want when you're trying to be sneaky.

However, if you purport to know what you're doing, there is a way around this. After discovering what device we're running from (and ensuring it is actually a USB device I hasten to add) we forcibly eject said device.

First find all the mounted removable media:

NSArray *volPaths = [[NSWorkspace sharedWorkspace] mountedRemovableMedia];

The 'virus' actually goes one step further and ensures that the removable media is in fact a USB device. Almost all USB devices have a serial number that is unique to them so I'm led to believe. It's possible to use IOKitLib to give us the value for the key 'USB Serial Number'. If you're interested you can see all sorts of properties attached to your hardware by running IORegistryExplorer, bundled with Xcode. It was quite the insight.

Then find out where our bundle is being run from:

NSString *ourPath = [[NSBundle mainBundle] bundlePath];

Then loop over [volPaths] until we find [ourPath]. This is the volume we need to unmount, using force:

  #include <DiskArbitration/DiskArbitration.h>

  DASessionRef session = NULL;
  DADiskRef disk = NULL;
                
  session = DASessionCreate(kCFAllocatorDefault);
                
  disk = DADiskCreateFromBSDName(kCFAllocatorDefault,
                                             session,
                                             [[volPath] UTF8String]);
                
  DADiskUnmount(disk,kDADiskUnmountOptionForce,NULL,NULL);
                
  CFRelease(disk);
  CFRelease(session);

Or a somewhat simpler alternative:

/usr/sbin/diskutil unmount force [volume]

The device will now have been quietly ejected regardless of whether it was in use or not. Yuck! Nausea aside we are now presented with a problem. Since the 'virus' lies in gestation, waiting for an unfortunate victim to return to their beloved Mac, much of its work takes place long after the USB stick has been removed. It still needs access to Unimotion, Box2D, a handful of sprites and of course its own code. All of which are long gone.

To get around this I borrowed from a neat trick of one of my colleagues. He'd discovered it while trying to speed up a freshly started MySQL on Linux. His idea was to force the database's indexes from a comparitively slow disk into memory immediatly rather than have MySQL do it piecemeal as and when the queries came in. This seemingly reduced the disks' thrashing and was very effective. And so to the magic in question:

  /bin/cat [file-destined-for-disk-cache] >/dev/null

Nifty eh? Upon execution the 'virus' iterates over the entire contents of its bundle on the USB device sending it to /dev/null prior to ejecting it. That includes the directories; despite the error you get when you do so. By doing this everything the 'virus' needs to run is placed in memory and the OS never needs to go back to the physical device for the files (well almost). Icky, yes. But ingenious, no?

I did wonder about using CSResourcesFileMapped in Info.plist for a while but not too hard and not for too long either. It's worth checking out if you don't know about it I guess.

Now, even as I write, I find myself wondering about the possibility of creating a RAM disk on the fly, and having the 'virus' run from there with only a bootstrapping program running directly from the USB device.

That seems eminently more sensible.

The Newton Virus appears on the MacLife.de cover disc
The Newton Virus appears on the MacLife.de cover disc

Window Capture

Now towards the final effect itself. Even if you don't initially realise that you can manipulate your desktop by tilting your laptop you'll be hard pushed to miss the mess at the bottom of your screen.

Of course it isn't actually your menu bar, icons and windows that are being flung around, rather a screenshot of each and every object - overlayed by way of OpenGL - in exactly the same place, initially at least.

Leopard provides an API that enables you to do this: you can capture the contents of any window. Icons, your menu bar and even the dock are just special types of window. So far so good I thought. That was until I realised Tiger doesn't have a public API for doing this.

Clearly you should not use private APIs, that goes without saying, they're private after all. You've no idea what might happen to them in the future or how they might be changed. But since I had no alternative...

Actually, heh, I have an inkling I could have used the Accessiblity API to capture the contents of the windows. Documentation for it, on the web at least, was difficult to find. Anyway in the end I had to resort to making undocumented calls via CGSInternal.h. Credit of which goes to Alacatia Labs.

The devil is in the detail of course. Working out what window belongs to which application, whether the window contains a transparent element and so on and so forth isn't easy.

Physics With Box2D

Having looked at a couple of 2D physics engine including Chipmunk I decided on Box2D for reasons that escape me as I write this. In part I suppose it was because I discovered quickly how easy it was to integrate C++ with Objective-C. Simply alter your source file extension from .m to .mm and you're free to mix Objective-C with C++ as you please. Well, nearly. Of course there are caveats but for the most part you don't have to think too hard about it.

Secondly and lest I forget, my predecessor Mauritius Seeger - who wrote the prototype of the Newton Virus in Processing - had used it too. And therefore it was patently up to the task.

Lastly the API is so simple it's easy to achieve a pleasing result with relatively little code. You define some shapes, attach them to a body, tell Box2D their starting positions, and watch as it tells you exactly where to paint those bodies around 30 times a second. Oh, I had to tell it in which direction gravity was acting too, but it was the least I could do given it'd relieved me of the task of doing any serious math. Besides I was saving myself for understanding projections and transformations in OpenGL, translating Box2D's output into something on screen.

And To Sum Up

So there you have it in all its glory. It's a little hard to believe that anyone will ever call on these so called techniques. But it was interesting to dig out my favourite snippets if only for the sake of posterity.

Having purchased my first Mac for the express purpose of building the 'virus' I can highly recommend it as a platform on which to develop. But you knew that already. If you're running a Linux desktop here's something that perhaps you don't know. Having run Fluxbox on Gentoo for as long as I can remember I was pained at the prospect of moving my everyday workings to OS X. In the event it was a breeze and I've never looked back.

Alright - so it's not open - and yes, that has tripped me up on more than one occassion. But fire up Terminal, install something like MacPorts and it's a home from home. What's more you've a beautiful desktop environment to develop end-user apps for.

Bonus Material: Having A ScreenSaver Loadable Bundle Link To A Dynamic Library

Should you ever write a screensaver, or any loadable bundle for that matter, that makes calls to an external library this is for you. It took me some time to work this out so it seems only fair I share it.

A Screenshot of The Newton Virus ScreenSaver In Action
The Newton Virus ScreenSaver In Action

The problem is that by default the bundle will look for its libraries in the @executable_path. That is to say the path of the current executable that is running which in my case is the OSX screensaver engine. Which is where my libraries aren't. Instead you need it to look in the @loader_path, the path of the bundle requesting the load (your screensaver).

Below you've a script that fixes this. It's part of my build process in Xcode and runs after the screensaver has been successfully compiled and the binary linked with its libraries. In this instance I'm dynamically linking to libUniMotion.

#!/bin/bash

/usr/bin/install_name_tool -change "@executable_path/libUniMotion.dylib"
"@loader_path/../Resources/libUniMotion.dylib"
"$TARGET_BUILD_DIR/$TARGET_NAME/Contents/MacOS/$PRODUCT_NAME"

You can list the shared libraries linked to by your binary using the command below. Run it before and after the above and you'll see the fruits of your labour.

/usr/bin/otool -L [your-binary]

And that's your lot!

Snow Leopard

With the release of Snow Leopard Apple in their wisdom are forcing all screensavers to 64-bit. And here — in part — is why:

The screen saver engine in Snow Leopard has gone from 32 to 64-bit. As screensavers' are .dylib (dynamic libraries) they need to be ported to 64-bit in order to run under the new engine. Hence a 64-bit version of the Newton Virus Screen Saver is in the pipeline.

Desktop Screenshots

Nor can we take screenshots of desktop icons as we did in Tiger and Leopard. That facility has gone. Boo. This is presumably as Finder now paints desktop icons using an entirely different method, each icon is no longer a window. A method the Dock has employed since Leopard. But fret not Newton Virus fans: a work-around is on its way.



Your Comments

Dead or not?

Is the project dead?


Is this project dead?

Hey guys, are you still working on this? I would love to get it and mess with some of my friends MacBooks, but I can't because I can't find it anywhere.


dead or not

this project doesn't work on snow leopard ,how can i do


Snow Leopard

Is this project dead or is a Snow Leopard version still on its way...? I wasn't aware that the Newton Virus didn't work for Snow Leopard until it was too late. Oh well, I guess that's what happens when one doesn't research something like program-compatibility first :P


So, I guess all hopes are

So, I guess all hopes are dead. No Newton Virus for Snow Leopard will ever be released. Too bad... :(


iVirus for iPhone, inspired by Newton Virus

Stephen,

I wanted to let you know I REALLY enjoyed the Newton Virus and watching it explode across the internet in the last year. I started programming late last year for the iphone on my macbook pro and the first application we created and released this last week is the "iVirus" !

Yes, iVirus was truly inspired by the Newton Virus and it as benign as yours. While the code seemed easy at first, getting it to work properly and passed by Apple (you are not allowed to simulate failure on their devices!) was another journey. We finally settled on a version that allows you to use a screenshot of your iPhone from the photo album. Once loaded with the custom screenshot (or one of our pre-installed silly themes), users can touch, fling and rotate the phone to watch their icons colide and react to gravity! (Yes, it does sound very familar).

Thanks again.
Steve
Co-founder Core Information Systems Inc.


re: Network

Dear Huevoos,

While it's conceivable that one could copy the USB version of the 'virus' to a networked drive you couldn't execute it remotely. Though I could contrive of a way of having the screensaver spread ;)

You must remember our intention is not for the Newton Virus to act like a true virus: we don't want it to spread!! We'd lose out on sales after all ;)


Network

I was about to copy the "virus" to my USB for a test run, when I saw My dad's MB listed on my network, so, I guess you know where this is going.

It would be really cool to infect via network, is this remotelly possible?


re: so...

Dear Anonymous,

First let me say thank you for your purchase. You're the second person to mention the superfluious 'T' and for that reason we've decided to remove it. All new purchases from this point forth will exclude the 'T'. If you drop me an email at stephen@everita.com I'll personally send you the new version.

With regards to having the 'virus' automatically launch: in reality it proved impossible, Mac's do still appear impregnable in this respect. However you can remove the USB stick the moment 'infection' has occured, leaving it to strike later. In this respect it's true to the video.

Finally, there is a new video on YouTube to accompany this release: http://www.youtube.com/watch?v=eh75j6OHhRc

I do hope you enjoy it.


so...

i guess you just didnt even try making it a plug and play app like the video shows? you have to run this app within the USB... plus, I noticed the splash screen is changeable, so is the .tif for the icon that drops on top of the icons... When I changed the .tifs around at one point it froze up (probably wrong size or something)...

the windows dont crash, they just seem to hide (like expose all windows), the icon really [expletive] me off... is there a way for me to get rid of the RED T icon that falls with the menu bar?

I tried just deleting it i think.. and it didnt work, i just want it gone!


Having MySQL performance issues?

We're experts at tuning MySQL and offer a MySQL performance consulting service.

LAMP stack not performing as you'd hoped?

Everita is experienced at getting the most out of your Linux, Apache, MySQL and Perl, PHP or Python setup. We're Drupal Experts.

Client Testimonials

Steve was knowledgeable and diligent in helping us identify application characteristics which were impacting MySQL's efficiency.

I would recommend him to anyone needing help optimising MySQL server and look forward to working with him in the future.

Richard Ainley
Performance Tester
WorkPlace Systems PLC

Next »

Subscribe

Enter your email address below to receive a very occasional message when something significant is published on the site.

You can unsubscribe at any time and we'll never share your address.

The Newton Virus: Infection In Steps

Images courtesy of Troika

Contact Us

E: info@everita.com
L: Reading, United Kingdom

Linux & Mac Specialists

Images courtesy of Rowan Mersh