Rixstep
 About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Home » Learning Curve

Uncle John's Rules for Running Third Party Software

An heuristic approach. Revised and augmented from the original.


Get It

Try It

Never run unknown and untrusted software, goes the Apple mantra. Yet that seems to be an impossible proposition. For how can you ever get to know and trust something if you never run it?

But the proposition stands as good advice. Taking a look at what you get both before and after running unknown and untrusted software can be the only way to avoid disaster.

[Note: the following applies to software for Apple computer systems. The legions at the App Store are supposed to do most of this for the iPhone and the iPad. Those are closed systems and you can't really do much with what you get anyway - unless of course your device is jailbroken.]

1. Avoid impulse downloads. It's too easy to screw up a perfectly good system by downloading and running things willy-nilly. Not everyone writes good software. In fact, very few write really good software. The archives of the Very Ugly are full of examples. And don't trust your friends and their opinions and advice either. And absolutely don't trust IT journalists and their software reviews - they know less about software than almost everybody and mostly only read the back of the box. They're the last people to listen to. You have to learn to assess software on your own.

Don't get into the habit of downloading and running on impulse. This doesn't work when shopping in the real world - for groceries, for a car, you name it - and it doesn't work here either. Make up your mind about what you want before you go shopping for it.

2. Comparison shopping. See what's available for what you need. Compare the alternatives. The smaller the package, the better the quality. Apps built with strange tools such as REAL Studio, Flash, and Qt should be avoided if possible. A dazzling appearance can be an encouraging sign but form never reigns over function - it's the second thing to look for, never the first.

Today you want Cocoa bundles and nothing else. You don't want yesterday's Carbon either - or even worse as Adobe did for years: legacy PEF binaries inside Carbon wrappers. OS X and the Cocoa frameworks have been out for about fifteen years; the better developers have been familiar with the platform years more than that; if someone is still not with the programme, then avoid them.

$ cd '/Library/Application Support/Macromedia/Shockwave 10/Shockwave.bundle/Contents/MacOS'
$ file *
DPLib:                header for PowerPC PEF executable
IMLLib:               header for PowerPC PEF executable
MacromediaRuntimeLib: header for PowerPC PEF executable
PluginLib:            header for PowerPC PEF executable
ProjLib:              header for PowerPC PEF executable
SwMenuLib:            header for PowerPC PEF executable
SwSupportLib:         header for PowerPC PEF executable

Apple's recent insistence on allowing only native code on their mobile devices isn't solely about raising barriers to entry - it's also about being able to better guarantee software quality.

3. Peek inside. This takes the most time and truthfully it's a black art. OS X software comes in bundles - hierarchies of files and directories with something with an 'app' extension atop it all. That's good when you want to inspect things before running them. But it also gives vendors more opportunities to screw up. So make sure you take a peek.

What do you look for? You'll get better at this as time goes on. And the more you learn, the more you pick up, the better you'll get at sidestepping booby traps others fall too easily into. [See below for a short list.]

If your software comes as a DMG then you can mount it and inspect it from there - or copy it to your hard drive instead. This can be useful when the software is hiding things inside zip archives and you want to open them to see what's inside - you can't do this directly on a read-only DMG mount.

If your software comes as a package (extension PKG) or as part of a metapackage (extension MPKG) you might want the pax front end Pacifist to peek at what's inside - or you can spare yourself that pleasure and unzip the 'Archive' yourself. But you need to peek inside.

4. Run only native code. Make sure your app is written for your platform. Apple computers have two possible CPU architectures: PowerPC and Intel. The more recent editions run Intel.

Older software for the platform was made for the PowerPC processor; but if you're running an Intel Apple box, then make sure your software has binaries that directly support Intel. You don't want to run things through Apple's Rosetta ABI if possible.

How do you do check for CPU support? You drop to a command line inside your application bundle and drill down to the Contents/MacOS directory and run the following command.

$ file *

The output from this program will tell you right away if you have what you need. If you have an Intel box but all you see is 'PPC' or 'ppc7400' then you don't have something you'll like. You need to see 'i386' or 'x86_64'. And if you're running OS X 10.6, then you prefer using an 'x86_64' architecture.

Running file on Apple's Xcode binary yields the following.

$ file *
Xcode: Mach-O universal binary with 3 architectures
Xcode (for architecture x86_64): Mach-O 64-bit executable x86_64
Xcode (for architecture i386): Mach-O executable i386
Xcode (for architecture ppc7400): Mach-O executable ppc

And make sure you run file on all binaries in your application package. How do you find out if there are other binaries? Either by looking around at file permissions or with the following command from the same location as last time.

$ otool -L *

This will list all the dependencies of the binaries. If any of them begin with something like @executablepath or @loaderpath then you have dependencies in the application package and you should check them out too.

Running otool on Apple's Xcode binary yields the following.

Xcode:
    @rpath/DevToolsFoundation.framework/Versions/A/DevToolsFoundation (compatibility version 1.0.0, current version 1612.0.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 550.0.0)
    /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 751.0.0)
    /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 152.0.0)
    /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 1038.0.0)
    @rpath/JavaKit.framework/Versions/A/JavaKit (compatibility version 1.0.0, current version 1591.0.0)
    @rpath/DevToolsCore.framework/Versions/A/DevToolsCore (compatibility version 1.0.0, current version 1613.0.0)
    @rpath/DevToolsSupport.framework/Versions/A/DevToolsSupport (compatibility version 1.0.0, current version 1591.0.0)
    @rpath/DevToolsRemoteClient.framework/Versions/A/DevToolsRemoteClient (compatibility version 1.0.0, current version 1613.0.0)
    @rpath/DevToolsInterface.framework/Versions/A/DevToolsInterface (compatibility version 1.0.0, current version 1613.0.0)
    @rpath/DevToolsCParsing.framework/Versions/A/DevToolsCParsing (compatibility version 1.0.0, current version 1591.0.0)
    /usr/lib/libauto.dylib (compatibility version 1.0.0, current version 1.0.0)
    @rpath/XcodeEdit.framework/Versions/A/XcodeEdit (compatibility version 1.0.0, current version 1611.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 123.0.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)

