Rizin
unix-like reverse engineering framework and cli tools
dyldcache_rebase.c File Reference
#include "dyldcache.h"

Go to the source code of this file.

Classes

struct  BufCtx
 

Macros

#define RZ_IS_PTR_AUTHENTICATED(x)   B_IS_SET(x, 63)
 

Functions

static void rebase_bytes_v1 (RzDyldRebaseInfo1 *rebase_info, ut8 *buf, ut64 offset, int count, ut64 start_of_write)
 
static void rebase_bytes_v2 (RzDyldRebaseInfo2 *rebase_info, ut8 *buf, ut64 offset, int count, ut64 start_of_write)
 
static void rebase_bytes_v3 (RzDyldRebaseInfo3 *rebase_info, ut8 *buf, ut64 offset, int count, ut64 start_of_write)
 
static RzDyldRebaseInforebase_info_by_range (RzDyldRebaseInfos *infos, ut64 offset, ut64 count)
 
static void rebase_bytes (RzDyldRebaseInfo *rebase_info, ut8 *buf, ut64 offset, int count, ut64 start_of_write)
 
static bool buf_init (RzBuffer *b, const void *user)
 
static bool buf_fini (RzBuffer *b)
 
static bool buf_resize (RzBuffer *b, ut64 newsize)
 
static st64 buf_read (RzBuffer *b, ut8 *buf, ut64 len)
 
static st64 buf_write (RzBuffer *b, const ut8 *buf, ut64 len)
 
static ut64 buf_get_size (RzBuffer *b)
 
static st64 buf_seek (RzBuffer *b, st64 addr, int whence)
 
static ut8buf_get_whole_buf (RzBuffer *b, ut64 *sz)
 
RZ_API RzBufferrz_dyldcache_new_rebasing_buf (RzDyldCache *cache)
 
RZ_API bool rz_dyldcache_needs_rebasing (RzDyldCache *cache)
 
RZ_API bool rz_dyldcache_range_needs_rebasing (RzDyldCache *cache, ut64 paddr, ut64 size)
 

Variables

static const RzBufferMethods buf_methods
 

Macro Definition Documentation

◆ RZ_IS_PTR_AUTHENTICATED

#define RZ_IS_PTR_AUTHENTICATED (   x)    B_IS_SET(x, 63)

Definition at line 89 of file dyldcache_rebase.c.

Function Documentation

◆ buf_fini()

static bool buf_fini ( RzBuffer b)
static

Definition at line 191 of file dyldcache_rebase.c.

