使用 PAR::Packer 编译的 Perl 脚本在 Mac 中的代码签名失败

Code signing in Mac with Perl scripts compiled with PAR::Packer fails

有没有人有将已编译的 Perl 二进制文件用于代码登录 OSX 的经验?尝试在 PAR 中编译 Perl 脚本时,returns 当我尝试对其进行代码签名时出现错误。我通过不尝试将其代码签名为二进制文件(例如,在 .app 中的 "Resources" 文件夹内)来解决此错误,但如果我将其放在正确的 MacOS 目录中,则签名失败。

我已经看到许多针对 python 脚本 (https://github.com/kamillus/py2app-pyqt-codesign-fix-os-x) 的修复,但没有任何针对 Perl 的修复!

codesign -s报错信息为"main executable failed strict validation"。我也尝试了 --deep 选项但没有成功。

我已经找到解决方法了。这是我根据此处编写的 Python 解决方案改编的解决方案:

https://github.com/pyinstaller/pyinstaller/wiki/Recipe-OSX-Code-Signing

这是 Mach-O headers 引起的问题。希望这对其他人有帮助。 运行在 PAR 可执行文件上安装此 python 脚本后,它将进行代码签名。

仍然需要对 PAR 进行一些修改才能使其达到 运行,但是,由于 PAR 在文件末尾查找 \nPAR.pm\n 签名...现在包含代码签名.我也有一个可行的解决方案,如果其他人有兴趣可以分享。

#!/usr/bin/env python

from __future__ import print_function

import os
import sys

from macholib._cmdline import main as _main
from macholib.MachO import MachO
from macholib.mach_o import *

ARCH_MAP={
    ('<', '64-bit'): 'x86_64',
    ('<', '32-bit'): 'i386',
    ('>', '64-bit'): 'ppc64',
    ('>', '32-bit'): 'ppc',
}

def print_file(fp, path):
    print(path, file=fp)
    exe_data = MachO(path)

    for header in exe_data.headers:
        seen = set()
        if header.MH_MAGIC == MH_MAGIC_64:
            sz = '64-bit'
        else:
            sz = '32-bit'

        arch = CPU_TYPE_NAMES.get(header.header.cputype,
                header.header.cputype)

        print('    [%s endian=%r size=%r arch=%r]' % (header.__class__.__name__,
                header.endian, sz, arch), file=fp)
        for idx, name, other in header.walkRelocatables():
            if other not in seen:
                seen.add(other)
                print('\t' + other, file=fp)
    print('', file=fp)

    cmds = exe_data.headers[0].commands  # '0' - Exe contains only one architecture.
    file_size = exe_data.headers[0].size

    linkedit = cmds[3][1] # __LINKEDIT
    new_segsize = file_size - linkedit.fileoff
    linkedit.filesize = new_segsize

    alignment = 4096
    linkedit.vmsize = new_segsize + (alignment - (new_segsize % alignment)) # alignment

    data = cmds[4][1] # LC_SYMTAB
    new_strsize = file_size - data.stroff
    data.strsize = new_strsize

    # Write changes back.
    fp = open(exe_data.filename, 'rb+')
    exe_data.write(fp)
    fp.close()

    print ("Successfully modified headers.\n")

def main():
    _main(print_file)

if __name__ == '__main__':
    try:
        sys.exit(main())
    except KeyboardInterrupt:
        pass