开源软件名称(OpenSource Name):slavaim/MacOSX-Kernel-Filter开源软件地址(OpenSource Url):https://github.com/slavaim/MacOSX-Kernel-Filter开源编程语言(OpenSource Language):C++ 82.7%开源软件介绍(OpenSource Introduction):MacOSX-Kernel-FilterLicenseThe license model is a BSD Open Source License. This is a non-viral license, only asking that if you use it, you acknowledge the authors, in this case Slava Imameev. The project uses the distorm disassembler https://github.com/gdabah/distorm which is now released under BSD license. FeaturesThe project contains a kernel mode driver filter for Mac OS X , aka kernel extension ( kext ). General InformationThe driver was developed in 2009-2013 and tested on Mac OS X Snow Leopard, Mac OS X Lion, Mac OS X Mountain Lion, Mac OS X Mavericks, Mac OS X Yosemite. DesignThis kernel extension (kext) consists of a number of fairly independent subsystems. Some of these subsystems are discussed in the following documents https://github.com/slavaim/MacOSX-FileSystem-Filter/blob/master/README.md The kext uses a hooking technique to provide filtering functionality. The kext hooks C++ virtual table for IOKit classes to filter access to IOKit objects and file operation tables for VFS to filter access to file systems. Apple I/O Kit is a set of classes to develop kernel modules for Mac OS X and iOS. Its analog in the Windows world is KMDF/UMDF framework. I/O Kit is built atop Mach and BSD subsystems like Windows KMDF is built atop WDM and kernel API. The official way to develop a kernel module filter for Mac OS X and iOS is to inherit filter C++ class from a C++ class it filters. This requires access to a class declaration which is not always possible as some classes are Apple private or not published by a third party developers. In most cases all these private classes are inherited from classes that are in the public domain. That means they extend an existing interface/functionality and a goal to filter device I/O can be achieved by filtering only the public interface. This is nearly always true because an I/O Kit class object that is attached to this private C++ class object is usually an Apple I/O Kit class that knows nothing about the third party extended interface or is supposed to be from a module developed by third party developers and it knows only about a public interface. In both cases the attached object issues requests to a public interface. Let's consider some imaginary private class IOPrivateInterface that inherits from some IOAppleDeviceClass which declaration is available and an attached I/O Kit object issues requests to IOAppleDeviceClass interface
You want to filter requests to a device managed by IOPrivateInterface, that means that you need to declare your filter like
this would never compile as you do not have access to IOPrivateInterface class. You can't declare you filter as
as this will jettison all IOPrivateInterface code and the device will not function correctly. There might be another reason to avoid standard I/O Kit filtering by inheritance. A filtering class objects replaces an original class object in the I/O Kit device stack. That means a module with a filter should be available on device discovery and initialization. In nearly all cases this means that an instance of a filter class object will be created during system startup. This puts a great responsibility on a module developer as an error might render the system unbootable without an easy solution for a customer to fix the problem. To overcome these limitations I developed a hooking technique for I/O kit classes. I/O Kit uses virtual C++ functions so a class can be extended but its clients still be able to use a base class declaration. That means that all functions that used for I/O are placed in the array of function pointers known as vtable. The hooking technique supports two types of hooking.
The former method allows to filter access to a particular object of a class but requires knowing a vtable size. The latter method allows to filter request without knowing vtable size but as vtable is shared by all objects of a class a filter will see requests to all objects of a particular class. To get a vtable size you need a class declaration or get the size by reverse engineering. The hooker code can be found in DldHookerCommonClass.cpp . The kext uses C++ templates to avoid code duplication. Though Apple documentation declares that C++ templates are not supported by I/O Kit it is true only if a template is used to declare I/O kit object. You can compile I/O kit module with C++ template classes if they are not I/O Kit classes but template parameters can be I/O Kit classes. As you probably know after instantiation a template is just an ordinary C++ class. Template classes support is not required from run time environment. You can't declare I/O Kit class as a template just because a way Apple declares them by using C style preprocessor definitions. Below is a call stack when a hooked I/O Kit object virtual function is called by IOStorage::open
The more thorough hooker description can be found here https://github.com/slavaim/MacOSX-IOKit-Hooker/blob/master/README.md Loading the moduleTo load the kext run the following commands, in my case the project's directory is /work/DL/GitHub/DL
To verify that the kext has loaded run the output should be like
ClientThe folder DldClient contains a user mode client that connects to a loaded kernel module. The client code is out of sync with the driver but nevertheless it gives some ideas how to communicate with the kernel module. The client project was composed in an ancient XCode 3.2.6 , this is a mid 2010 project. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论