191  {
192  BufCtx *ctx = b->priv;
193  free(ctx);
194  return true;
195 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define b(i)
Definition: sha256.c:42

References b, and free().

◆ buf_get_size()

static ut64 buf_get_size ( RzBuffer b)
static

Definition at line 253 of file dyldcache_rebase.c.

253  {
254  BufCtx *ctx = b->priv;
255  return rz_buf_size(ctx->cache->buf);
256 }
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225

References b, and rz_buf_size().

◆ buf_get_whole_buf()

static ut8* buf_get_whole_buf ( RzBuffer b,
ut64 sz 
)
static

Definition at line 263 of file dyldcache_rebase.c.

263  {
264  BufCtx *ctx = b->priv;
265  return (ut8 *)rz_buf_data(ctx->cache->buf, sz);
266 }
uint8_t ut8
Definition: lh5801.h:11
RZ_DEPRECATE RZ_API RZ_BORROW ut8 * rz_buf_data(RZ_NONNULL RzBuffer *b, RZ_NONNULL RZ_OUT ut64 *size)
Return a borrowed array of bytes representing the buffer data.
Definition: buf.c:1287

References b, and rz_buf_data().

◆ buf_init()

static bool buf_init ( RzBuffer b,
const void *  user 
)
static

Definition at line 181 of file dyldcache_rebase.c.

181  {
182  BufCtx *ctx = RZ_NEW0(BufCtx);
183  if (!ctx) {
184  return false;
185  }
186  ctx->cache = (void *)user;
187  b->priv = ctx;
188  return true;
189 }
#define RZ_NEW0(x)
Definition: rz_types.h:284

References b, and RZ_NEW0.

◆ buf_read()

static st64 buf_read ( RzBuffer b,
ut8 buf,
ut64  len 
)
static

Definition at line 202 of file dyldcache_rebase.c.

202  {
203  BufCtx *ctx = b->priv;
204  st64 r = rz_buf_read_at(ctx->cache->buf, ctx->off, buf, len);
205  if (r <= 0 || !len) {
206  return r;
207  }
208 
209  RzDyldCache *cache = ctx->cache;
210  RzDyldRebaseInfo *rebase_info = rebase_info_by_range(cache->rebase_infos, ctx->off, len);
211 
212  if (!rebase_info) {
213  return rz_buf_read_at(cache->buf, ctx->off, buf, len);
214  }
215  st64 result = 0;
216  ut64 offset_in_data = ctx->off - rebase_info->start_of_data;
217  ut64 page_offset = offset_in_data % rebase_info->page_size;
218 
219  ut64 internal_offset = ctx->off & ~(rebase_info->page_size - 1);
220  ut64 internal_end = ctx->off + len;
221  int rounded_count = internal_end - internal_offset;
222 
223  ut8 *internal_buf = rebase_info->one_page_buf;
224  if (rounded_count > rebase_info->page_size) {
225  internal_buf = malloc(rounded_count);
226  if (!internal_buf) {
227  RZ_LOG_ERROR("Cannot allocate memory for 'internal_buf'\n");
228  return -1;
229  }
230  }
231 
232  st64 internal_result = rz_buf_read_at(cache->buf, internal_offset, internal_buf, rounded_count);
233  if (internal_result >= page_offset + len) {
234  rebase_bytes(rebase_info, internal_buf, internal_offset, internal_result, page_offset);
235  result = RZ_MIN(len, internal_result);
236  memcpy(buf, internal_buf + page_offset, result);
237  } else {
238  RZ_LOG_ERROR("Cannot rebase\n");
239  result = rz_buf_read_at(cache->buf, ctx->off, buf, len);
240  }
241 
242  if (internal_buf != rebase_info->one_page_buf) {
243  RZ_FREE(internal_buf);
244  }
245  return result;
246 }
size_t len
Definition: 6502dis.c:15
#define r
Definition: crypto_rc6.c:12
static RzDyldRebaseInfo * rebase_info_by_range(RzDyldRebaseInfos *infos, ut64 offset, ut64 count)
static void rebase_bytes(RzDyldRebaseInfo *rebase_info, ut8 *buf, ut64 offset, int count, ut64 start_of_write)
voidpf void * buf
Definition: ioapi.h:138
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
Definition: malloc.c:123
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_FREE(x)
Definition: rz_types.h:369
#define RZ_MIN(x, y)
#define st64
Definition: rz_types_base.h:10
RzBuffer * buf
Definition: dyldcache.h:105
RzDyldRebaseInfos * rebase_infos
Definition: dyldcache.h:106
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References b, rz_dyldcache_t::buf, len, malloc(), memcpy(), rz_dyld_rebase_info_t::one_page_buf, rz_dyld_rebase_info_t::page_size, r, rebase_bytes(), rebase_info_by_range(), rz_dyldcache_t::rebase_infos, rz_buf_read_at(), RZ_FREE, RZ_LOG_ERROR, RZ_MIN, st64, rz_dyld_rebase_info_t::start_of_data, and ut64().

Referenced by LoadCentralDirectoryRecord().

◆ buf_resize()

static bool buf_resize ( RzBuffer b,
ut64  newsize 
)
static

Definition at line 197 of file dyldcache_rebase.c.

197  {
198  BufCtx *ctx = b->priv;
199  return rz_buf_resize(ctx->cache->buf, newsize);
200 }
RZ_API bool rz_buf_resize(RZ_NONNULL RzBuffer *b, ut64 newsize)
Resize the buffer size.
Definition: buf.c:890

References b, and rz_buf_resize().

◆ buf_seek()

static st64 buf_seek ( RzBuffer b,
st64  addr,
int  whence 
)
static

Definition at line 258 of file dyldcache_rebase.c.

258  {
259  BufCtx *ctx = b->priv;
260  return ctx->off = rz_seek_offset(ctx->off, rz_buf_size(b), addr, whence);
261 }
static ut64 rz_seek_offset(ut64 cur, ut64 length, st64 addr, int whence)
change cur according to addr and whence (RZ_BUF_SET/RZ_BUF_CUR/RZ_BUF_END)
Definition: rz_buf.h:67
static int addr
Definition: z80asm.c:58

References addr, b, rz_buf_size(), and rz_seek_offset().

◆ buf_write()

static st64 buf_write ( RzBuffer b,
const ut8 buf,
ut64  len 
)
static

Definition at line 248 of file dyldcache_rebase.c.

248  {
249  BufCtx *ctx = b->priv;
250  return rz_buf_write_at(ctx->cache->buf, ctx->off, buf, len);
251 }
RZ_API st64 rz_buf_write_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL const ut8 *buf, ut64 len)
Write len bytes of the buffer at the specified address.
Definition: buf.c:1197

