A semi-automated way to find sysent

The original method to hijack sysent table was described by Landon Fuller and then Braeden Thomas updated it to Snow Leopard due to new location and lack of nsysent symbol. Charlie Miller and Dino Dai Zovi at The Mac Hacker’s Handbook, have some code to try to automate this search for sysent. I never tried it before and today I decided to hack around it. It suffers from the problem of no nsysent symbol (is there a way to fix it? I remember I tried when Snow Leopard was out but couldn’t work around it), so we need to hardcore its address. Fortunately this address has been in a rather stable range, so we can use one value and work on that range. The same applies to the offset from nsysent symbol to sysent table.

The basic code (slightly modified from the original since it was for Leopard, typos included) is like this:

#define is_small(x)		(*(x)>=0 && *(x)<100)
#define is_addy(x)		(*(x)>10000)
#define is_optional_addy(x)	(*(x)==0 || *(x)>10000)
#define is_stuct_sysent(x)	( is_small(x) && is_addy((x)+1) && is_optional_addy((x)+2) && is_optional_addy((x)+3) && is_small((x)+4) && is_small((x)+5) )
#define is_sysent(x)		(is_stuct_sysent((x)) && is_stuct_sysent((x+6)) && is_stuct_sysent((x+12)) && is_stuct_sysent((x+18)) && is_stuct_sysent((x+24)) )
 
static struct sysent *find_sysent ()
{
(...)
	unsigned int *looker = (unsigned int *) ( 0x00831790 - 0x3000 );
 
	while(!is_sysent(looker))
	{
		looker++;
	}
	printf("[onyx-the-black-cat] Found sysent table at %x\n", looker);
(...)

You can adapt the find_sysent to include this change and use the found value to double check if it’s really sysent and hijack it. You might need to adjust the value that is substracted, but it successfully identified sysent for 10.6.3 and 10.6.5. There is room for improvement in those macros, since they generate some false positives in other ranges. One idea is to add the remaining fields of sysent structure, which should reduce the possible amount of false positives.

That’s it for now. I’ve been working on improving some tools but they will not be released. The fuss about Protools at MSJ remembered me that the majority of people just want to pirate software and free stuff, knowledge is a secondary or not even important. The economic crisis has shown us the results of greed, and greed is something that I really hate! These days I also had a user asking for help but he was annoyed by my lack of cooperation – I wasn’t pointing him to basic stuff. Well, that basic stuff is available at my blog and over the web. I really hate people who don’t make an effort to learn, research and study. Might be a personal flaw but it’s something that I strongly believe: No effort, No gain! He was also pissed off by losing 3 days around a simple crackme without advancing. Who said cracking is easy and rewarding all the time? 🙂

To finish, just a little publicity to a magnificient App that I started using and love: Alfred. Buy it if you really use the advanced features (of course you can crack it as personal curiosity but pay for it if you really use those features, the rest of the app is free and it rocks!).

Have fun,
fG!

P.S.: The problem with nsysent seems to be related to this.

10 thoughts on “A semi-automated way to find sysent

  1. Hopefully the tools you’re working on but not releasing don’t include gdbinit. It would be too bad to see updates stopped for such a useful tool. Out of curiosity could you mention what the tools you’re working on do or are used for?

    1. I’m working on improving debugging tools 🙂 Gdbinit needs some small fixes for better 64bits support, but currently it accomplishes all my needs. If anyone out there has added interesting things or has ideas to add, feel free to send patches or describe them.

      1. Feel free to add the support I’ve found for displaying C++ class names from pointers. Not quite sure how to do a code tag here (or even if it’s supported) but this can be added to the gdbinit file:

        define cppclassname
        if $argc == 0
        help cppclassname
        end
        if $argc == 1
        x/s *(int *)((*(int *)((*(int *)$arg0)-4))+4)
        end
        if $argc > 1
        help cppclassname
        end
        end
        document cppclassname
        Get’s the C++ class name associated with a pointer object.
        Usage: cppclassname
        end

        The name it spits out can be filtered with the command-line tool c++filt (by prepending “__Z” in front) to obtain the unmangled name. I’ve found it useful in several cases 😉

        You may have already come across this if you’ve browsed the Protools thread.

  2. get Kernel Version

    int mib[2];
    size_t len;
    char *kernelVersion;

    // Get the kernel’s version as a string called “kernelVersion”:
    mib[0] = CTL_KERN;
    mib[1] = KERN_OSRELEASE;
    sysctl(mib, 2, NULL, &len, NULL, 0);
    kernelVersion = malloc(len * sizeof(char));
    sysctl(mib, 2, kernelVersion, &len, NULL, 0);

    // 10.4 kernel for my 10.6.4 MacOS
    //may be this good for make fully automate

Leave a Reply

Your email address will not be published. Required fields are marked *