12 Feb 2006

circumventing ichat's g3 restriction (part 1)

[UPDATE (13 Feb 06): turns out that canSupportH264Decode is not really what I want because you cannot use H264 with any of the G3 processors. That turned out to be a red herring. Instead, what we really wanted was the ProcessorSpeedMHz which we can override using mach_inject. More on that in a following blog post.]

so the newest ichat will not enable video chat for G3's that are slower than 600MHz. the reason is that i suppose the H264 implementation requires quite a bit more oomph than these G3s can provide. however, the problem is that it is a blanket ban that assumes you are using it for two way chat. if you are only doing one way video chat, you should be allowed to use it for that. I mean, theoretically speaking that should only require a 300MHz G3! (ok, i know my numbers are flawed, but my argument still stands.)

Ichatg3

what got me thinking is that the software from iglasses and ichatusbcam is able to circumvent this restriction. however, i don't really need iglasses or ichatusbcam, i just want to switch off the stupid restriction. since they can do it, it must be quite easy to do. i don't really need to fork out some money just to turn it off, i'm sure its only a couple of lines of code once i found the right place.

in fact, after some educated guesses, i think i have the solution. but first i'll talk about finding where this restriction is set so that maybe other people who might like to think about trying the same thing won't fall into the same holes as i did.

Step 1. Collect the tools and links.



If you are just starting out, read the wonderful CocoaReverseEngineering guide by Mike Solomon, the developer behind PithHelmet.

Basically, most of the essential tools are already on your mac, otool, nm and gdb. The only other essential tool you need is class-dump which is able to scour for symbols in a Mach-O binary and dump a pseudo header for you. That way you can find out the Objective-C selectors that an object responds to, and also their names. One note of caution, you will need to get class-dump 3.1 which handles universal binaries if you are doing this on Mac OS X 10.4.

Step 2. Know your enemy



My enemy is iChat and it is rather simple. Here are the steps I took, some leading to dead ends, others leading to fruitful places.

Firstly, when you plug an iSight into a G3, you don't get your usual video preview, instead you get a message saying that "Your computer does not support video conferencing." So it must of done the check somewhere in the program to determine that. Now, obviously it needs to find the clock speed and the processor type. Under Mac OS 9/10, there is only one good way to do it, that is using Gestalt. You can find out all sorts of information all the way from whether your processor is a M68K to a G5 (and presumably Intel.)

Knowing that Gestalt will be called at some point, now I just need to make sure that it really is what I'm looking for. I use nm to confirm this for me:

nm /Applications/iChat.app/Contents/MacOS/iChat | grep Gestalt
U _Gestalt


So it is there, the U there says that it is undefined. That means it get resolved at runtime, so its somewhere in some shared library.

Next step I took was the run class-dump on iChat and look through the class definitions to see if there was anything matching "Clock", "Video" or "Processor" to see if there was a specific function that looked at the clock speed or processor. I couldn't find any, weird.

Not to worry, my next plan of attack is to run iChat through GDB. It is kinda scary at first, but once you know a couple of the commands, its pretty easy. What we want to do is to find out where Gestalt is being called and look at the stack trace that leads to that call. Because Gestalt is used to query many aspects of the system, there maybe alot of calls to this function, so smart and filter out what is unneeded and take note of what is relevant.

gdb /Application/iChat.app/Contents/MacOS/iChat
(gdb) break Gestalt
Function "Gestalt" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (Gestalt) pending.
(gdb) run


Now it will run, and every time Gestalt is called, it will jump you to a prompt. There are many things you can do, but the simplest thing to do is to print out the back trace using the command backtrace or its shorthand
bt. When you've had enough with the back trace, use the command continue or the shorthand c and it will continue running the program from that point. I'll just show you the interesting bits that you'll find when you run it in that way:

