fix(macos): add MH_PIE flag + LC_DYLD_INFO_ONLY to fix SIGKILL on macOS
Root cause of 'zsh: killed' (SIGKILL) was two missing Mach-O elements: 1. Missing MH_PIE flag (0x200000): macOS 11+ (especially Apple Silicon/arm64) requires all executables to be Position Independent. The kernel kills non-PIE binaries with SIGKILL before even checking the code signature. This is why even empty.pe (no externals) was killed. 2. Missing LC_DYLD_INFO_ONLY (0x80000022): The BIND opcodes for external symbol resolution were generated but never referenced by any load command. dyld had no way to find them, so symbols like printf were never bound. Now properly referenced via dyld_info_command. Additional changes: - Generate rebase opcodes for Abs64 fixups (required for PIE: dyld adds ASLR slide to absolute addresses in .data at runtime) - Reorganize LINKEDIT layout: rebase -> bind -> symtab -> indirect -> strtab -> sig - Update ncmds from 11 to 12, sizeofcmds += 48 (dyld_info_command size) - Applied to both MachOWriter.cs (x64) and MachOWriterArm64.cs (arm64) - Workflow: add PIE/LC_DYLD_INFO_ONLY verification + time.pe run test
这个提交包含在:
@@ -106,6 +106,14 @@ jobs:
|
||||
file /tmp/hello.macos
|
||||
chmod +x /tmp/hello.macos
|
||||
|
||||
echo "=== verify PIE flag + LC_DYLD_INFO_ONLY ==="
|
||||
otool -hv /tmp/hello.macos | head -5
|
||||
otool -l /tmp/hello.macos | grep -E "LC_DYLD_INFO_ONLY|LC_CODE_SIGNATURE|LC_UUID|LC_BUILD_VERSION" || true
|
||||
|
||||
# 编译 time.pe(用户报告的被 kill 的程序)
|
||||
$PAZE tests/time.pe --target macos $ARCH_FLAG -o /tmp/time.macos 2>&1 || true
|
||||
chmod +x /tmp/time.macos 2>/dev/null || true
|
||||
|
||||
echo "=== codesign display (paze-generated) ==="
|
||||
codesign -dv --verbose=4 /tmp/hello.macos 2>&1 || true
|
||||
echo "=== codesign verify (paze-generated) ==="
|
||||
@@ -114,6 +122,9 @@ jobs:
|
||||
echo "=== try run (paze-generated signature) ==="
|
||||
/tmp/hello.macos 2>&1; echo "exit code: $?"
|
||||
|
||||
echo "=== try run time.macos ==="
|
||||
/tmp/time.macos 2>&1; echo "time exit code: $?"
|
||||
|
||||
# 对照实验:用系统 codesign -s - 重新签名,排除 paze 签名生成器的问题
|
||||
echo "=== re-sign with system codesign -s - ==="
|
||||
cp /tmp/hello.macos /tmp/hello_resigned.macos
|
||||
@@ -143,6 +154,17 @@ jobs:
|
||||
echo "=== dyld debug (hello.macos) ==="
|
||||
DYLD_PRINT_LIBRARIES=1 DYLD_PRINT_BINDINGS=1 /tmp/hello.macos 2>&1 | head -20; echo "dyld exit: $?"
|
||||
|
||||
# clang 对比测试:用 clang 编译同样逻辑的程序,对比 Mach-O 结构
|
||||
echo "=== clang reference build ==="
|
||||
echo 'int main(void){return 0;}' > /tmp/ref.c
|
||||
clang -o /tmp/ref.macos /tmp/ref.c
|
||||
file /tmp/ref.macos
|
||||
/tmp/ref.macos; echo "clang ref exit: $?"
|
||||
echo "--- clang ref otool -l (segments) ---"
|
||||
otool -l /tmp/ref.macos 2>&1 | grep -E "LC_SEGMENT|segname|vmaddr|vmsize|fileoff|filesize|cmd LC" | head -40
|
||||
echo "--- paze hello otool -l (segments) ---"
|
||||
otool -l /tmp/hello.macos 2>&1 | grep -E "LC_SEGMENT|segname|vmaddr|vmsize|fileoff|filesize|cmd LC" | head -40
|
||||
|
||||
exit 0
|
||||
|
||||
- name: Dump Mach-O load commands
|
||||
|
||||
@@ -31,6 +31,14 @@ public sealed class MachOWriter : IExecutableWriter
|
||||
private const uint LC_CODE_SIGNATURE = 0x1D;
|
||||
private const uint LC_BUILD_VERSION = 0x32;
|
||||
private const uint LC_UUID = 0x1B;
|
||||
private const uint LC_DYLD_INFO_ONLY = 0x80000022;
|
||||
private const int MH_PIE = 0x200000;
|
||||
// Rebase opcodes(dyld 对 PIE 二进制中绝对地址加 ASLR slide)
|
||||
private const byte REBASE_OPCODE_DONE = 0x00;
|
||||
private const byte REBASE_OPCODE_SET_TYPE_IMM = 0x10;
|
||||
private const byte REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB128 = 0x20;
|
||||
private const byte REBASE_OPCODE_DO_REBASE_IMM_TIMES = 0x50;
|
||||
private const int REBASE_TYPE_POINTER = 1;
|
||||
private const int VM_PROT_READ = 1, VM_PROT_WRITE = 2, VM_PROT_EXECUTE = 4;
|
||||
private const int S_NON_LAZY_SYMBOL_POINTERS = 0x06;
|
||||
// nlist n_type
|
||||
@@ -164,8 +172,9 @@ public sealed class MachOWriter : IExecutableWriter
|
||||
int lcCodeSig = 16; // linkedit_data_command(cmd+cmdsize+dataoff+datasize)
|
||||
int lcBuildVer = 24; // build_version_command(cmd+cmdsize+platform+minos+sdk+ntools)
|
||||
int lcUuid = 24; // uuid_command(cmd+cmdsize+uuid[16])
|
||||
int sizeofcmds = segTextCmd + segDataCmd + segLinkCmd + lcDylinker + lcDylib + lcMain + lcSymtab + lcDysymtab + lcCodeSig + lcBuildVer + lcUuid;
|
||||
int ncmds = 11;
|
||||
int lcDyldInfo = 48; // dyld_info_command(rebase+bind+lazy_bind+export 各 off/size)
|
||||
int sizeofcmds = segTextCmd + segDataCmd + segLinkCmd + lcDylinker + lcDylib + lcMain + lcSymtab + lcDysymtab + lcCodeSig + lcBuildVer + lcUuid + lcDyldInfo;
|
||||
int ncmds = 12;
|
||||
|
||||
int headerSize = 32;
|
||||
int textFileOff = headerSize + sizeofcmds; // __text 文件偏移
|
||||
@@ -187,22 +196,12 @@ public sealed class MachOWriter : IExecutableWriter
|
||||
long dataSegFileEnd = dataFileOff + data.Count;
|
||||
long dataSegVmEnd = bssVmaddr + bssSize;
|
||||
|
||||
// __LINKEDIT 段
|
||||
// __LINKEDIT 段(偏移在 fixup 处理后计算,因 rebase 数据需先生成)
|
||||
long linkSegFileOff = Align(dataSegFileEnd, Page);
|
||||
long linkSegVmaddr = Align(dataSegVmEnd, Page);
|
||||
|
||||
// LINKEDIT 内布局:bind, symtab, indirect, strtab —— 每个数据结构 8 字节对齐,
|
||||
// 否则 dyld 报 "mis-aligned LINKEDIT content" 并拒绝加载(SIGKILL)。
|
||||
long bindOff = linkSegFileOff;
|
||||
long symtabOff = Align(bindOff + bind.Count, 8);
|
||||
long indirectOff = Align(symtabOff + symtab.Count, 8);
|
||||
long strtabOff = Align(indirectOff + indirect.Count, 8);
|
||||
// 代码签名(ad-hoc):16 字节对齐后附加到 __LINKEDIT 末尾
|
||||
long sigOff = Align(strtabOff + strtab.Count, 16);
|
||||
int codeLimit = (int)sigOff;
|
||||
int sigBlobSize = MachOCodeSignature.ComputeBlobSize(codeLimit);
|
||||
long linkSegFileEnd = sigOff + sigBlobSize;
|
||||
long linkSegVmEnd = linkSegVmaddr + (linkSegFileEnd - linkSegFileOff);
|
||||
long rebaseOff = 0, bindOff = 0, symtabOff = 0, indirectOff = 0, strtabOff = 0, sigOff = 0;
|
||||
int codeLimit = 0, sigBlobSize = 0;
|
||||
long linkSegFileEnd = 0, linkSegVmEnd = 0;
|
||||
|
||||
// ---- 填充 main 符号 n_value ----
|
||||
long mainVmaddr = textVmaddr + mainOff;
|
||||
@@ -219,6 +218,7 @@ public sealed class MachOWriter : IExecutableWriter
|
||||
}
|
||||
|
||||
// ---- 解析 fixup ----
|
||||
var rebaseFixups = new List<(int seg, long off)>();
|
||||
foreach (var f in img.Fixups)
|
||||
{
|
||||
var list = f.Section == img.Data ? data : f.Section == img.RData ? cstring : text;
|
||||
@@ -251,9 +251,43 @@ public sealed class MachOWriter : IExecutableWriter
|
||||
{
|
||||
long target = SymVmaddr(f.Symbol, img, textVmaddr, cstringVmaddr, dataVmaddr, bssVmaddr, stubsVmaddr, externals);
|
||||
Write64At(list, f.Offset, target);
|
||||
// PIE: 记录需要 dyld rebase 的绝对地址位置(segment index + 段内偏移)
|
||||
if (f.Section == img.Data)
|
||||
rebaseFixups.Add((1, got.Count + f.Offset)); // __DATA seg
|
||||
else if (f.Section == img.Text)
|
||||
rebaseFixups.Add((0, textFileOff + f.Offset)); // __TEXT seg
|
||||
else if (f.Section == img.RData)
|
||||
rebaseFixups.Add((0, textFileOff + text.Count + f.Offset)); // __TEXT seg (__cstring)
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 生成 rebase opcodes(PIE: dyld 对绝对地址加 ASLR slide)----
|
||||
var rebase = new List<byte>();
|
||||
if (rebaseFixups.Count > 0)
|
||||
{
|
||||
rebaseFixups.Sort((a, b) => a.seg == b.seg ? a.off.CompareTo(b.off) : a.seg.CompareTo(b.seg));
|
||||
rebase.Add((byte)(REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER));
|
||||
foreach (var (seg, off) in rebaseFixups)
|
||||
{
|
||||
rebase.Add((byte)(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB128 | seg));
|
||||
WriteUleb128(rebase, (ulong)off);
|
||||
rebase.Add((byte)(REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1));
|
||||
}
|
||||
rebase.Add(REBASE_OPCODE_DONE);
|
||||
}
|
||||
|
||||
// ---- LINKEDIT 内布局:rebase, bind, symtab, indirect, strtab, sig ----
|
||||
rebaseOff = rebase.Count > 0 ? linkSegFileOff : 0;
|
||||
bindOff = rebase.Count > 0 ? Align(rebaseOff + rebase.Count, 8) : linkSegFileOff;
|
||||
symtabOff = Align(bindOff + bind.Count, 8);
|
||||
indirectOff = Align(symtabOff + symtab.Count, 8);
|
||||
strtabOff = Align(indirectOff + indirect.Count, 8);
|
||||
sigOff = Align(strtabOff + strtab.Count, 16);
|
||||
codeLimit = (int)sigOff;
|
||||
sigBlobSize = MachOCodeSignature.ComputeBlobSize(codeLimit);
|
||||
linkSegFileEnd = sigOff + sigBlobSize;
|
||||
linkSegVmEnd = linkSegVmaddr + (linkSegFileEnd - linkSegFileOff);
|
||||
|
||||
// ============ 装配 Mach-O ============
|
||||
var f2 = new List<byte>();
|
||||
|
||||
@@ -264,7 +298,7 @@ public sealed class MachOWriter : IExecutableWriter
|
||||
Write32At(f2, (uint)MH_EXECUTE);
|
||||
Write32At(f2, (uint)ncmds);
|
||||
Write32At(f2, (uint)sizeofcmds);
|
||||
Write32At(f2, 0); // flags(非 PIE)
|
||||
Write32At(f2, (uint)MH_PIE); // flags = MH_PIE(macOS 11+ arm64 强制要求 PIE,x64 也推荐)
|
||||
Write32At(f2, 0); // reserved
|
||||
|
||||
// ---- LC_SEGMENT_64 __TEXT ----
|
||||
@@ -289,6 +323,18 @@ public sealed class MachOWriter : IExecutableWriter
|
||||
WriteSegment64(f2, "__LINKEDIT", linkSegVmaddr, linkSegVmEnd - linkSegVmaddr,
|
||||
linkSegFileOff, linkSegFileEnd - linkSegFileOff, VM_PROT_READ, VM_PROT_READ, 0);
|
||||
|
||||
// ---- LC_DYLD_INFO_ONLY ----(rebase/bind 信息,dyld 通过此命令处理符号绑定和 PIE 地址修正)
|
||||
Write32At(f2, LC_DYLD_INFO_ONLY);
|
||||
Write32At(f2, 48); // cmdsize (dyld_info_command)
|
||||
Write32At(f2, (uint)(rebase.Count > 0 ? rebaseOff : 0)); // rebase_off
|
||||
Write32At(f2, (uint)rebase.Count); // rebase_size
|
||||
Write32At(f2, (uint)bindOff); // bind_off
|
||||
Write32At(f2, (uint)bind.Count); // bind_size
|
||||
Write32At(f2, 0); // lazy_bind_off(非懒绑定,无 lazy stub)
|
||||
Write32At(f2, 0); // lazy_bind_size
|
||||
Write32At(f2, 0); // export_off(主可执行文件无需导出符号)
|
||||
Write32At(f2, 0); // export_size
|
||||
|
||||
// ---- LC_LOAD_DYLINKER ----
|
||||
Write32At(f2, LC_LOAD_DYLINKER);
|
||||
Write32At(f2, (uint)lcDylinker);
|
||||
@@ -370,6 +416,11 @@ public sealed class MachOWriter : IExecutableWriter
|
||||
|
||||
// ---- __LINKEDIT 段数据 ----(各子表之间 8 字节对齐填充)
|
||||
while (f2.Count < linkSegFileOff) f2.Add(0);
|
||||
if (rebase.Count > 0)
|
||||
{
|
||||
f2.AddRange(rebase);
|
||||
while (f2.Count < bindOff) f2.Add(0);
|
||||
}
|
||||
f2.AddRange(bind);
|
||||
while (f2.Count < symtabOff) f2.Add(0);
|
||||
f2.AddRange(symtab);
|
||||
|
||||
@@ -34,6 +34,14 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
||||
private const uint LC_CODE_SIGNATURE = 0x1D;
|
||||
private const uint LC_BUILD_VERSION = 0x32;
|
||||
private const uint LC_UUID = 0x1B;
|
||||
private const uint LC_DYLD_INFO_ONLY = 0x80000022;
|
||||
private const int MH_PIE = 0x200000;
|
||||
// Rebase opcodes(dyld 对 PIE 二进制中绝对地址加 ASLR slide)
|
||||
private const byte REBASE_OPCODE_DONE = 0x00;
|
||||
private const byte REBASE_OPCODE_SET_TYPE_IMM = 0x10;
|
||||
private const byte REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB128 = 0x20;
|
||||
private const byte REBASE_OPCODE_DO_REBASE_IMM_TIMES = 0x50;
|
||||
private const int REBASE_TYPE_POINTER = 1;
|
||||
private const int VM_PROT_READ = 1, VM_PROT_WRITE = 2, VM_PROT_EXECUTE = 4;
|
||||
private const int S_NON_LAZY_SYMBOL_POINTERS = 0x06;
|
||||
private const byte N_EXT = 0x01, N_SECT = 0x0e;
|
||||
@@ -143,8 +151,9 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
||||
int lcCodeSig = 16; // linkedit_data_command(cmd+cmdsize+dataoff+datasize)
|
||||
int lcBuildVer = 24; // build_version_command(cmd+cmdsize+platform+minos+sdk+ntools)
|
||||
int lcUuid = 24; // uuid_command(cmd+cmdsize+uuid[16])
|
||||
int sizeofcmds = segTextCmd + segDataCmd + segLinkCmd + lcDylinker + lcDylib + lcMain + lcSymtab + lcDysymtab + lcCodeSig + lcBuildVer + lcUuid;
|
||||
int ncmds = 11;
|
||||
int lcDyldInfo = 48; // dyld_info_command(rebase+bind+lazy_bind+export 各 off/size)
|
||||
int sizeofcmds = segTextCmd + segDataCmd + segLinkCmd + lcDylinker + lcDylib + lcMain + lcSymtab + lcDysymtab + lcCodeSig + lcBuildVer + lcUuid + lcDyldInfo;
|
||||
int ncmds = 12;
|
||||
|
||||
int headerSize = 32;
|
||||
int textFileOff = headerSize + sizeofcmds;
|
||||
@@ -166,22 +175,12 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
||||
long dataSegFileEnd = dataFileOff + data.Count;
|
||||
long dataSegVmEnd = bssVmaddr + bssSize;
|
||||
|
||||
// __LINKEDIT 段
|
||||
// __LINKEDIT 段(偏移在 fixup 处理后计算,因 rebase 数据需先生成)
|
||||
long linkSegFileOff = Align(dataSegFileEnd, Page);
|
||||
long linkSegVmaddr = Align(dataSegVmEnd, Page);
|
||||
|
||||
// LINKEDIT 内布局:bind, symtab, indirect, strtab —— 每个数据结构 8 字节对齐,
|
||||
// 否则 dyld 报 "mis-aligned LINKEDIT content" 并拒绝加载(SIGKILL)。
|
||||
long bindOff = linkSegFileOff;
|
||||
long symtabOff = Align(bindOff + bind.Count, 8);
|
||||
long indirectOff = Align(symtabOff + symtab.Count, 8);
|
||||
long strtabOff = Align(indirectOff + indirect.Count, 8);
|
||||
// 代码签名(ad-hoc):16 字节对齐后附加到 __LINKEDIT 末尾
|
||||
long sigOff = Align(strtabOff + strtab.Count, 16);
|
||||
int codeLimit = (int)sigOff;
|
||||
int sigBlobSize = MachOCodeSignature.ComputeBlobSize(codeLimit);
|
||||
long linkSegFileEnd = sigOff + sigBlobSize;
|
||||
long linkSegVmEnd = linkSegVmaddr + (linkSegFileEnd - linkSegFileOff);
|
||||
long rebaseOff = 0, bindOff = 0, symtabOff = 0, indirectOff = 0, strtabOff = 0, sigOff = 0;
|
||||
int codeLimit = 0, sigBlobSize = 0;
|
||||
long linkSegFileEnd = 0, linkSegVmEnd = 0;
|
||||
|
||||
// ---- 填充 main 符号 n_value ----
|
||||
long mainVmaddr = textVmaddr + mainOff;
|
||||
@@ -205,6 +204,7 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
||||
}
|
||||
|
||||
// ---- 解析 fixup ----
|
||||
var rebaseFixups = new List<(int seg, long off)>();
|
||||
foreach (var f in img.Fixups)
|
||||
{
|
||||
var list = f.Section == img.Data ? data : f.Section == img.RData ? cstring : text;
|
||||
@@ -250,9 +250,43 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
||||
{
|
||||
long target = SymVmaddr(f.Symbol, img, textVmaddr, cstringVmaddr, dataVmaddr, bssVmaddr, stubsVmaddr, externals);
|
||||
Write64At(list, f.Offset, target);
|
||||
// PIE: 记录需要 dyld rebase 的绝对地址位置(segment index + 段内偏移)
|
||||
if (f.Section == img.Data)
|
||||
rebaseFixups.Add((1, got.Count + f.Offset)); // __DATA seg
|
||||
else if (f.Section == img.Text)
|
||||
rebaseFixups.Add((0, textFileOff + f.Offset)); // __TEXT seg
|
||||
else if (f.Section == img.RData)
|
||||
rebaseFixups.Add((0, textFileOff + text.Count + f.Offset)); // __TEXT seg (__cstring)
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 生成 rebase opcodes(PIE: dyld 对绝对地址加 ASLR slide)----
|
||||
var rebase = new List<byte>();
|
||||
if (rebaseFixups.Count > 0)
|
||||
{
|
||||
rebaseFixups.Sort((a, b) => a.seg == b.seg ? a.off.CompareTo(b.off) : a.seg.CompareTo(b.seg));
|
||||
rebase.Add((byte)(REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER));
|
||||
foreach (var (seg, off) in rebaseFixups)
|
||||
{
|
||||
rebase.Add((byte)(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB128 | seg));
|
||||
WriteUleb128(rebase, (ulong)off);
|
||||
rebase.Add((byte)(REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1));
|
||||
}
|
||||
rebase.Add(REBASE_OPCODE_DONE);
|
||||
}
|
||||
|
||||
// ---- LINKEDIT 内布局:rebase, bind, symtab, indirect, strtab, sig ----
|
||||
rebaseOff = rebase.Count > 0 ? linkSegFileOff : 0;
|
||||
bindOff = rebase.Count > 0 ? Align(rebaseOff + rebase.Count, 8) : linkSegFileOff;
|
||||
symtabOff = Align(bindOff + bind.Count, 8);
|
||||
indirectOff = Align(symtabOff + symtab.Count, 8);
|
||||
strtabOff = Align(indirectOff + indirect.Count, 8);
|
||||
sigOff = Align(strtabOff + strtab.Count, 16);
|
||||
codeLimit = (int)sigOff;
|
||||
sigBlobSize = MachOCodeSignature.ComputeBlobSize(codeLimit);
|
||||
linkSegFileEnd = sigOff + sigBlobSize;
|
||||
linkSegVmEnd = linkSegVmaddr + (linkSegFileEnd - linkSegFileOff);
|
||||
|
||||
// ============ 装配 Mach-O ============
|
||||
var f2 = new List<byte>();
|
||||
|
||||
@@ -263,7 +297,7 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
||||
Write32At(f2, (uint)MH_EXECUTE);
|
||||
Write32At(f2, (uint)ncmds);
|
||||
Write32At(f2, (uint)sizeofcmds);
|
||||
Write32At(f2, 0); // flags(非 PIE)
|
||||
Write32At(f2, (uint)MH_PIE); // flags = MH_PIE(macOS 11+ arm64 强制要求 PIE)
|
||||
Write32At(f2, 0); // reserved
|
||||
|
||||
// ---- LC_SEGMENT_64 __TEXT ----
|
||||
@@ -287,6 +321,18 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
||||
WriteSegment64(f2, "__LINKEDIT", linkSegVmaddr, linkSegVmEnd - linkSegVmaddr,
|
||||
linkSegFileOff, linkSegFileEnd - linkSegFileOff, VM_PROT_READ, VM_PROT_READ, 0);
|
||||
|
||||
// ---- LC_DYLD_INFO_ONLY ----(rebase/bind 信息,dyld 通过此命令处理符号绑定和 PIE 地址修正)
|
||||
Write32At(f2, LC_DYLD_INFO_ONLY);
|
||||
Write32At(f2, 48); // cmdsize (dyld_info_command)
|
||||
Write32At(f2, (uint)(rebase.Count > 0 ? rebaseOff : 0)); // rebase_off
|
||||
Write32At(f2, (uint)rebase.Count); // rebase_size
|
||||
Write32At(f2, (uint)bindOff); // bind_off
|
||||
Write32At(f2, (uint)bind.Count); // bind_size
|
||||
Write32At(f2, 0); // lazy_bind_off(非懒绑定,无 lazy stub)
|
||||
Write32At(f2, 0); // lazy_bind_size
|
||||
Write32At(f2, 0); // export_off(主可执行文件无需导出符号)
|
||||
Write32At(f2, 0); // export_size
|
||||
|
||||
// ---- LC_LOAD_DYLINKER ----
|
||||
Write32At(f2, LC_LOAD_DYLINKER);
|
||||
Write32At(f2, (uint)lcDylinker);
|
||||
@@ -367,6 +413,11 @@ public sealed class MachOWriterArm64 : IExecutableWriter
|
||||
|
||||
// ---- __LINKEDIT 段数据 ----(各子表之间 8 字节对齐填充)
|
||||
while (f2.Count < linkSegFileOff) f2.Add(0);
|
||||
if (rebase.Count > 0)
|
||||
{
|
||||
f2.AddRange(rebase);
|
||||
while (f2.Count < bindOff) f2.Add(0);
|
||||
}
|
||||
f2.AddRange(bind);
|
||||
while (f2.Count < symtabOff) f2.Add(0);
|
||||
f2.AddRange(symtab);
|
||||
|
||||
在新工单中引用
屏蔽一个用户