macOS IOKit
Temel Bilgiler
I/O Kit, XNU çekirdeğinde açık kaynaklı, nesne yönelimli cihaz sürücüsü çerçevesidir ve dinamik olarak yüklenen cihaz sürücülerini yönetir. Farklı donanımları destekleyerek çekirdeğe modüler kod eklenmesine olanak tanır.
IOKit sürücüleri esasen çekirdekten fonksiyonlar dışa aktarır. Bu fonksiyon parametre tipleri önceden tanımlıdır ve doğrulanır. Ayrıca, XPC'ye benzer şekilde, IOKit sadece Mach mesajlarının üstünde başka bir katmandır.
IOKit XNU çekirdek kodu, Apple tarafından https://github.com/apple-oss-distributions/xnu/tree/main/iokit adresinde açık kaynak olarak yayınlanmıştır. Ayrıca, kullanıcı alanı IOKit bileşenleri de açık kaynaklıdır https://github.com/opensource-apple/IOKitUser.
Ancak, hiçbir IOKit sürücüsü açık kaynak değildir. Yine de, zaman zaman bir sürücü sürümü, hata ayıklamayı kolaylaştıran sembollerle birlikte gelebilir. Firmware'den sürücü uzantılarını nasıl alacağınızı buradan kontrol edin.
C++ ile yazılmıştır. Demangled C++ sembollerini almak için:
IOKit açık fonksiyonlar bir istemcinin bir fonksiyonu çağırmaya çalıştığında ek güvenlik kontrolleri gerçekleştirebilir, ancak uygulamaların genellikle etkileşimde bulunabilecekleri IOKit fonksiyonlarıyla sandbox tarafından sınırlı olduğunu unutmayın.
Sürücüler
macOS'ta şunlarda bulunurlar:
/System/Library/Extensions
OS X işletim sistemine entegre edilmiş KEXT dosyaları.
/Library/Extensions
Üçüncü taraf yazılımlar tarafından yüklenen KEXT dosyaları.
iOS'ta şunlarda bulunurlar:
/System/Library/Extensions
9'a kadar listelenen sürücüler 0 adresinde yüklenmiştir. Bu, bunların gerçek sürücüler olmadığı, ancak çekirdek parçası oldukları ve boşaltılamayacakları anlamına gelir.
Belirli uzantıları bulmak için şunları kullanabilirsiniz:
Kernel uzantılarını yüklemek ve kaldırmak için:
IORegistry
IORegistry, macOS ve iOS'taki IOKit çerçevesinin önemli bir parçasıdır ve sistemin donanım yapılandırmasını ve durumunu temsil eden bir veritabanı olarak hizmet eder. Bu, sistemde yüklü olan tüm donanım ve sürücüleri temsil eden hiyerarşik bir nesne koleksiyonudur ve bunların birbirleriyle olan ilişkilerini gösterir.
IORegistry'yi, konsoldan incelemek için cli ioreg
kullanarak alabilirsiniz (özellikle iOS için faydalıdır).
IORegistryExplorer
'ı Xcode Ek Araçlar'dan https://developer.apple.com/download/all/ adresinden indirebilir ve macOS IORegistry'ni grafiksel bir arayüz aracılığıyla inceleyebilirsiniz.
IORegistryExplorer'da, "düzlemler" IORegistry'deki farklı nesneler arasındaki ilişkileri düzenlemek ve görüntülemek için kullanılır. Her düzlem, belirli bir ilişki türünü veya sistemin donanım ve sürücü yapılandırmasının belirli bir görünümünü temsil eder. IORegistryExplorer'da karşılaşabileceğiniz bazı yaygın düzlemler şunlardır:
IOService Düzlemi: Bu, sürücüleri ve nubs'ları (sürücüler arasındaki iletişim kanalları) temsil eden hizmet nesnelerini görüntüleyen en genel düzlemdir. Bu nesneler arasındaki sağlayıcı-müşteri ilişkilerini gösterir.
IODeviceTree Düzlemi: Bu düzlem, cihazların sisteme bağlı olduğu fiziksel bağlantıları temsil eder. Genellikle USB veya PCI gibi bus'lar aracılığıyla bağlı cihazların hiyerarşisini görselleştirmek için kullanılır.
IOPower Düzlemi: Güç yönetimi açısından nesneleri ve bunların ilişkilerini görüntüler. Diğerlerinin güç durumunu etkileyen nesneleri gösterebilir, güçle ilgili sorunları gidermek için yararlıdır.
IOUSB Düzlemi: Özellikle USB cihazları ve bunların ilişkilerine odaklanır, USB hub'larının ve bağlı cihazların hiyerarşisini gösterir.
IOAudio Düzlemi: Bu düzlem, ses cihazlarını ve bunların sistem içindeki ilişkilerini temsil etmek içindir.
...
Sürücü İletişim Kodu Örneği
Aşağıdaki kod, IOKit hizmetine "YourServiceNameHere"
bağlanır ve seçici 0 içindeki fonksiyonu çağırır. Bunun için:
Öncelikle
IOServiceMatching
veIOServiceGetMatchingServices
çağrılarak hizmet alınır.Ardından
IOServiceOpen
çağrılarak bir bağlantı kurulur.Son olarak, seçici 0'ı belirterek
IOConnectCallScalarMethod
ile bir fonksiyon çağrılır (seçici, çağırmak istediğiniz fonksiyona atanan numaradır).
There are other functions that can be used to call IOKit functions apart of IOConnectCallScalarMethod
like IOConnectCallMethod
, IOConnectCallStructMethod
...
Sürücü giriş noktasını tersine mühendislik
Bunları örneğin bir firmware image (ipsw) üzerinden elde edebilirsiniz. Ardından, bunu en sevdiğiniz dekompilerde yükleyin.
externalMethod
fonksiyonunu decompile etmeye başlayabilirsiniz çünkü bu, çağrıyı alacak ve doğru fonksiyonu çağıracak sürücü fonksiyonudur:
O korkunç çağrı demagled, şunları ifade eder:
Önceki tanımda self
parametresinin eksik olduğunu unutmayın, iyi bir tanım şöyle olmalıdır:
Aslında, gerçek tanımı https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/Kernel/IOUserClient.cpp#L6388 adresinde bulabilirsiniz:
Bu bilgiyle Ctrl+Right -> Edit function signature
yazabilir ve bilinen türleri ayarlayabilirsiniz:
Yeni decompile edilmiş kod şöyle görünecek:
Sonraki adımda IOExternalMethodDispatch2022
yapısını tanımlamamız gerekiyor. Bu yapı https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/iokit/IOKit/IOUserClient.h#L168-L176 adresinde açık kaynak olarak mevcuttur, bunu tanımlayabilirsiniz:
Şimdi, (IOExternalMethodDispatch2022 *)&sIOExternalMethodArray
ifadesinin ardından birçok veri görebilirsiniz:
Veri Türünü IOExternalMethodDispatch2022:
olarak değiştirin:
değişiklikten sonra:
Ve şimdi orada 7 elemanlı bir dizi olduğunu biliyoruz (son decompile edilmiş kodu kontrol edin), 7 elemanlı bir dizi oluşturmak için tıklayın:
Dizi oluşturulduktan sonra, tüm dışa aktarılan fonksiyonları görebilirsiniz:
Hatırlarsanız, kullanıcı alanından bir dışa aktarılan fonksiyonu çağırmak için fonksiyonun adını değil, seçici numarasını çağırmamız gerekiyor. Burada seçici 0 fonksiyonu initializeDecoder
, seçici 1 startDecoder
, seçici 2 initializeEncoder
olduğunu görebilirsiniz...
Last updated