(gdb) r
Starting program: /Applications/iChat.app/Contents/MacOS/iChat
Reading symbols for shared libraries ....
...
Breakpoint 1, 0x90b1a470 in Gestalt ()
(gdb) bt
#0 0x90b1a470 in Gestalt ()
#1 0x9814155c in ProcessorSpeedMHz ()
#2 0x98141490 in getHardwareInfo ()
#3 0x98141368 in +[VCRules canSupportH264Decode] ()
#4 0x98141228 in +[VCRules canSupportH264Encode] ()
#5 0x98141124 in +[VCRules bestParametersForFramerate:imageSize:forTransportType:] ()
#6 0x98140e70 in -[VideoConferenceController resetVars] ()
#7 0x9813f990 in -[VideoConferenceController initWithRectTexture:] ()
#8 0x9813f71c in -[VideoConferenceMultiController initWithRectTexture:] ()
...
(gdb)c
Breakpoint 1, 0x90b1a470 in Gestalt ()
(gdb) bt
#0 0x90b1a470 in Gestalt ()
#1 0x9814181c in MachineType ()
#2 0x98141584 in hasG5 ()
#3 0x9814149c in getHardwareInfo ()
#4 0x98141368 in +[VCRules canSupportH264Decode] ()
#5 0x98141228 in +[VCRules canSupportH264Encode] ()
#6 0x98141124 in +[VCRules bestParametersForFramerate:imageSize:forTransportType:] ()
#7 0x98140e70 in -[VideoConferenceController resetVars] ()
#8 0x9813f990 in -[VideoConferenceController initWithRectTexture:] ()
#9 0x9813f71c in -[VideoConferenceMultiController initWithRectTexture:] ()


[UPDATE (13 Feb 06):Please note that the below is one of the dead ends. canSupportH264Encode is not what we need to enable iChat for G3s under 600MHz, but is probably also an interesting call by itself.]

There we have something interesting, it seems like the critical thing that determines whether you can use video conference is that [VCRules canSupportH264Encode]. But what is this VideoConferenceController?
The obvious place is in iChat.app, but its no where to be found in the classes. So it must of been loaded in somewhere else through a framework. Here we break out otool and check out what libraries it uses:

otool -L /Applications/iChat.app/Contents/MacOS/iChat | grep Video
/System/Library/PrivateFrameworks/VideoConference.framework/Versions/A/VideoConference (compatibility version 2.0.0, current version 2.0.0)


Here we see there is a PrivateFramework that handles all the VideoConference joy. Running class-dump on this framework's library will reveal the VCRules class. And that is what we need to modify.

lass-dump /System/Library/PrivateFrameworks/VideoConference.framework/VideoConference | grep VCRules -A 20
@interface VCRules : NSObject
{
}

+ (unsigned int)QuickTimeBandwidth;
+ (id)rulesForVideoCodec:(int)fp8 withCurrentUserCount:(int)fp12 withBitrateLimit:(int)fp16;
+ (id)rulesForH263WithCurrentUserCount:(int)fp8 withBitrateLimit:(int)fp12;
+ (id)rulesForH264WithCurrentUserCount:(int)fp8 withBitrateLimit:(int)fp12;
+ (void)loadOtherRules;
+ (void)parametersForRules:(id)fp8 pFramerate:(int *)fp12 pWidth:(int *)fp16 pHeight:(int *)fp20;
+ (BOOL)canSupportH264Encode;
+ (BOOL)canSupportH264Decode;
+ (void)bestParametersForFramerate:(int *)fp8 imageSize:(int *)fp12 forTransportType:(int)fp16;
+ (BOOL)isHardwareSuitableForFilters;
+ (void)updateImageSize:(int *)fp8 forBandwidth:(int)fp12;
+ (unsigned int)minAudioBandwidth;
+ (unsigned int)minVideoBandwidth;
+ (unsigned short)cutoff15FPS;
+ (unsigned int)magicRTCBandwidth;
+ (unsigned int)minCPUSpeedForH264;
+ (struct _NSSize)applyImageSizeDowngradeRuleForPayload:(int)fp8 currentSize:(struct _NSSize)fp12 bitrate:(int)fp20 pFramerate:(int *)fp24 inMultiway:(BOOL)fp28;