References b, len, and rz_buf_write_at().

◆ rebase_bytes()

static void rebase_bytes ( RzDyldRebaseInfo rebase_info,
ut8 buf,
ut64  offset,
int  count,
ut64  start_of_write 
)
static

Definition at line 162 of file dyldcache_rebase.c.

162  {
163  if (!rebase_info || !buf) {
164  return;
165  }
166 
167  if (rebase_info->version == 3) {
168  rebase_bytes_v3((RzDyldRebaseInfo3 *)rebase_info, buf, offset, count, start_of_write);
169  } else if (rebase_info->version == 2 || rebase_info->version == 4) {
170  rebase_bytes_v2((RzDyldRebaseInfo2 *)rebase_info, buf, offset, count, start_of_write);
171  } else if (rebase_info->version == 1) {
172  rebase_bytes_v1((RzDyldRebaseInfo1 *)rebase_info, buf, offset, count, start_of_write);
173  }
174 }
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 count
Definition: sflib.h:98
static void rebase_bytes_v1(RzDyldRebaseInfo1 *rebase_info, ut8 *buf, ut64 offset, int count, ut64 start_of_write)
static void rebase_bytes_v2(RzDyldRebaseInfo2 *rebase_info, ut8 *buf, ut64 offset, int count, ut64 start_of_write)
static void rebase_bytes_v3(RzDyldRebaseInfo3 *rebase_info, ut8 *buf, ut64 offset, int count, ut64 start_of_write)
voidpf uLong offset
Definition: ioapi.h:144

References count, rebase_bytes_v1(), rebase_bytes_v2(), rebase_bytes_v3(), and rz_dyld_rebase_info_t::version.

Referenced by buf_read().

◆ rebase_bytes_v1()

static void rebase_bytes_v1 ( RzDyldRebaseInfo1 rebase_info,
ut8 buf,
ut64  offset,
int  count,
ut64  start_of_write 
)
static

Definition at line 7 of file dyldcache_rebase.c.

