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 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:

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).

Bob left a link for a blog entry reporting the same problem. Available at

Someone found it first! 😄