I tried to load kext module on M1 machine running 11.4 Beta (20F5046g) Big Sur and encounter some error messages on binding at kext module loading.
Accessing kernel symbol exported from Apple kext modules
First, to access the kernel functions exported from apple's kext module, com.apple.kpi.unsupported, I used the below extern declaration.
extern int cpu_number(void);
Also, I added the com.apple.kpi.unsupported on the info.plist
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.libkern</key>
<string>20.5</string>
<key>com.apple.kpi.unsupported</key>
<string>20.5.0</string>
</dict>
The compilation doesn't raise any errors, but when I try to load the module, it prints below message.
Error Domain=KMErrorDomain Code=31 "Error occurred while building a collection:
1: One or more binaries has an error which prevented linking. See other errors.
2: Could not use 'kext' because: Failed to bind '_cpu_number' in 'kext' (at offset 0x0 in __DATA_CONST, __got) as could not find a kext which exports this symbol
kext specific:
1: Failed to bind '_cpu_number' in 'kext' (at offset 0x0 in __DATA_CONST, __got) as could not find a kext which exports this symbol
" UserInfo={NSLocalizedDescription=Error occurred while building a collection:
1: One or more binaries has an error which prevented linking. See other errors.
2: Could not use 'kext' because: Failed to bind '_cpu_number' in 'kext' (at offset 0x0 in __DATA_CONST, __got) as could not find a kext which exports this symbol
kext specific:
1: Failed to bind '_cpu_number' in 'kext' (at offset 0x0 in __DATA_CONST, __got) as could not find a kext which exports this symbol
Can I access the kernel symbol specified in the kernel symbol list but not exported from apple's kext module?
I also would like to access kernel function called SecureDTInitEntryIterator. I found that this symbol is listed on the kernel symbol located in the /System/Library/Kernels/kernel. However, $kextfind -defines-symbol _SecureDTIterateEntries doesn't return any corresponding kext module names.
As an IOS newbie, I guess that this symbol is not exported from any apple's kexy module. Is there any way to access this function from my kext module? I think I can just type cast the address where the symbol is located within the kernel space with the function prototype, but I am looking for a systematic approach if there exists.
I have just checked, and the crucial detail appears to be that you are trying to access this function on arm64/aarch64. As it turns out, it's exported in the "unsupported" KPI for x86_64, but not on arm64:
Unsupported.x86_64.exports in xnu source
Unsupported.arm64.exports in xnu source
There's no straightforward way of accessing unexported symbols. If you know the offset of a symbol in the exact version of the running kernel, you should be able to compute the address by offsetting from a known function address; at least, this worked on x86-64. arm64 may require extra effort due to PAC (pointer authentication).
As this circumvents Apple's policies, I don't recommend using this type of technique in a shipping product.
Related
I am trying to hunt down retain leaks in an open-source project to support I2C based trackpads (https://github.com/kprinssu/VoodooI2CHID).
The reason why I believe that there are retain leaks is because when I attempt to unload the kernel extension via the following commands:
sudo kextunload -verbose 6 VoodooI2CHID.kext
I get the following output:
Kext user-space log filter changed from 0xff2 to 0xfff.
Kext kernel-space log filter changed from 0xff2 to 0xfff.
Kext library architecture set to x86_64.
Requesting unload of com.alexandred.VoodooI2CHID (with termnation of IOServices).
(kernel) User-space log flags changed from 0x0 to 0xfff.
(kernel) Received 'Unload' request from user space.
(kernel) Rescheduling scan for unused kexts in 60 seconds.
(kernel) Can't unload kext com.alexandred.VoodooI2CHID; classes have instances:
(kernel) Kext com.alexandred.VoodooI2CHID class VoodooI2CPrecisionTouchpadHIDEventDriver has 1 instance.
(kernel) Kext com.alexandred.VoodooI2CHID class VoodooI2CMultitouchHIDEventDriver has 1 instance.
Kernel error handling kext request - (libkern/kext) kext is in use or retained (cannot unload).
Failed to unload com.alexandred.VoodooI2CHID - (libkern/kext) kext is in use or retained (cannot unload).
I came across pmdj's excellent answer on tracking down retain leaks (Can't Unload Kernel Extension; Classes Have Instances). I verfied that my situation is the second case via ioreg (classes are being terminated but are not properly freed). Additionally, I used pmdj's hint by overiding taggedRelease and taggedRetain (https://stackoverflow.com/a/13471512/48660) to print the stack trace of the function calls.
Here's where I run into problems, I cannot use atos to convert the hex addresses back into human readable symbols. I use the follow command to generate the symbols:
atos -arch x86_x64 -o VoodooI2C.kext/Contents/MacOS/VoodooI2C -l 0xffffff7f8432b000 0xffffff804588dfa0
The load address parameter is retrieved from kextstat and I expect the -l argument should handle the slide arithmetic.
atos should return a valid symbol but all I get is the hex address back. In the above example, I get 0xffffff804588dfa0 as the output. Can anybody point out what I exactly I am missing?
Both kextstat and OSReportWithBacktrace report unslid addresses, so KASLR is not your problem.
Notice that your kext is apparently loaded at 0xffffff7f8432b000, whereas your backtrace frame address is 0xffffff804588dfa0. This is quite far apart, and indeed kexts are always loaded in the 0xffffff7f8??????? (unslid) range, so 0xffffff804588dfa0 can't be anywhere near kext code. (the offset is about 3GB) It's almost certainly a function in the kernel proper. If you use atos with the appropriate running kernel's binary, it should be able to locate which one. For example:
atos -o /Library/Developer/KDKs/KDK_10.14.5_18F132.kdk/System/Library/Kernels/kernel 0xffffff804588dfa0
(I don't know what kernel version you are using, and this address doesn't seem to be meaningful in the 18F132 kernel, but you get the idea.)
For example IDA Pro shows import table containing function CheckTokenMembership in library api-ms-win-security-base-l1-2-0
Checking MSDN info for API call https://msdn.microsoft.com/en-us/library/windows/desktop/aa376389(v=vs.85).aspx it says it is in advapi32.dll
However trying
bp advapi32!CheckTokenMembership
Results in error Couldn't resolve error at 'advapi32!CheckTokenMembership'
CheckTokenMembership is and always will be exported by advapi32.dll. The problem is that WinDbg uses the symbol name if you have symbols for said module.
What I would do is type bp ADVAPI32!CheckTokenMembership and then press Tab and you should end up with bp ADVAPI32!CheckTokenMembershipStub. This trick does not work for everything, sometimes you have to figure out the forward yourself or take a peek at the ntdll.dll and kernelbase.dll exports.
api- files do not contain code, they are just a layering exercise that Microsoft is forcing on everyone for some reason. I believe they are a result of the MinWin experiment and they might possibly some day contain code but even then kernel32 and friends will still have forwarders to maintain compatibility so there is no reason for anyone outside Microsoft to use the api- files (IMHO).
I verified on a crash dump file that advapi32.dll exports the CheckTokenMembership function, so setting a breakpoint should be possible. It's likely in your scenario the module has not yet been loaded, so how about trying 'bu' instead? From WinDbg help:
The bu (Set Unresolved Breakpoint) command sets a deferred or unresolved breakpoint. A bu breakpoint is set on a symbolic reference to the breakpoint location that is specified in the command (not on an address) and is activated whenever the module with the reference is resolved. For more information about these breakpoints, see Unresolved Breakpoints (bu Breakpoints).
76b51ca2 advapi32!CheckTokenMembership ()
Recently my laptop has been having Kernel Panics once every few days. I can't find a certain program that is making it happen, or a certain task that I perform.
I read that you can look in the .crash reports for a possible cause. So here is part of one I found.
Dyld Error Message:
Library not loaded: /usr/lib/libgutenprint.2.dylib
Referenced from: /usr/libexec/cups/driver/gutenprint.5.2
Reason: image not found
I am wondering if gutenprint.5.2 could be the reason for the Kernel crashing. If so, should I remove it? Install an update?
Thanks!
That's not a kernel panic. You'll find kernel panic reports in Console.app, under system diagnostic reports. They start with "kernel" and end with ".panic". Unless you wrote the driver that's crashing, this is the wrong site to post such questions. Try the Ask Different sister site at https://apple.stackexchange.com/ instead.
I am doing some OSX kernel debugging with lldb and KDK.
When the kernel crash,I want to view the zones,and search the zones.
So I use:
(lldb) command script import lldb.macosx.heap
(lldb) cstr_refs CSTRING
This command is always working in Ring3 debugging, but when at kernel debugging, lldb give me an error:
error: error: use of undeclared identifier 'malloc_get_all_zones'
error: 1 errors parsing expression
The script heap.py is unusable in kernel?
How to search the kernel zones at this situation?
Someone more familiar with kernel issues can maybe tell you how to get the information you want out of the kernel. I can answer the part about "heap.py". It is only meant to be used when debugging userland programs. It relies on details of the userland malloc implementation, and it relies on being able to call functions in the debugee which is not currently possible when debugging the kernel.
Note, if you get the KDK so you have the dSYM for the mach kernel, it defines a bunch of commands that poke around in the kernel's data structures. It may be one of them will tell you what you want to know. Remember to run the lldb command:
(lldb) settings set target.load-script-from-symbol-file true
in order to allow lldb to read in the Python from the dSYM that defines all these macros. Then running the lldb help command will show you all the kernel-specific commands.
I've got some obscure errors in an OS X program concerning the loading and unloading and symbol bindings of dynamically loaded libraries. First attempts to analyse the problem by using the DYLD_PRINT_* environment variables failed.
I solved similar problems under GNU/Linux by installing the glibc with debug symbols and the corresponding sources. Since the sources for dyld are also available, something similar must be possible under OS X.
How do I have to proceed in order to set up a debugging session and step through the sources of dyld in order to understand what went wrong with the program? Is it possible to start an application using a different hand-crafted dyld?
You can set a symbolic breakpoint of dyld`dyldbootstrap::start.
So, Symbol is "dyldbootstrap::start", and Module is "dyld".
Actually, we can set a symbolic breakpoint of dyld`_dyld_start, and we can see it enabled after the process launched, but it won't be hit.
Yes, and it's actually designed to be this way. You can drop your custom dyld in the file system, making sure its LC_ID_DYLINKER command is set properly. Then, to use it, edit the Mach-O you are loading so that its LC_LOAD_DYLINKER points to it.
Mind you, it's possible to just step through dyld anyway without all this - use lldb and do process launch -s , then you can single step right through dyld as well, albeit in assembly.
Caveat: Don't touch or move the /usr/lib/dyld in the process - but rather drop the custom dyld side by side to it. Since virtually everything requires dyld, moving it can be a pain to undo (and requires booting with a ramdisk and mounting the root file system as a secondary just so as to issue the correcting mv..)