llvm-objcopy for MachO does not update ENCRYPTION_INFO load command
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Objcopy removes gaps from the physical representation between segments.
ENCRYPTION_INFO load command matches physical representation of segment, but does not get updated correspondingly.
End result on manipulated binary:
```
objdump --headers Runner2
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump: error: 'Runner2': truncated or malformed object (cryptoff field plus cryptsize field of LC_ENCRYPTION_INFO_64 command 14 extends past the end of the file)
```
repro.yaml:
```
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x100000C
cpusubtype: 0x0
filetype: 0x2
ncmds: 11
sizeofcmds: 640
flags: 0x200085
reserved: 0x0
LoadCommands:
- cmd: LC_ENCRYPTION_INFO_64
cmdsize: 24
cryptoff: 16384
cryptsize: 4145152
cryptid: 0
pad: 0
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __PAGEZERO
vmaddr: 0
vmsize: 4294967296
fileoff: 0
filesize: 0
maxprot: 0
initprot: 0
nsects: 0
flags: 0
- cmd: LC_SEGMENT_64
cmdsize: 152
segname: __TEXT
vmaddr: 4294967296
vmsize: 4161536
fileoff: 0
filesize: 4161536
maxprot: 5
initprot: 5
nsects: 1
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x100004000
size: 36
offset: 0x4000
align: 2
reloff: 0x0
nreloc: 0
flags: 0x80000400
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: FF8300D1F44F00A9FD7B01A905000094FD7B41A9F44F40A9FF830091C0035FD6C0035FD6
- cmd: LC_SEGMENT_64
cmdsize: 152
segname: __DATA
vmaddr: 4299128832
vmsize: 16384
fileoff: 0x3F8000
filesize: 36
maxprot: 5
initprot: 5
nsects: 1
flags: 0
Sections:
- sectname: __stuf
segname: __DATA
addr: 0x1003F8000
size: 36
offset: 0x3F8000
align: 2
reloff: 0x0
nreloc: 0
flags: 0x00000000
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: FF8300D1F44F00A9FD7B01A905000094FD7B41A9F44F40A9FF830091C0035FD6C0035FD6
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __LINKEDIT
vmaddr: 4295032832
vmsize: 32768
fileoff: 4177920
filesize: 18672
maxprot: 1
initprot: 1
nsects: 0
flags: 0
- cmd: LC_UUID
cmdsize: 24
uuid: 2B57DC2F-4029-3EA3-A1B5-B0FC06927842
- cmd: LC_BUILD_VERSION
cmdsize: 32
platform: 1
minos: 983040
sdk: 983552
ntools: 1
Tools:
- tool: 3
version: 73074435
- cmd: LC_SOURCE_VERSION
cmdsize: 16
version: 0
- cmd: LC_MAIN
cmdsize: 24
entryoff: 16188
stacksize: 0
- cmd: LC_LOAD_DYLIB
cmdsize: 56
dylib:
name: 24
timestamp: 2
current_version: 87556096
compatibility_version: 65536
Content: '/usr/lib/libSystem.B.dylib'
ZeroPadBytes: 6
- cmd: LC_CODE_SIGNATURE
cmdsize: 16
dataoff: 4177920
datasize: 18672
...
```
Repro:
```
yaml2obj repro.yaml -o a.out
llvm-objdump --headers ./a.out
# success
llvm-strip ./a.out -o ./b.out
llvm-objdump: error: './b.out': truncated or malformed object (cryptoff field plus cryptsize field of LC_ENCRYPTION_INFO_64 command 0 extends past the end of the file)
```
Reproed with llvm-21.
How should encryption command look like?
It should include whole __TEXT segment physical representation, skipping header page and the __oslogstring section:
https://github.com/apple-oss-distributions/ld64/blob/1a4389663d65d6630e4b3e31ace2a86b6183b452/src/ld/OutputFile.cpp#L4210
Contributor guide
Research direction
Start with repro.yaml and run yaml2obj, llvm-strip, and llvm-objdump as shown to confirm the malformed output. Trace how llvm-strip rewrites the Mach-O segment layout and preserves LC_ENCRYPTION_INFO_64, then verify that the resulting cryptoff and cryptsize cover the intended __TEXT physical representation and that llvm-objdump accepts the output.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100