Wednesday, September 30, 2009

Fixing Canon Selphy CP790 printer drivers on Snow Leopard

I'm a happy Snow Leopard user, and as an amateur photographer I was interested in doing some home printing. Canon Selphy printers are cheap with extremely good print quality in a 4x6 format, but in usual giant corporate style, Canon hasn't updated their printer drivers for Snow Leopard. I suspected their generic "The version of present Macintosh cannot install a printer driver" error was complete crap, so I did some poking around in the installer binary. A little quality time with GDB and 0xED later, I had found the function that checks the OS X version. Thanks to their particular library code style, it takes only a single byte to change the function from "check the version and bomb if we don't like it", to "return immediately as if everything is fine".

I transformed the edit down to a small Python script that anyone can run. Just copy this code into a text file, I called mine "fixSelphy.py". Copy the installer.app for your Selphy out of the dmg, and run the script from terminal with "python script.py installer.app" (with whatever you named your script and whatever your installer is called). There are some basic protections to make sure you have a version of installer that the script knows how to edit, but it should work on any of the Selphy CP7xx series installers, since they all use the same core library for version checking. Once the script has run, the installer will work without complaining, and you'll have a working printer on Snow Leopard.

For those intrepid folks who just want to make the edit themselves, fire up a hex editor against Contents/PlugIns/SELPHY_ExtCode.bundle/Contents/MacOS/SELPHY_ExtCode, and at offset 0x7116, change the byte 0x55 to 0xC3 and save.

Here's the script:
#!/usr/bin/python
#
# Hack Selphy CP7xx installers to run on any OS X version (inc. Snow Leopard)
#
import sys
import os.path

if len(sys.argv) < 2:
print('Usage: %s path/to/CPXXX Installer.app' % sys.executable)
sys.exit(0)

path = os.path.expanduser(os.path.expandvars(os.path.join(sys.argv[1],
'Contents/PlugIns/SELPHY_ExtCode.bundle/Contents/MacOS/SELPHY_ExtCode')))
if not os.path.exists(path):
print("Can't find the right file in the installer. Sorry.")
sys.exit(0)
f = open(path,'r+b')
f.seek(0x7116)
if [ord(x) for x in f.read(8)] != [85, 137, 229, 87, 86, 190, 16, 39]:
print("File doesn't look right, I'm bailing. Sorry.")
sys.exit(0)
f.seek(0x7116)
f.write(chr(0xc3))
f.flush()
f.close()
print('Edit completed successfully. Happy installing.')