Little Snitch is an awesome target to learn tons of stuff about Mac OS X. It’s a very worthy challenge and I’m loving it… I gave up on it for a while to read some stuff about IPC and mach messaging since I have strong clues it’s being used for Little Snitch components communication. Little Snitch uses threads and other stuff to make reversing much harder. One of my various reversing threads was to try to beat the 3 hour limit but I couldn’t find a good entry point to start tracing the network filter initialization. Tracing the mouse/keyboard events is a solution but it’s totally crazy because too much code must be traced…
One particular detail that puzzled me since the beginning was the fact that NIB resources were only possible to read into Interface Builder for Little Snitch UI Agent.app. The other Little Snitch programs gave an error while trying to load them. I had some interest in loading the NIB files because I read some tutorial that used Interface Builder Inspector tool to find the class associated to the button/form. Until today I never explored why I couldn’t load them. Today in one of those out of the box moments, I started exploring if for example the files were crypted. A crude comparison between a “good” NIB and a “bad” NIB hinted me of no such thing. What was different was the number of files each NIB had (I had already noted this in the past), the “good” had 3 files (classes.nib, info.nib, keyedobjects.nib) and the “bad” just 1 file (keyedobjects.nib). Both classes.nib and info.nib are text files.
Time to start messing around with it, so my first attempt was to create the classes.nib for the “bad” one. I just copied classes.nib from the “good” and tried to load the “bad” into Interface Builder… Voila, it worked! Now I can read the “bad” NIB file and I can see the following action for the start button, toggleNetworkFilterStatus. Searching Little Snitch Configuration disassembly and I can find that class 😄.
The previous piece of code calls networkFilterStatus function where we can see this following code:
00009df7 e849d30200 calll 0x00037145 -[(%esp,1) setValue:forKey:]
00009dfc 89f8 movl %edi,%eax
00009dfe 84c0 testb %al,%al
00009e00 743e je 0x00009e40 - show demo alert ? if yes, don't jump
00009e02 e835feffff calll 0x00009c3c
00009e07 85c0 testl %eax,%eax
00009e09 7535 jne 0x00009e40
00009e0b c744241000000000 movl $0x00000000,0x10(%esp,1)
00009e13 c744241400000000 movl $0x00000000,0x14(%esp,1)
00009e1b c744240c00000000 movl $0x00000000,0x0c(%esp,1)
00009e23 a1b4960300 movl 0x000396b4,%eax _runDemoAlert
00009e28 89442408 movl %eax,0x08(%esp,1)
00009e2c a134950300 movl 0x00039534,%eax performSelector:withObject:afterDelay:
Attaching GDB to Little Snitch Configuration process and changing that je into a jmp we get no demo alert! The description for that performSelector class is:
performSelector:withObject:afterDelay
Invokes a method of the receiver on the current thread using the default mode after a delay.
For now there’s no much interest in tracing this since bypassing this doesn’t influence network filter starting. What follows is to trace the 3 hour timer and the start message to the network driver. At least I think I have a better entry point, nevertheless I found how to fix those NIB files (undocumented feature? bug? Little Snitch author made it on purpose for sure).
Update:
Bob left a link for a blog entry reporting the same problem. Available at http://yamacdev.blogspot.com/2007/01/cant-touch-nibs.html
Someone found it first! 😄