Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions docs/handlers.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
| [`D-LINK FPKG`](#d-link-fpkg) | ARCHIVE | :octicons-check-16: |
| [`D-LINK SHRS`](#d-link-shrs) | ARCHIVE | :octicons-check-16: |
| [`DMG`](#dmg) | ARCHIVE | :octicons-check-16: |
| [`DYLD SHARED CACHE`](#dyld-shared-cache) | ARCHIVE | :octicons-check-16: |
| [`ELF (32-BIT)`](#elf-32-bit) | EXECUTABLE | :octicons-check-16: |
| [`ELF (64-BIT)`](#elf-64-bit) | EXECUTABLE | :octicons-check-16: |
| [`ENGENIUS`](#engenius) | ARCHIVE | :octicons-alert-fill-12: |
Expand Down Expand Up @@ -497,6 +498,22 @@
=== "References"

- [Apple Disk Image Format Documentation](http://newosxbook.com/DMG.html){ target="_blank" }
## dyld Shared Cache

!!! success "Fully supported"

=== "Description"

The dyld shared cache is a pre-linked collection of system dynamic libraries used by macOS and iOS to accelerate application launch. Modern caches are split across multiple files with suffixes such as .01, .symbols, .atlas, .dylddata, and .dyldlinkedit.

---

- **Handler type:** Archive
- **Vendor:** Apple

=== "References"

- [dyld - Apple open-source dynamic linker](https://github.com/apple-oss-distributions/dyld){ target="_blank" }
## ELF (32-bit)

!!! success "Fully supported"
Expand Down
2 changes: 2 additions & 0 deletions python/unblob/handlers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from .archive import (
zip as ziparchive,
)
from .archive.apple import dyld
from .archive.autel import ecc
from .archive.dlink import alpha_encimg, deafbead, encrpted_img, fpkg, shrs
from .archive.engeniustech import engenius
Expand Down Expand Up @@ -174,4 +175,5 @@
sevenzip.MultiVolumeSevenZipHandler,
gzip.MultiVolumeGzipHandler,
par2.MultiVolumePAR2Handler,
dyld.MultifileDyldCacheHandler,
)
Empty file.
68 changes: 68 additions & 0 deletions python/unblob/handlers/archive/apple/dyld.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from pathlib import Path

from structlog import get_logger

from unblob.models import (
DirectoryHandler,
Glob,
HandlerDoc,
HandlerType,
MultiFile,
Reference,
)

logger = get_logger()

_MAGIC_PREFIX = b"dyld_v1 "


class MultifileDyldCacheHandler(DirectoryHandler):
NAME = "multifile_dyld_cache"

EXTRACTOR = None
PATTERN = Glob("dyld_shared_cache_*")

DOC = HandlerDoc(
name="dyld Shared Cache",
description="The dyld shared cache is a pre-linked collection of system dynamic libraries used by macOS and iOS to accelerate application launch. Modern caches are split across multiple files with suffixes such as .01, .symbols, .atlas, .dylddata, and .dyldlinkedit.",
handler_type=HandlerType.ARCHIVE,
vendor="Apple",
references=[
Reference(
title="dyld - Apple open-source dynamic linker",
url="https://github.com/apple-oss-distributions/dyld",
),
],
limitations=[],
)

def calculate_multifile(self, file: Path) -> MultiFile | None:
if file.suffix:
return None

try:
with file.open("rb") as f:
if not f.read(len(_MAGIC_PREFIX)).startswith(_MAGIC_PREFIX):
return None
except (IsADirectoryError, PermissionError, FileNotFoundError):
return None

siblings = sorted(
[
p
for p in file.parent.iterdir()
if p.name.startswith(file.stem)
and p.name != file.name
and ":" not in p.name
],
key=lambda p: (len(p.name), p.name),
)

if not siblings:
return None

logger.info(
"creating unified dyld cache view", main=file.name, parts=len(siblings) + 1
)

return MultiFile(name=f"{file.stem}.unified", paths=[file, *siblings])
Loading