使用 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
有没有人有将已编译的 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