7  {
8  int in_buf = 0;
9  while (in_buf < count) {
10  ut64 offset_in_data = offset - rebase_info->start_of_data;
11  ut64 page_index = offset_in_data / rebase_info->page_size;
12  ut64 page_offset = offset_in_data % rebase_info->page_size;
13  ut64 to_next_page = rebase_info->page_size - page_offset;
14  ut64 entry_index = page_offset / 32;
15  ut64 offset_in_entry = (page_offset % 32) / 4;
16 
17  if (entry_index >= rebase_info->entries_size) {
18  in_buf += to_next_page;
19  offset += to_next_page;
20  continue;
21  }
22 
23  if (page_index >= rebase_info->toc_count) {
24  break;
25  }
26 
27  ut8 *entry = &rebase_info->entries[rebase_info->toc[page_index] * rebase_info->entries_size];
28  ut8 b = entry[entry_index];
29 
30  if (b & (1 << offset_in_entry)) {
32  value += rebase_info->slide;
34  in_buf += 8;
35  offset += 8;
36  } else {
37  in_buf += 4;
38  offset += 4;
39  }
40  }
41 }
static int value
Definition: cmd_api.c:93
static io_buf in_buf
Input and output buffers.
Definition: coder.c:39
static const char * page_index
Definition: rz-agent.c:8
static ut64 rz_read_le64(const void *src)
Definition: rz_endian.h:266
static void rz_write_le64(void *dest, ut64 val)
Definition: rz_endian.h:277
Definition: zipcmp.c:77

References b, count, rz_dyld_rebase_info_1_t::entries, rz_dyld_rebase_info_1_t::entries_size, in_buf, page_index, rz_dyld_rebase_info_1_t::page_size, rz_read_le64(), rz_write_le64(), rz_dyld_rebase_info_1_t::slide, rz_dyld_rebase_info_1_t::start_of_data, rz_dyld_rebase_info_1_t::toc, rz_dyld_rebase_info_1_t::toc_count, ut64(), and value.

Referenced by rebase_bytes().

◆ rebase_bytes_v2()

static void rebase_bytes_v2 ( RzDyldRebaseInfo2 rebase_info,
ut8 buf,
ut64  offset,
int  count,
ut64  start_of_write 
)
static

Definition at line 43 of file dyldcache_rebase.c.

43  {
44  int in_buf = 0;
45  while (in_buf < count) {
46  ut64 offset_in_data = offset - rebase_info->start_of_data;
47  ut64 page_index = offset_in_data / rebase_info->page_size;
48  ut64 page_offset = offset_in_data % rebase_info->page_size;
49  ut64 to_next_page = rebase_info->page_size - page_offset;
50 
51  if (page_index >= rebase_info->page_starts_count) {
52  goto next_page;
53  }
54  ut16 page_flag = rebase_info->page_starts[page_index];
55 
56  if (page_flag == DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE) {
57  goto next_page;
58  }
59 
60  if (!(page_flag & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA)) {
61  ut64 first_rebase_off = rebase_info->page_starts[page_index] * 4;
62  if (first_rebase_off >= page_offset && first_rebase_off < page_offset + count) {
63  ut32 delta = 1;
64  while (delta) {
65  ut64 position = in_buf + first_rebase_off - page_offset;
66  if (position >= count) {
67  break;
68  }
69  ut64 raw_value = rz_read_le64(buf + position);
70  delta = ((raw_value & rebase_info->delta_mask) >> rebase_info->delta_shift);
71  if (position >= start_of_write) {
72  ut64 new_value = raw_value & rebase_info->value_mask;
73  if (new_value != 0) {
74  new_value += rebase_info->value_add;
75  new_value += rebase_info->slide;
76  }
77  rz_write_le64(buf + position, new_value);
78  }
79  first_rebase_off += delta;
80  }
81  }
82  }
83  next_page:
84  in_buf += to_next_page;
85  offset += to_next_page;
86  }
87 }
uint16_t ut16
uint32_t ut32
#define DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE
Definition: mach0_specs.h:351
#define DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA
Definition: mach0_specs.h:350
static st64 delta
Definition: vmenus.c:2425

References count, delta, rz_dyld_rebase_info_2_t::delta_mask, rz_dyld_rebase_info_2_t::delta_shift, DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA, DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE, in_buf, page_index, rz_dyld_rebase_info_2_t::page_size, rz_dyld_rebase_info_2_t::page_starts, rz_dyld_rebase_info_2_t::page_starts_count, rz_read_le64(), rz_write_le64(), rz_dyld_rebase_info_2_t::slide, rz_dyld_rebase_info_2_t::start_of_data, ut64(), rz_dyld_rebase_info_2_t::value_add, and rz_dyld_rebase_info_2_t::value_mask.