There are the nice bits and pieces we can override. All sorts of limitations we can get rid of. They're probably there for a good reason, but we can act like children and think that we know better than Apple Engineers! Emm ..

Step 2.5 Alert Alert! Dead end.



[UPDATE (13 Feb 06):This section added because more testing revealed that canSupportH264Encode was not the function that detemines whether a G3 under 600MHz can run video chat.]

Further testing actually indicates that canSupportH264Encode is a red herring because G3s do not use H264, but instead H263. So enabling support for that by overriding/replacing those methods won't actually help our cause. Instead, we should look at the interesting function that it called called ProcessorSpeedMHz. If you debug a little more, you'll find that iChat will also call a function called HasAltivec. Interestingly, Apple's sample code online has a sample implementation of HasAltivec which is solely to detect whether the processor is a G4.

If the processor does not have Altivec it must be a G3 or less. In that case, iChat uses are different mechanism to determine whether video chat should be enabled, which is just by comparing ProcessorSpeedMHz to the reference.

As a side note, checking minCPUSpeedForH264 will show you that you need a 850MHz G4 or above to use H264. In fact, a bit more hunting around and you can actually unlock the restriction that only allows certain Dual G4s and G5s to host multi-way voice and video conference. But that'll be for another day.

Step 3. Modifying iChat's Behaviour at Runtime



[UPDATE (13 Feb 06):Added pointer to the "real" method we would like to pursue, which is mach_override rather than MethodSwizzling.]

I'll go into that in the next post, but basically it involves SIMBL, MethodSwizzling (with a simple twist since these are all Objective C class selectors rather than instance selectors) and/or mach_override (kind of like LD_PRELOAD for Linux). Stay tuned!

... Read More


11 Feb 2006

multi point input research

this video has been making the rounds on the internet, and is not some cheesy mashed up movie trailer or stupid funny video. it's a demonstration of what you can do with a huge touchscreen and multiple point touch screens. these are touchscreens that can detect multple "fingers" on the screen. they call the system frustrated total internal reflection.

they have a really cool movie you can download on their site. it's one of these demos that are done very well, by people who are graphical ninjas! my favourites is the onscreen dj mix deck, map viewer, photo organiser and the onscreen keyboard. the ui looks so intuitive that once someone demos it, you understand immediately.

Multitouch

i wonder if you can do something similar with the powerbook touchpad since it can recognise two fingers. or maybe it does a weird driver hack to sense it. hrmm ... someone is already thinking about it -- free focused scroll.

... Read More


11 Feb 2006

happy birthday chris

no not that chris, the other chris. yes you, that one there.

so i called up chris in australia to wish him happy birthday. turns out that:

(a) i called him too late that it was already past his birthday -- hey its still the right day in UK :P
(b) i woke him up! damn it, what are you doing sleeping at 12:30am? you're getting old, dude.

... Read More


10 Feb 2006

british accent is the sexiest accent!

that's another thing you brits have won! you guys are on a roll, first the ashes cricket, then the rugby and now this, the sexiest accent in japan!

if you haven't read "an englishman in osaka", you must check it out. it is the funniest blog around about thing japanese. this is possibly the only thing me and anil would agree on! (say what about python?)

... Read More


10 Feb 2006

xgl: linux desktop is only 2 years behind mac

looks like everyone is getting in on the game of emulating the mac desktop features. look at the blow by blow videos from the novell on xgl.

1. real transparency in x -- err, ever since mac os x 10.0? see apple terminal.
2. zoom minimisation -- err, again, i think mac os x 10.0 has this
3. desktop reorganisation -- much more recent, 10.3 expose.
4. cube spinning -- fast user switching 10.3.

 Linux Xglrelease Img Movie-Cube

