Rizin
unix-like reverse engineering framework and cli tools
kernelcache.h File Reference
#include "mach0.h"
#include "../xnu/rz_cf_dict.h"

Go to the source code of this file.

Classes

struct  rz_xnu_kernelcache_file_range_t
 
struct  rz_xnu_kernelcache_rebase_info_t
 
struct  rz_xnu_kernelcache_parsed_pointer_t
 
struct  rz_xnu_kernelcache_obj_t
 

Macros

#define RZ_BIN_MACH064   1
 

Typedefs

typedef struct rz_xnu_kernelcache_file_range_t RzXNUKernelCacheFileRange
 
typedef struct rz_xnu_kernelcache_rebase_info_t RzXNUKernelCacheRebaseInfo
 
typedef struct rz_xnu_kernelcache_parsed_pointer_t RzXNUKernelCacheParsedPointer
 
typedef struct rz_xnu_kernelcache_obj_t RzXNUKernelCacheObj
 

Functions

RZ_API bool rz_xnu_kernelcache_buf_is_kernelcache (RzBuffer *b)
 
RZ_API RzBufferrz_xnu_kernelcache_new_rebasing_buf (RzXNUKernelCacheObj *obj)
 
RZ_API bool rz_xnu_kernelcache_needs_rebasing (RzXNUKernelCacheObj *obj)
 
RZ_API bool rz_xnu_kernelcache_parse_pointer (RzXNUKernelCacheParsedPointer *ptr, ut64 decorated_addr, RzXNUKernelCacheObj *obj)
 

Macro Definition Documentation

◆ RZ_BIN_MACH064

#define RZ_BIN_MACH064   1

Definition at line 8 of file kernelcache.h.

Typedef Documentation

◆ RzXNUKernelCacheFileRange

◆ RzXNUKernelCacheObj

◆ RzXNUKernelCacheParsedPointer

◆ RzXNUKernelCacheRebaseInfo

Function Documentation

◆ rz_xnu_kernelcache_buf_is_kernelcache()

RZ_API bool rz_xnu_kernelcache_buf_is_kernelcache ( RzBuffer b)

Definition at line 13 of file kernelcache.c.

13  {
15  if (length < sizeof(struct MACH0_(mach_header))) {
16  return false;
17  }
18  ut32 cputype;
19  if (!rz_buf_read_le32_at(b, 4, &cputype)) {
20  return false;
21  }
22  if (cputype != CPU_TYPE_ARM64) {
23  return false;
24  }
25  ut32 filetype;
26  if (!rz_buf_read_le32_at(b, 12, &filetype)) {
27  return false;
28  }
29  if (filetype == MH_FILESET) {
30  return true;
31  }
32  ut32 flags;
33  if (!rz_buf_read_le32_at(b, 24, &flags)) {
34  return false;
35  }
36  if (!(flags & MH_PIE)) {
37  return false;
38  }
39  ut32 ncmds;
40  if (!rz_buf_read_le32_at(b, 16, &ncmds)) {
41  return false;
42  }
43  bool has_unixthread = false;
44  bool has_negative_vaddr = false;
45  bool has_kext = false;
46 
47  ut32 cursor = sizeof(struct MACH0_(mach_header));
48  for (size_t i = 0; i < ncmds && cursor < length; i++) {
49 
50  ut32 cmdtype;
51  if (!rz_buf_read_le32_at(b, cursor, &cmdtype)) {
52  return false;
53  }
54 
55  ut32 cmdsize;
56  if (!rz_buf_read_le32_at(b, cursor + 4, &cmdsize)) {
57  return false;
58  }
59 
60  switch (cmdtype) {
61  case LC_KEXT:
62  has_kext = true;
63  break;
64  case LC_UNIXTHREAD:
65  has_unixthread = true;
66  break;
67  case LC_LOAD_DYLIB:
68  case LC_LOAD_WEAK_DYLIB:
69  case LC_LAZY_LOAD_DYLIB:
70  return false;
71  case LC_SEGMENT_64: {
72  if (has_negative_vaddr) {
73  break;
74  }
75  ut64 tmp;
76  if (!rz_buf_read_le64_at(b, cursor + 24, &tmp)) {
77  return false;
78  }
79 
80  st64 vmaddr = convert_to_two_complement_64(tmp);
81  if (vmaddr < 0) {
82  has_negative_vaddr = true;
83  }
84  } break;
85  }
86 
87  cursor += cmdsize;
88  }
89 
90  return has_kext || (has_unixthread && has_negative_vaddr);
91 }
lzma_index ** i
Definition: index.h:629
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
uint32_t ut32
@ LC_KEXT
@ LC_LOAD_WEAK_DYLIB
@ LC_UNIXTHREAD
@ LC_LOAD_DYLIB
@ LC_LAZY_LOAD_DYLIB
@ LC_SEGMENT_64
@ MH_FILESET
Definition: mach0_defines.h:83
@ MH_PIE
@ CPU_TYPE_ARM64
#define MACH0_(name)
Definition: mach0_specs.h:20
#define rz_buf_read_le32_at(b, addr, result)
Definition: rz_buf.h:271
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
#define rz_buf_read_le64_at(b, addr, result)
Definition: rz_buf.h:272
#define st64
Definition: rz_types_base.h:10
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define b(i)
Definition: sha256.c:42
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
filetype
Definition: z80asm.h:78