Referenced by rebase_bytes().

◆ rebase_bytes_v3()

static void rebase_bytes_v3 ( RzDyldRebaseInfo3 rebase_info,
ut8 buf,
ut64  offset,
int  count,
ut64  start_of_write 
)
static

Definition at line 91 of file dyldcache_rebase.c.

91  {
92  int in_buf = 0;
93  while (in_buf < count) {
94  ut64 offset_in_data = offset - rebase_info->start_of_data;
95  ut64 page_index = offset_in_data / rebase_info->page_size;
96  ut64 page_offset = offset_in_data % rebase_info->page_size;
97  ut64 to_next_page = rebase_info->page_size - page_offset;
98 
99  if (page_index >= rebase_info->page_starts_count) {
100  goto next_page;
101  }
102  ut64 delta = rebase_info->page_starts[page_index];
103 
105  goto next_page;
106  }
107 
108  ut64 first_rebase_off = delta;
109  if (first_rebase_off >= page_offset && first_rebase_off < page_offset + count) {
110  do {
111  ut64 position = in_buf + first_rebase_off - page_offset;
112  if (position >= count) {
113  break;
114  }
115  ut64 raw_value = rz_read_le64(buf + position);
116  delta = ((raw_value & rebase_info->delta_mask) >> rebase_info->delta_shift) * 8;
117  if (position >= start_of_write) {
118  ut64 new_value = 0;
119  if (RZ_IS_PTR_AUTHENTICATED(raw_value)) {
120  new_value = (raw_value & 0xFFFFFFFFULL) + rebase_info->auth_value_add;
121  // TODO: don't throw auth info away
122  } else {
123  new_value = ((raw_value << 13) & 0xFF00000000000000ULL) | (raw_value & 0x7ffffffffffULL);
124  new_value &= 0x00FFFFFFFFFFFFFFULL;
125  }
126  if (new_value != 0) {
127  new_value += rebase_info->slide;
128  }
129  rz_write_le64(buf + position, new_value);
130  }
131  first_rebase_off += delta;
132  } while (delta);
133  }
134  next_page:
135  in_buf += to_next_page;
136  offset += to_next_page;
137  }
138 }
#define RZ_IS_PTR_AUTHENTICATED(x)
#define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE
Definition: mach0_specs.h:353

References rz_dyld_rebase_info_3_t::auth_value_add, count, delta, rz_dyld_rebase_info_3_t::delta_mask, rz_dyld_rebase_info_3_t::delta_shift, DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE, in_buf, page_index, rz_dyld_rebase_info_3_t::page_size, rz_dyld_rebase_info_3_t::page_starts, rz_dyld_rebase_info_3_t::page_starts_count, RZ_IS_PTR_AUTHENTICATED, rz_read_le64(), rz_write_le64(), rz_dyld_rebase_info_3_t::slide, rz_dyld_rebase_info_3_t::start_of_data, and ut64().

Referenced by rebase_bytes().

◆ rebase_info_by_range()

static RzDyldRebaseInfo* rebase_info_by_range ( RzDyldRebaseInfos infos,
ut64  offset,
ut64  count 
)
static

Definition at line 140 of file dyldcache_rebase.c.

140  {
141  int imid;
142  int imin = 0;
143  int imax = infos->length - 1;
144 
145  while (imin < imax) {
146  imid = (imin + imax) / 2;
147  RzDyldRebaseInfosEntry *entry = &infos->entries[imid];
148  if ((entry->end) <= offset) {
149  imin = imid + 1;
150  } else {
151  imax = imid;
152  }
153  }
154 
155  RzDyldRebaseInfosEntry *minEntry = &infos->entries[imin];
156  if ((imax == imin) && (minEntry->start <= offset + count) && (minEntry->end >= offset)) {
157  return minEntry->info;
158  }
159  return NULL;
160 }
#define NULL
Definition: cris-opc.c:27
Definition: dyldcache.h:23
ut64 start
Definition: dyldcache.h:24
RzDyldRebaseInfo * info
Definition: dyldcache.h:26
ut64 end
Definition: dyldcache.h:25
RzDyldRebaseInfosEntry * entries
Definition: dyldcache.h:30

References count, rz_dyld_rebase_infos_entry_t::end, rz_dyld_rebase_infos_t::entries, rz_dyld_rebase_infos_entry_t::info, rz_dyld_rebase_infos_t::length, NULL, and rz_dyld_rebase_infos_entry_t::start.

Referenced by buf_read(), and rz_dyldcache_range_needs_rebasing().

◆ rz_dyldcache_needs_rebasing()

RZ_API bool rz_dyldcache_needs_rebasing ( RzDyldCache cache)

Definition at line 284 of file dyldcache_rebase.c.

284  {
285  rz_return_val_if_fail(cache, false);
286  if (cache->rebase_infos) {
287  if (!rz_dyldcache_get_slide(cache)) {
288  return true;
289  }
290  }
291  return false;
292 }
RZ_API ut64 rz_dyldcache_get_slide(RzDyldCache *cache)
Definition: dyldcache.c:1097
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108

References rz_dyldcache_t::rebase_infos, rz_dyldcache_get_slide(), and rz_return_val_if_fail.

Referenced by classes(), rz_dyldcache_range_needs_rebasing(), and virtual_files().

◆ rz_dyldcache_new_rebasing_buf()

RZ_API RzBuffer* rz_dyldcache_new_rebasing_buf ( RzDyldCache cache)

Definition at line 279 of file dyldcache_rebase.c.

279  {
280  rz_return_val_if_fail(cache, NULL);
281  return rz_buf_new_with_methods(&buf_methods, cache);
282 }
static const RzBufferMethods buf_methods
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, NULL, rz_buf_new_with_methods(), and rz_return_val_if_fail.

Referenced by classes(), and virtual_files().

◆ rz_dyldcache_range_needs_rebasing()

RZ_API bool rz_dyldcache_range_needs_rebasing ( RzDyldCache cache,
ut64  paddr,
ut64  size 
)

Definition at line 294 of file dyldcache_rebase.c.

294  {
295  rz_return_val_if_fail(cache, false);
296  if (!rz_dyldcache_needs_rebasing(cache)) {
297  return false;
298  }
299  return !!rebase_info_by_range(cache->rebase_infos, paddr, size);
300 }
RZ_API bool rz_dyldcache_needs_rebasing(RzDyldCache *cache)
voidpf void uLong size
Definition: ioapi.h:138

References rebase_info_by_range(), rz_dyldcache_t::rebase_infos, rz_dyldcache_needs_rebasing(), and rz_return_val_if_fail.

Referenced by maps().

Variable Documentation

◆ buf_methods

const RzBufferMethods buf_methods
static
Initial value:
= {
.init = buf_init,
.fini = buf_fini,
.read = buf_read,
.write = buf_write,
.get_size = buf_get_size,
.resize = buf_resize,
.seek = buf_seek,
.get_whole_buf = buf_get_whole_buf
}
static ut8 * buf_get_whole_buf(RzBuffer *b, ut64 *sz)
static ut64 buf_get_size(RzBuffer *b)
static st64 buf_seek(RzBuffer *b, st64 addr, int whence)
static st64 buf_write(RzBuffer *b, const ut8 *buf, ut64 len)
static st64 buf_read(RzBuffer *b, ut8 *buf, ut64 len)
static bool buf_fini(RzBuffer *b)
static bool buf_resize(RzBuffer *b, ut64 newsize)
static bool buf_init(RzBuffer *b, const void *user)

Definition at line 268 of file dyldcache_rebase.c.

Referenced by rz_dyldcache_new_rebasing_buf().