but its nice that linux (or X in general) is catching up. i particularly like the cube spinning for dragging windows between desktops. i still use desktop manager on the mac for multiple desktops, which is a hack to say the least. wonder why apple won't include this feature into their gui.

... Read More


10 Feb 2006

err, i'm a mac blogger ..

yeah, 6th post today, maybe i'll get up to 12 .. you can all cheer for me ..

i was just visiting the lovely cocoadevcentral (which is great because it presents mac development tutorials with a really slick web design -- very mac like). and apparently i'm on a list of mac bloggers on the side. huh? .. i still haven't reached my 1:10 released project to started project ratio yet! take a look at my cocoa projects folder:

Cocoadev-1

in that list, only Album Art Widget, Album Art Inspector, ATKeychainPlugin (that reminds me, its broken) and EyeTunes (needs more work as i'll explain later) are released. although, PosterTunes is getting along nicely as a meaningless playground to teach myself Core Image and PDFs, Violator which is actually working but can't really be released since it depends on SpotMeta and some other playful toys.

anyway, getting back to the point, surely there are some other people who are more worthy of being listed in one of the premier cocoa dev sites around ;)

... Read More


10 Feb 2006

how contributing to the (apple) mothership pays off

hey, as you can see, i'm in a bored blog-a-thon here .. so i'll continue ..

the safari team (aka. webkit) team has just announced that they're going to give the top 12 contributors (why 12? because its divisible by 2, 3, 4 and 6) to their open source webkit project a free macbook pro and inviting them to WWDC 2006 (which usually costs around US$600+).

damn, i wish i liked C++.

... Read More


10 Feb 2006

wtf, red cross now becomes red crystal?

i just read on boingboing about canadian red cross deciding to spend it's hard earned donations to go after GAME COMPANIES who use the red cross on their medic packs (yes, i'm looking at you team fortress!) how ridiculous is that? will you donate to the red cross again if they continue to do this crap?

what is even more surprising is that apparently the red cross and the red crescent (the muslim equiv of red cross, i presume) have now launched a new logo called the red crystal so that some israeli aid organisation won't get offended by not having a star on their humanitarian organisation.

Redcrystal

i didn't even know that the cross was in red cross was religious, because it sure doesn't look like the christian cross, more like switzerland, and i suppose is chosen because the geneva convention was signed there. how many decades will it take for people to recognise this logo? geez! great work guys!

... Read More


10 Feb 2006

i got world cup 2006 tickets!

yeah, i got allocated tickets to one game at the world cup in germany! woohoo! i applied for tickets for the world cup in japan back in 2002 and didn't get any tickets at all. but this time, i aimed slightly lower and only applied for the group stage games. but since i missed out on the olympics by being in princeton in 2004, i thought i had to go to one big sporting event while i was in europe.

so i applied online for three games, all of them were in the group which australia, japan and brazil were in. oh yeah, and i think there's croatia or something. so i applied for australia v brazil, japan v brazil and australia v japan. turns out i didn't get all three, but only got the australia v brazil game. it is a little disappointing that i didn't get the other two games, but hey, at least i get to see brazil play!

the best thing though, is that the game is going to be played in munich, which has this awesome allianz stadium. here are some pics of what it looks like:

Allianz

so i'll be in germany for a week of so in june. that'll be pretty awesome and i'm looking forward to it.

... Read More


10 Feb 2006

crazy fun flickr game

there's this really fun flickr game that's well implemented using ajax and what not, but is extremely addictive. its called fastr.

basically, the idea is that each round lasts for 5 minutes. and each game inside that round, pictures will be shown of a particular keyword. you have to guess the keyword as fast as you can, and for every extra picture that comes up, you earn one less point if you guess it.

Fastr

on the side, there's an accumulating score of people who are playing, and its really fun to play against other people rather than the other flickr games.

... Read More