Skip to content

Instantly share code, notes, and snippets.

@jmpews
Last active April 1, 2023 09:05
Show Gist options
  • Save jmpews/01b520993a742f72714cd06e40793eed to your computer and use it in GitHub Desktop.
Save jmpews/01b520993a742f72714cd06e40793eed to your computer and use it in GitHub Desktop.
reversing IOSurface kext and framework

xnu libkern c++ 初始化.

先初始化 metavtable

OSMetaClass *IOSurface_InitFunc_7()
{
  OSMetaClass *result; // x0

  result = OSMetaClass::OSMetaClass(
             (OSMetaClass *)&IOSurfaceRootUserClient,
             "IOSurfaceRootUserClient",
             (const OSMetaClass *)&IOUserClient::gMetaClass,
             0x150u);
  result->baseclass_0._vptr$OSMetaClassBase = (int (**)(void))&qword_FFFFFFF006E66390;
  return result;
}

初始化 vtable

__int64 __fastcall IOSurfaceRoot::newUserClient(void *this, task *owningTask, void *a2, unsigned int type, IOUserClient **handler)
{
  IOUserClient **v5; // x21
  task *v6; // x23
  void *v7; // x20
  __int64 v8; // x19
  __int64 v9; // x0
  IOUserClient *v10; // x22

  v5 = handler;
  v6 = owningTask;
  v7 = this;
  v8 = 3758097097LL;
  *handler = 0LL;
  if ( !type )
  {
    v9 = (*((__int64 (**)(void))IOSurfaceRootUserClient.baseclass_0._vptr$OSMetaClassBase + 0xC))();
    v10 = (IOUserClient *)v9;
    if ( v9 )
    {
      if ( (*(unsigned int (__fastcall **)(__int64, void *, task *, _QWORD))(*(_QWORD *)v9 + 0x5C8LL))(v9, v7, v6, 0LL)
        && (*(unsigned int (__fastcall **)(IOUserClient *, void *))(*(_QWORD *)v10 + 0x358LL))(v10, v7) )
      {
        if ( (*(unsigned int (__fastcall **)(IOUserClient *, void *))(*(_QWORD *)v10 + 680LL))(v10, v7) )
        {
          v8 = 0LL;
          *v5 = v10;
          return v8;
        }
        (*(void (__fastcall **)(IOUserClient *, void *))(*(_QWORD *)v10 + 864LL))(v10, v7);
      }
      (*(void (__fastcall **)(IOUserClient *))(*(_QWORD *)v10 + 40LL))(v10);
      return v8;
    }
  }
  return v8;
}

key structure

IOSurface: init with `IOSurface::init`.
struct IOSurface {
+0xD0: OSDictionary store the {key, value} which provided by `IOSurfaceRootUserClient::s_set_value`
};

IOSurfaceRoot: init at the first
struct IOSurfaceRoot {
+?: IOSurfaceArray store the `IOSurface`
}

IOSurfaceClient: IOSurfaceClient::init(IOSurfaceRootUserClient, IOSurface),and return to userspace
#pragma pack(push, 1)
struct IOSurfaceClient
{
  _QWORD field_0;
  _BYTE gap_8[8];
  IOSurfaceRootUserClient *IOSurfaceRootUserClient;
  _BYTE gap_18[16];
  _QWORD field_28;
  IOSurfaceClient **field_30;
  int IOSurfaceID;
  _BYTE gap_3C[4];
  IOSurface *IOSurface;
  _BYTE gap_48[16];
  unsigned __int64 field_58;
  unsigned __int64 field_60;
  __int64 field_68;
  char field_70;
  _BYTE gap_71[7];
  _QWORD field_78;
};
#pragma pack(pop)

IOSurfaceRootUserClient: has a `IOSurfaceClientArray` member to store the `IOSurfaceClient`
struct __attribute__((aligned(8))) IOSurface
{
  _QWORD field_0;
  _BYTE gap_8[4];
  int IOSurfaceID;
  _BYTE gap_10[17];
  char field_21;
  _BYTE gap_22[2];
  _BYTE IsAlreadyInitIOBufferMemoryDescriptor;
  char field_25;
  _BYTE gap_26[2];
  _QWORD field_28;
  _BYTE gap_30[8];
  _QWORD IOBufferMemoryDescriptor;
  _BYTE gap_40[24];
  __int64 field_58;
  _BYTE gap_60[32];
  _QWORD field_80;
  _BYTE gap_88[8];
  int field_90;
  int field_94;
  int field_98;
  char field_9C;
  _BYTE gap_9D;
  char field_9E;
  char field_9F;
  int field_A0;
  int field_A4;
  _BYTE gap_A8[4];
  int IOSurfaceAllocSize;
  int field_B0;
  int field_B4;
  __int64 field_B8;
  _QWORD field_C0;
  _QWORD field_C8;
  _QWORD UserspaceValueDictionary;
  _BYTE gap_D8[16];
  _QWORD field_E8;
  _BYTE gap_F0[232];
  __int64 field_1D8;
  _BYTE gap_1E0[4];
  int field_1E4;
  int field_1E8;
  _BYTE gap_1EC[36];
  __int64 field_210;
  _BYTE gap_218[54];
  __attribute__((packed)) __attribute__((aligned(1))) int field_24E;
  _BYTE gap_252[214];
  _QWORD field_328;
  _BYTE gap_330[8];
  char field_338;
  _BYTE gap_339[31];
  _QWORD field_358;
  _BYTE gap_360[32];
  OSDictionary *field_380;
};
#pragma pack(push, 1)
struct IOSurfaceClient
{
  _QWORD field_0;
  _BYTE gap_8[8];
  IOSurfaceRootUserClient *IOSurfaceRootUserClient;
  _BYTE gap_18[16];
  _QWORD field_28;
  IOSurfaceClient **field_30;
  int IOSurfaceID;
  _BYTE gap_3C[4];
  IOSurface *IOSurface;
  _BYTE gap_48[16];
  unsigned __int64 field_58;
  unsigned __int64 field_60;
  __int64 field_68;
  char field_70;
  _BYTE gap_71[7];
  _QWORD field_78;
};
#pragma pack(pop)
#pragma pack(push, 1)
struct IOSurfaceRootUserClient
{
  _QWORD field_0;
  _BYTE gap_8[208];
  __int64 field_D8;
  IOSurfaceRoot *IOSurfaceRoot;
  _BYTE gap_E8[8];
  IOSurfaceRootUserClient *field_F0;
  __int64 field_F8;
  char *field_100;
  __int64 field_108;
  char *field_110;
  IOSurfaceClient **IOSurfaceClientArray;
  __int64 field_120;
  _BYTE gap_128[16];
  char field_138;
  char field_139;
  _BYTE gap_13A[2];
  int field_13C;
  _QWORD field_140;
  _QWORD field_148;
};
#pragma pack(pop)
disass -n kernel_memory_allocate -c 2
breakpoint set -a 0xffffff801a63bca0
breakpoint modify -c "$rdi==kernel_map" 1
breakpoint set -n IOSurfaceRootUserClient::s_set_value
@jmpews
Copy link
Author

jmpews commented Apr 2, 2020

https://mega.nz/#!Sc8w3SKZ!9j7bTN4q-BrFhOTFcLN3AEjYpX8zDMXXymMjPZgmByc macOS 10.15.1 /System/Library/Extensions/IOSurface.kext/Contents/MacOS/IOSurface

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment