Re: Obtaining non-exported symbol from kernel on runtime (without the debug symbols)
site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com On Sat, 13 Dec 2008, John D. wrote: Hi, I'm working on a college project and I would like to access some non-exported API. For example chgproccnt and kld_file_lookupsymbol. I want to be able to obtain a symbol address from a kernel extension, say, of the mach_kernel file. This could come handy but apparently none of the useful API is available to extensions. Has anyone done anything similar or can provide a suggestion to access kld_file_lookupsymbol() without using static addresses (to avoid version-specific builds, since Apple can change it anytime). 1 - You can create your Kext against the entire kernel instead of supported KPI bundles, by putting the following in the Info.plist for the Kext. <key>OSBundleLibraries</key> <dict> <key>com.apple.kernel</key> <string>9.5.0</string> </dict> Then, you can link to any global symbol in "/mach_kernel". (For example, chgproccnt() is one of these.) You will probably need the open kernel sources to use as documentation and you can find out what is global via "nm -g /mach_kernel" and looking for the symbols. 2 - If that doesn't get what you want, because the routine you need is non-global, you can crib it (making sure the resultant source file has the APSL on it and it handled in accordance with the APSL). This works if the routine doesn't use "private" globals or you can get a set of routines cribbed, so that you get to that state. (Obviously risky and you may need to re-crib them each time a new xnu-1228 source tree is released.) 3 - If you need to figure out where a private global is, you might be able to locate it based on knowing that the linker has it between two globals that you can link to. (To make this even more fun, the linking used for PPC vs Intel kernels results in slightly different orderings, ergo the just before or after.) All readers can now prepare to puke (or maybe just laugh) at the following code I use to do that for one case: /* * Holy Bogosity Batman!. To hijack the nfssvc syscall, * I need to fiddle with the sysent table, but it's defined * __private_extern__, so I use nsysent to get a pointer to it. * The trick is that nsysent is right next to the table, either * just before or just after it. (Not right after it, though:-) * First, try just before and then just after. */ if (mysysentptr == NULL) { mysysentptr = (struct sysent *)&nsysent; mysysentptr -= nsysent; if (mysysentptr[SYS_nfssvc].sy_call != (sy_call_t *)nfssvc) { tptr = &nsysent; do { tptr++; mysysentptr = (struct sysent *)tptr; } while (mysysentptr[SYS_nfssvc].sy_call != (sy_call_t *)nfssvc && tptr < &kdebug_chudhook); } if (mysysentptr[SYS_nfssvc].sy_call != (sy_call_t *)nfssvc) { mysysentptr = NULL; printf("couldn't hijack nfssvc\n"); return (EINVAL); } } Not recommended and only to be used if you understand the implications, but they work for me. (I've actually been lucky and my Kext hasn't needed to be changed for 9.0.0->9.5.0, but I expect to get bit soon:-) Good luck with it, rick _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... Since you note that it is a college project (which sounds like it is similar in spirit to my open source experimental kext), here's a few things I've done to get around this problem. If you do any of these you will end up with a Kext that could break horribly whenever a new version of the mach_kernel is released by Apple. If you can live with this, here goes... This email sent to site_archiver@lists.apple.com
participants (1)
-
Rick Macklem