Today it's common to bundle software with both the Growl and Sparkle frameworks. These frameworks can be useful but one copy of each is enough for an entire file system. Yet many third party vendors package them in their bundles with hard-coded paths. You can liberate these frameworks and rescue megabloats of disk space but that's beyond the scope of this article.

A good vendor will include a facility for moving the frameworks to a common location and not burden you with unnecessary clutter. Unsanity do it with their APE. But truth be told: there aren't many vendors in that class.

Do check the embedded frameworks for cruft you don't want. They can come with hundreds of language files you never use. Keep only the ones you know you'll use. They're normally stored in subdirectories to a Resources directory. The system works as follows.

  1. Paths to resources in language files are specified only as far as the Resources directory. Anything else is up to the system and your particular configuration.
  2. If the system finds what it needs already in Resources then it looks no further - it won't drill down in the language subdirectories (with extension lproj).
  3. You can for example - if you're going to use English - take all the files in English.lproj/en.lproj and move them up to the parent Resources directory and then remove the rest.
    [Note: this isn't something you want to try at home if you're not familiar with Cocoa localisations and comfortable with the whole thing.]

5. See what's inside the binaries. You might find evidence of someone phoning home - a URL beginning with http:// or ftp:// might be suspect if there's no reason you can think for the application to have this (such as a menu item to scoot you to the vendor's site).

Look inside with a dedicated utility like Xstrings or 'roll your own' with the command line strings.

$ strings <PATH TO BINARY> >~/Documents/strings.txt

You get the output in ~/Documents/strings.txt and you can then study it for 'funny things'. The software reviews at this site are ripe with examples of how this is done and how it's of benefit.

Shareware sometimes tries to hide things in fun locations to stop you from exceeding the trial period. Playing according to the rules is important - but that applies to the vendors too. Finding the following in an application binary should immediately raise an eyebrow.

Library/Preferences/com.apple.dock.plist
Library/Preferences/com.apple.finder.plist

There is no way but no way a third party application has any business going into the dock's or Finder's preferences. What would probably be happening is the third party vendor will hide something about your trial period (and its expiration date) at a key in those preferences files where Apple's software will never notice it or bother with it. This is invasive behaviour on the part of your third party vendor and you really don't want to invite invasive software (or invasive vendors) onto your system.

Watch out as well for mention of Unsanity and eSellerate products such as the APE and EWS frameworks. Those things spell trouble. Many third party tools use them but rarely tell you about it. The eSellerate EWS framework often comes zipped up so you have to first unzip it to see what's inside - something your unknown and untrusted software was going to do at runtime. You'll commonly find this in the Resources subdirectory inside your application bundle.

Look for strings beginning with '/Users/' and ending with '.c' or '.m' or even worse: '.o'. These are only found in binaries not built for installing. They might be debug builds or they might be builds that are not stripped properly. Apple have made it very clear how 'install' builds are to be made; if your vendors refuse to take this advice, then maybe you should look elsewhere for a better product.

Under no circumstance should you accept a debug build for a release product. Vendors are supposed to thoroughly test their software before releasing it and not use you as their guinea pig.

6. Run the application. Found nothing to lose sleep over? OK - but take steps to track it as you do.

You must absolutely and without exception track (or otherwise monitor) what the software does when it's run. All the preparations and safeguards in the world won't guarantee something bad can't happen - and you need to know what the software does if you're ever going to trust it.

You have two options here. You can either use a dedicated utility like Tracker (really one of a kind) or you can 'roll your own' again using the command line find. If you choose the latter, make sure you study find syntax thoroughly so you get it right - you don't get a second chance as easily. At any rate: run the application (under supervision) and make sure to try everything in the application, including playing around with its preferences. Provoke all possible behaviour on this first run.

Check the menu - was it just thrown together or was time taken to tweak it properly? Try the application help item. If all you get is 'help is not available for this application' then you know your vendor friends are lame. Either they add a help system to the app or they break into a sweat removing the item. Function, form, and packaging (and in that order) mean everything - if your software package is itself sloppy then it's likely the engineering is sloppy as well.

7. Close the application and check what's happened with your system. If you're running Tracker then you just click a toolbar button and wait; if you 'rolled your own' then you drop to a command line and use find to start looking for files and directories that have been in some way modified. Take a good look at what's happened and take your time.

Did the app leave a lot of junk around? Some apps leave (literally) tens of megabytes of useless cruft; do you want to be cleaning up after the sorry thing time and again? A good (benign) program will at most leave a single preferences file - and then only if you've actually reconfigured the app. A good app won't leave piles of festering turds in the 'Application Support' directories (there are two) for doing nothing at all.

And if after all this the application actually does what you want and looks good doing it - then you've got a winner.

Postscript: Packaging Classics

Ten things that should set off sirens. Add your own.

  • Apps with uncompressed TIFFs.
  • Apps that ship with header files.
  • Apps that are easy to throw for a loop.
  • App binaries with source code paths inside.
  • Apps that crash before you do anything at all.
  • Apps that link with AppleScript, REALbasic, APE.
  • Cruft left on disk just for opening and closing an app.
  • Apps (or installers) that want your password but won't explain why.
  • Graphically nontrivial apps that don't have NIBs. (Spotify the brilliant exception.)
  • Apps with files like classes.nib, data.dependency, designable.nib, and info.nib.

See Also
Radsoft: Uncle John's Rules for Downloading and Running Junkware

About | ACP | Buy | Industry Watch | Learning Curve | News | Products | Search | Substack
Copyright © Rixstep. All rights reserved.