# macOS IOKit
{% hint style="success" %}
Learn & practice AWS Hacking:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
Learn & practice GCP Hacking: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Support HackTricks
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 馃挰 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 馃惁 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
{% endhint %}
## Podstawowe informacje
IO Kit to otwarto藕r贸d艂owy, obiektowy **framework sterownik贸w urz膮dze艅** w j膮drze XNU, obs艂uguj膮cy **dynamicznie 艂adowane sterowniki urz膮dze艅**. Umo偶liwia dodawanie modularnego kodu do j膮dra w locie, wspieraj膮c r贸偶norodny sprz臋t.
Sterowniki IOKit zasadniczo **eksportuj膮 funkcje z j膮dra**. Typy **parametr贸w** tych funkcji s膮 **zdefiniowane z g贸ry** i s膮 weryfikowane. Ponadto, podobnie jak XPC, IOKit jest po prostu kolejn膮 warstw膮 **na szczycie komunikat贸w Mach**.
**Kod j膮dra IOKit XNU** jest otwarto藕r贸d艂owy i udost臋pniony przez Apple w [https://github.com/apple-oss-distributions/xnu/tree/main/iokit](https://github.com/apple-oss-distributions/xnu/tree/main/iokit). Ponadto, komponenty IOKit w przestrzeni u偶ytkownika s膮 r贸wnie偶 otwarto藕r贸d艂owe [https://github.com/opensource-apple/IOKitUser](https://github.com/opensource-apple/IOKitUser).
Jednak偶e, **偶adne sterowniki IOKit** nie s膮 otwarto藕r贸d艂owe. Tak czy inaczej, od czasu do czasu wydanie sterownika mo偶e zawiera膰 symbole, kt贸re u艂atwiaj膮 jego debugowanie. Sprawd藕, jak [**uzyska膰 rozszerzenia sterownika z oprogramowania uk艂adowego tutaj**](./#ipsw)**.**
Jest napisany w **C++**. Mo偶esz uzyska膰 zdemanglowane symbole C++ za pomoc膮:
```bash
# Get demangled symbols
nm -C com.apple.driver.AppleJPEGDriver
# Demangled symbols from stdin
c++filt
__ZN16IOUserClient202222dispatchExternalMethodEjP31IOExternalMethodArgumentsOpaquePK28IOExternalMethodDispatch2022mP8OSObjectPv
IOUserClient2022::dispatchExternalMethod(unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*)
```
{% hint style="danger" %}
Funkcje **exponowane przez IOKit** mog膮 wykonywa膰 **dodatkowe kontrole bezpiecze艅stwa**, gdy klient pr贸buje wywo艂a膰 funkcj臋, ale nale偶y zauwa偶y膰, 偶e aplikacje s膮 zazwyczaj **ograniczone** przez **piaskownic臋**, z kt贸rymi funkcjami IOKit mog膮 wchodzi膰 w interakcje.
{% endhint %}
## Sterowniki
W macOS znajduj膮 si臋 w:
* **`/System/Library/Extensions`**
* Pliki KEXT wbudowane w system operacyjny OS X.
* **`/Library/Extensions`**
* Pliki KEXT zainstalowane przez oprogramowanie firm trzecich
W iOS znajduj膮 si臋 w:
* **`/System/Library/Extensions`**
```bash
#Use kextstat to print the loaded drivers
kextstat
Executing: /usr/bin/kmutil showloaded
No variant specified, falling back to release
Index Refs Address Size Wired Name (Version) UUID
1 142 0 0 0 com.apple.kpi.bsd (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
2 11 0 0 0 com.apple.kpi.dsep (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
3 170 0 0 0 com.apple.kpi.iokit (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
4 0 0 0 0 com.apple.kpi.kasan (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
5 175 0 0 0 com.apple.kpi.libkern (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
6 154 0 0 0 com.apple.kpi.mach (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
7 88 0 0 0 com.apple.kpi.private (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
8 106 0 0 0 com.apple.kpi.unsupported (20.5.0) 52A1E876-863E-38E3-AC80-09BBAB13B752 <>
9 2 0xffffff8003317000 0xe000 0xe000 com.apple.kec.Libm (1) 6C1342CC-1D74-3D0F-BC43-97D5AD38200A <5>
10 12 0xffffff8003544000 0x92000 0x92000 com.apple.kec.corecrypto (11.1) F5F1255F-6552-3CF4-A9DB-D60EFDEB4A9A <8 7 6 5 3 1>
```
Do numeru 9 wymienione sterowniki s膮 **za艂adowane pod adresem 0**. Oznacza to, 偶e nie s膮 to prawdziwe sterowniki, ale **cz臋艣膰 j膮dra i nie mog膮 by膰 od艂adowane**.
Aby znale藕膰 konkretne rozszerzenia, mo偶esz u偶y膰:
```bash
kextfind -bundle-id com.apple.iokit.IOReportFamily #Search by full bundle-id
kextfind -bundle-id -substring IOR #Search by substring in bundle-id
```
Aby za艂adowa膰 i od艂adowa膰 rozszerzenia j膮dra, wykonaj:
```bash
kextload com.apple.iokit.IOReportFamily
kextunload com.apple.iokit.IOReportFamily
```
## IORegistry
**IORegistry** jest kluczow膮 cz臋艣ci膮 frameworka IOKit w macOS i iOS, kt贸ry s艂u偶y jako baza danych do reprezentowania konfiguracji i stanu sprz臋tu systemu. To **hierarchiczna kolekcja obiekt贸w, kt贸re reprezentuj膮 ca艂y sprz臋t i sterowniki** za艂adowane w systemie oraz ich wzajemne relacje.
Mo偶esz uzyska膰 IORegistry za pomoc膮 cli **`ioreg`**, aby go zbada膰 z konsoli (szczeg贸lnie przydatne dla iOS).
```bash
ioreg -l #List all
ioreg -w 0 #Not cut lines
ioreg -p #Check other plane
```
Mo偶esz pobra膰 **`IORegistryExplorer`** z **Xcode Additional Tools** z [**https://developer.apple.com/download/all/**](https://developer.apple.com/download/all/) i zbada膰 **macOS IORegistry** za pomoc膮 **interfejsu graficznego**.
W IORegistryExplorer "p艂aszczyzny" s膮 u偶ywane do organizowania i wy艣wietlania relacji mi臋dzy r贸偶nymi obiektami w IORegistry. Ka偶da p艂aszczyzna reprezentuje okre艣lony typ relacji lub szczeg贸lny widok konfiguracji sprz臋towej i sterownik贸w systemu. Oto niekt贸re z powszechnych p艂aszczyzn, kt贸re mo偶esz napotka膰 w IORegistryExplorer:
1. **IOService Plane**: To najbardziej og贸lna p艂aszczyzna, wy艣wietlaj膮ca obiekty us艂ug, kt贸re reprezentuj膮 sterowniki i nuby (kana艂y komunikacyjne mi臋dzy sterownikami). Pokazuje relacje dostawca-klient mi臋dzy tymi obiektami.
2. **IODeviceTree Plane**: Ta p艂aszczyzna reprezentuje fizyczne po艂膮czenia mi臋dzy urz膮dzeniami, gdy s膮 pod艂膮czone do systemu. Cz臋sto jest u偶ywana do wizualizacji hierarchii urz膮dze艅 pod艂膮czonych przez magistrale, takie jak USB lub PCI.
3. **IOPower Plane**: Wy艣wietla obiekty i ich relacje w kontek艣cie zarz膮dzania energi膮. Mo偶e pokaza膰, kt贸re obiekty wp艂ywaj膮 na stan zasilania innych, co jest przydatne do debugowania problem贸w zwi膮zanych z zasilaniem.
4. **IOUSB Plane**: Skupia si臋 na urz膮dzeniach USB i ich relacjach, pokazuj膮c hierarchi臋 hub贸w USB i pod艂膮czonych urz膮dze艅.
5. **IOAudio Plane**: Ta p艂aszczyzna jest przeznaczona do reprezentowania urz膮dze艅 audio i ich relacji w systemie.
6. ...
## Przyk艂ad kodu komunikacji sterownika
Poni偶szy kod 艂膮czy si臋 z us艂ug膮 IOKit `"YourServiceNameHere"` i wywo艂uje funkcj臋 wewn膮trz selektora 0. W tym celu:
* najpierw wywo艂uje **`IOServiceMatching`** i **`IOServiceGetMatchingServices`**, aby uzyska膰 us艂ug臋.
* Nast臋pnie nawi膮zuje po艂膮czenie, wywo艂uj膮c **`IOServiceOpen`**.
* A na ko艅cu wywo艂uje funkcj臋 za pomoc膮 **`IOConnectCallScalarMethod`**, wskazuj膮c selektor 0 (selektor to numer przypisany funkcji, kt贸r膮 chcesz wywo艂a膰).
```objectivec
#import
#import
int main(int argc, const char * argv[]) {
@autoreleasepool {
// Get a reference to the service using its name
CFMutableDictionaryRef matchingDict = IOServiceMatching("YourServiceNameHere");
if (matchingDict == NULL) {
NSLog(@"Failed to create matching dictionary");
return -1;
}
// Obtain an iterator over all matching services
io_iterator_t iter;
kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
if (kr != KERN_SUCCESS) {
NSLog(@"Failed to get matching services");
return -1;
}
// Get a reference to the first service (assuming it exists)
io_service_t service = IOIteratorNext(iter);
if (!service) {
NSLog(@"No matching service found");
IOObjectRelease(iter);
return -1;
}
// Open a connection to the service
io_connect_t connect;
kr = IOServiceOpen(service, mach_task_self(), 0, &connect);
if (kr != KERN_SUCCESS) {
NSLog(@"Failed to open service");
IOObjectRelease(service);
IOObjectRelease(iter);
return -1;
}
// Call a method on the service
// Assume the method has a selector of 0, and takes no arguments
kr = IOConnectCallScalarMethod(connect, 0, NULL, 0, NULL, NULL);
if (kr != KERN_SUCCESS) {
NSLog(@"Failed to call method");
}
// Cleanup
IOServiceClose(connect);
IOObjectRelease(service);
IOObjectRelease(iter);
}
return 0;
}
```
There are **inne** functions that can be used to call IOKit functions apart of **`IOConnectCallScalarMethod`** like **`IOConnectCallMethod`**, **`IOConnectCallStructMethod`**...
## Reversing driver entrypoint
You could obtain these for example from a [**obraz firmware (ipsw)**](./#ipsw). Then, load it into your favourite decompiler.
You could start decompiling the **`externalMethod`** function as this is the driver function that will be receiving the call and calling the correct function:
That awful call demagled means:
{% code overflow="wrap" %}
```cpp
IOUserClient2022::dispatchExternalMethod(unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*)
```
{% endcode %}
Zauwa偶, 偶e w poprzedniej definicji brakuje parametru **`self`**, dobra definicja to:
{% code overflow="wrap" %}
```cpp
IOUserClient2022::dispatchExternalMethod(self, unsigned int, IOExternalMethodArgumentsOpaque*, IOExternalMethodDispatch2022 const*, unsigned long, OSObject*, void*)
```
{% endcode %}
W rzeczywisto艣ci mo偶esz znale藕膰 prawdziw膮 definicj臋 w [https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/Kernel/IOUserClient.cpp#L6388](https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/Kernel/IOUserClient.cpp#L6388):
```cpp
IOUserClient2022::dispatchExternalMethod(uint32_t selector, IOExternalMethodArgumentsOpaque *arguments,
const IOExternalMethodDispatch2022 dispatchArray[], size_t dispatchArrayCount,
OSObject * target, void * reference)
```
Z tymi informacjami mo偶esz przepisa膰 Ctrl+Right -> `Edit function signature` i ustawi膰 znane typy:
Nowy dekompilowany kod b臋dzie wygl膮da膰 nast臋puj膮co:
Na nast臋pnym etapie musimy zdefiniowa膰 struktur臋 **`IOExternalMethodDispatch2022`**. Jest to open source w [https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/IOKit/IOUserClient.h#L168-L176](https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/IOKit/IOUserClient.h#L168-L176), mo偶esz j膮 zdefiniowa膰:
Teraz, po `(IOExternalMethodDispatch2022 *)&sIOExternalMethodArray` mo偶esz zobaczy膰 wiele danych:
Zmie艅 typ danych na **`IOExternalMethodDispatch2022:`**
po zmianie:
Jak teraz widzimy, mamy **tablic臋 7 element贸w** (sprawd藕 ko艅cowy dekompilowany kod), kliknij, aby utworzy膰 tablic臋 7 element贸w:
Po utworzeniu tablicy mo偶esz zobaczy膰 wszystkie eksportowane funkcje:
{% hint style="success" %}
Je艣li pami臋tasz, aby **wywo艂a膰** funkcj臋 **eksportowan膮** z przestrzeni u偶ytkownika, nie musimy wywo艂ywa膰 nazwy funkcji, ale **numer selektora**. Tutaj mo偶esz zobaczy膰, 偶e selektor **0** to funkcja **`initializeDecoder`**, selektor **1** to **`startDecoder`**, selektor **2** **`initializeEncoder`**...
{% endhint %}
{% hint style="success" %}
Ucz si臋 i 膰wicz Hacking AWS:[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)\
Ucz si臋 i 膰wicz Hacking GCP: [**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)
Wsparcie dla HackTricks
* Sprawd藕 [**plany subskrypcyjne**](https://github.com/sponsors/carlospolop)!
* **Do艂膮cz do** 馃挰 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **艣led藕** nas na **Twitterze** 馃惁 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Dziel si臋 sztuczkami hackingowymi, przesy艂aj膮c PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repozytori贸w github.
{% endhint %}