Dump a class gMetaClass

Questions and Answers about all things *OS (macOS, iOS, tvOS, watchOS)

Dump a class gMetaClass

Postby kmfpl » Mon Dec 21, 2015 5:51 pm

I was reading this paper from BHUSA 2015: https://www.blackhat.com/docs/us-15/materials/us-15-Lei-Optimized-Fuzzing-IOKit-In-iOS-wp.pdf.
The author explains some pretty cool techniques to fuzz IOKit on iOS, so I thought to give it a shot and replicate them on OSX.

After writing some quick and dirty functions to runtime-read kernel memory (I did this by disabling SIP and getting kernel's port via processor_set_tasks workaround. Then just mach_vm_read_overwrite on addr + kslide), I did some tests to confirm everything was working fine. Reading from a kext base address (from kextstat) + kslide yielded 0xfeedfacf, so I am quite sure everything works.

I noticed that the paper's author uses a particular formula to calculate gMetaClass address for a specified class, the formula is tuned for ARM 32bit. I wasn't able to replicate this formula in OSX x86_64, so tried to come up with another method.

I am actually interested in IOHIDUserClient gMetaClass. A quick Hopper disassembly revealed that IOHIDUserClient (as well as other classes) have a particular method, ::getMetaClass(). So I found IOHIDUserClient::getMetaClass() method with Hopper, which disassembles to the following:

Code: Select all
__ZNK15IOHIDUserClient12getMetaClassEv:        // IOHIDUserClient::getMetaClass() const
0000000000038708         push       rbp
0000000000038709         mov        rbp, rsp
000000000003870c         lea        rax, qword [ds:__ZN15IOHIDUserClient10gMetaClassE] // offset is 0x561c0
0000000000038713         pop        rbp
0000000000038714         ret 


I am interested in getting the __ZN15IOHIDUserClient10gMetaClassE. The offset is actually 0x561c0, so I thought that doing:

Code: Select all
gMetaClass_addr = slide_address(kext_base_addr + 0x561c0)


Would've worked. The former actually resolves to a valid kernel address, however I can't seem to find the MetaClass structure in the dumped data, meaning my idea was very probably wrong.

tl;dr
Basically I have to find this gMetaClass variable for IOHIDUserClient class. The method I tried didn't work.

I hope someone knows how to do this, or at least can provide me with some other good methods/ideas for getting runtime class informations. Thanks in advance!
kmfpl
 
Posts: 2
Joined: Mon Dec 21, 2015 5:07 pm

Re: Dump a class gMetaClass

Postby morpheus » Wed Dec 23, 2015 6:14 pm

Seems like you're doing everything right; I'd have to look at the code or the dump for an accurate answer.
morpheus
Site Admin
 
Posts: 532
Joined: Thu Apr 11, 2013 6:24 pm

Re: Dump a class gMetaClass

Postby kmfpl » Wed Dec 23, 2015 7:32 pm

Hey! Thanks for the reply. I realized that I was indeed doing right, but it seems that the gMetaClass object structure doesn't follow the same structure as the iOS gMetaClass.
Here's the dump of IOHIDUserClient's gMetaClass object in memory, byte by byte:

Code: Select all

// kernel pointer
0x58
0xa4
0xb0
0x9d
0x7f
0xff
0xff
0xff

// kernel pointer
0x20
0x69
0x42
0x47
0x80
0xff
0xff
0xff

// kernel pointer
0x88
0x90
0x92
0x1d
0x80
0xff
0xff
0xff

// kernel pointer
0x90
0x94
0x42
0x47
0x80
0xff
0xff
0xff

// IOHIDUserClient size!
0xe0


The size is stored at the end of the structure, before a bunch of zeroes that mark the end. But I can't seem to get anything useful by reading those pointers.
Anyway, it looks like I can get all the infos I need (class name, size, parent's gMetaClass pointer) by disassembling the class constructor, the only thing that still bothers me is how to analyze and find all these informations with symbols stripped.
I read around that I should find cross references of __ZN11OSMetaClassC2EPKcPKS_j, which is called by any IOKit constructor. Thing is: I don't know how to find these cross references. If you can provide even a starting point or some informations I would be so grateful! Thanks again!
kmfpl
 
Posts: 2
Joined: Mon Dec 21, 2015 5:07 pm

Re: Dump a class gMetaClass

Postby morpheus » Thu Jan 07, 2016 9:50 pm

First, for our readers not fluent in C++-ish: you're looking for OSMetaClass::OSMetaClass(char const*, OSMetaClass const*, unsigned int), mangled by C++.

Second: The symbol you want is exported by xnu

Code: Select all
Ergo:~ morpheus$ jtool -S /System/Library/Kernels/kernel | grep __ZN11OSMetaClassC2EPKcPKS_j
ffffff8000838cc0 T __ZN11OSMetaClassC2EPKcPKS_j


and called on by oh so many kexts, as you correctly pointed out.. For example, the Adversary, AMFI:

Code: Select all
Ergo:~ morpheus$ jtool -S /System/Library/Extensions/AppleMobileFileIntegrity.kext/Contents/MacOS/AppleMobileFileIntegrity  | grep __ZN11OSMetaClassC2EPKcPKS_j   | c++filt
         U OSMetaClass::OSMetaClass(char const*, OSMetaClass const*, unsigned int)


and so finding the refs is easy (unfortunately with otool, since jtool doesn't do Intel..)

Code: Select all
Ergo:~ morpheus$ otool -tV /System/Library/Extensions/AppleMobileFileIntegrity.kext/Contents/MacOS/AppleMobileFileIntegrity  | grep __ZN11OSMetaClassC2EPKcPKS_j 
00000000000010c8   callq   __ZN11OSMetaClassC2EPKcPKS_j
0000000000001188   callq   __ZN11OSMetaClassC2EPKcPKS_j
00000000000014b2   callq   __ZN11OSMetaClassC2EPKcPKS_j
0000000000003e78   callq   __ZN11OSMetaClassC2EPKcPKS_j
0000000000003f38   callq   __ZN11OSMetaClassC2EPKcPKS_j
0000000000005415   calls   __ZN11OSMetaClassC2EPKcPKS_j


and btw,
morpheus
Site Admin
 
Posts: 532
Joined: Thu Apr 11, 2013 6:24 pm


Return to Questions and Answers

Who is online

Users browsing this forum: No registered users and 2 guests