References b, CPU_TYPE_ARM64, flags, i, LC_KEXT, LC_LAZY_LOAD_DYLIB, LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, LC_SEGMENT_64, LC_UNIXTHREAD, length, MACH0_, MH_FILESET, MH_PIE, rz_buf_read_le32_at, rz_buf_read_le64_at, rz_buf_size(), st64, autogen_x86imm::tmp, and ut64().

Referenced by check_buffer().

◆ rz_xnu_kernelcache_needs_rebasing()

RZ_API bool rz_xnu_kernelcache_needs_rebasing ( RzXNUKernelCacheObj obj)

Definition at line 317 of file kernelcache.c.

317  {
318  return obj->rebase_info || obj->mach0->chained_starts;
319 }
RzXNUKernelCacheRebaseInfo * rebase_info
Definition: kernelcache.h:38

References rz_xnu_kernelcache_obj_t::rebase_info.

◆ rz_xnu_kernelcache_new_rebasing_buf()

RZ_API RzBuffer* rz_xnu_kernelcache_new_rebasing_buf ( RzXNUKernelCacheObj obj)

Definition at line 313 of file kernelcache.c.

313  {
314  return rz_buf_new_with_methods(&buf_methods, obj);
315 }
static const RzBufferMethods buf_methods
Definition: kernelcache.c:302
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_methods(RZ_NONNULL const RzBufferMethods *methods, void *init_user)
Creates a new buffer with a specific back end.
Definition: buf.c:525

References buf_methods, and rz_buf_new_with_methods().

◆ rz_xnu_kernelcache_parse_pointer()

RZ_API bool rz_xnu_kernelcache_parse_pointer ( RzXNUKernelCacheParsedPointer ptr,
ut64  decorated_addr,
RzXNUKernelCacheObj obj 
)

Definition at line 218 of file kernelcache.c.

218  {
219  /*
220  * Logic taken from:
221  * https://github.com/Synacktiv/kernelcache-laundering/blob/master/ios12_kernel_cache_helper.py
222  */
223 
224  if ((decorated_addr & 0x4000000000000000LL) == 0 && obj->rebase_info) {
225  if (decorated_addr & 0x8000000000000000LL) {
226  ptr->address = obj->rebase_info->kernel_base + (decorated_addr & 0xFFFFFFFFLL);
227  } else {
228  ptr->address = ((decorated_addr << 13) & 0xFF00000000000000LL) | (decorated_addr & 0x7ffffffffffLL);
229  if (decorated_addr & 0x40000000000LL) {
230  ptr->address |= 0xfffc0000000000LL;
231  }
232  }
233  } else {
234  ptr->address = decorated_addr;
235  }
236 
237  return true;
238 }

References rz_xnu_kernelcache_parsed_pointer_t::address, rz_xnu_kernelcache_rebase_info_t::kernel_base, and rz_xnu_kernelcache_obj_t::rebase_info.

Referenced by on_rebase_pointer(), and p_ptr().