通过 -sectcreate __TEXT 读取链接到可执行文件的数据(嵌入式 plist)
我使用 -sectcreate __TEXT
链接器标志将可执行文件与 plist 链接。这样做的原因主要是使用了SMJobBless()方法。但我需要阅读从另一个应用程序链接的 plist。这只是因为我需要在 10.5 系统上安装相同的特权应用程序,并且无法在 10.5 上使用 SMJobBless()。
如何使用 Objective-C 读取此链接的 plist,以便我可以将其复制到 /Library/LaunchDaemons/ 自己?
I am linking a executable with a plist using -sectcreate __TEXT
linker flags. Reason for this is mainly to use the SMJobBless() method. But I need to read plist linked from another application. This is only because I need to install the same privileged application on a 10.5 system and I can’t use SMJobBless() on 10.5.
How do I read this linked plist using Objective-C so I can copy it to /Library/LaunchDaemons/ myself?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
otool
您可以使用 otool(1) 转储包含嵌入 plist 的部分的内容:
然后将其输出通过管道传输到 xxd(1) 以获得相应的 ASCII 表示形式:
但是, otool 仅在安装了 Xcode 的计算机上可用。
NSBundle
对于程序需要读取自己嵌入的 plist 的情况,可以使用 NSBundle:
Mach-O
对于程序需要读取任意文件的嵌入 plist 而不借助 otool 的情况,程序可以解析 Mach -O 文件中的信息并按如下方式提取其嵌入的 plist:
并且:
请注意
embeddedPlist()
有一些限制:它期望该文件是一个瘦 Mach-O 文件(即,它将使用非 Mach-O 文件会崩溃,并且不适用于包含 i386 和 x86_64 Mach-O 数据的胖文件);它仅适用于 x86_64 文件;它不报告错误。我继续在 MIT 许可下发布了 BVPlistExtractor。它检测文件是否确实是瘦 Mach-O 文件还是胖/通用文件,并且适用于 i386 和 x86_64。
otool
You can use otool(1) to dump the contents of the section containing the embedded plist:
and then pipe its output to xxd(1) in order to obtain the corresponding ASCII representation:
However, otool is only available in machines where Xcode has been installed.
NSBundle
For the cases where a program needs to read its own embedded plist, NSBundle can be used:
Mach-O
For the cases where a program needs to read the embedded plist of an arbitrary file without resorting to otool, the program can parse the Mach-O information in the file and extract its embedded plist as follows:
and:
Note that
embeddedPlist()
has some limitations: it expects the file to be a thin Mach-O file (i.e., it will crash with non-Mach-O files and it won’t work with fat files containing, for example, both i386 and x86_64 Mach-O data); it only works with x86_64 files; it doesn’t report errors.I went ahead and released BVPlistExtractor under the MIT licence. It detects whether the file is indeed a thin Mach-O file or a fat/universal file, and works with both i386 and x86_64.
有一个 CoreFoundation 函数可以实现此目的:
CFBundleCopyInfoDictionaryForURL()
。从文档中:它可在 Mac OS X v10.2 及更高版本上使用。如果您在 Cocoa 中使用,则可以执行此操作(前提是您有该捆绑包的
(NSURL*)url
):There's a CoreFoundation function for that:
CFBundleCopyInfoDictionaryForURL()
. From the documentation:It's available on Mac OS X v10.2 and later. If you use in Cocoa you can do this (provided you have an
(NSURL*)url
for the bundle):用户的计算机可能没有安装
otool
,我也遇到了同样的问题。解决方案是使用launchctl
,它保证在任何现代 Mac 上都存在。它有一个
plist
子命令,它执行以下操作:如果您未指定该部分,则默认情况下它将打印 __TEXT。提供的唯一参数是可执行文件的路径:
launchctl plist /Library/PrivilegedHelperTools/com.sparklabs.ViscosityHelper
如果您提供了路径,输出可能如下所示:
它可以在命令中使用-line 以及通过
NSTask
(swift 中的Process
)类的代码。User's computer would not probably have
otool
installed, and I had the same problem. The solution was to uselaunchctl
, which is guaranteed to be present at any modern Mac.It has a
plist
subcommand which does the following:If you do not specify the section, it prints __TEXT by default. The only argument to provide is the path to the executable:
launchctl plist /Library/PrivilegedHelperTools/com.sparklabs.ViscosityHelper
If you have given path, output might be something like this:
It can be used in command-line as well as from code via
NSTask
(Process
in swift) class.一种更简单的方法:
man getectdata。有很多关于如何访问各个部分(当前可执行文件、任意可执行文件、框架等)的示例。
A much simpler approach:
man getsectdata. There's lots of examples on how to access various pieces (current executable, arbitrary executable, framework, etc).
由于接受的答案中的 otool 命令似乎不再起作用(在 macOS Monterey 上产生乱码),因此您仍然可以通过命令行上的 mach-o 读取嵌入的 Info.plist:
从手册页:
Since the otool command from the accepted answer does not seem to work anymore (produces gibberish on macOS Monterey), here is how you can still read an embedded Info.plist from a mach-o on the command line:
From the man pages:
与最初的问题类似,我需要使用
-sectcreate __TEXT
读取嵌入在可执行文件中的信息和 launchd 属性列表。现在是 2021 年,我正在使用 Swift,但找不到任何现有的东西可以满足我的需求。我花了一些时间才弄清楚如何实现,所以我决定将其打包:EmbeddedPropertyList。如果您在使用时遇到任何问题,请在 Github 上打开问题时在此处回复。
Similarly to the original question I needed to read info and launchd property lists embedded in an executable with
-sectcreate __TEXT
. As it's 2021 I'm using Swift, but couldn't find anything existing to meet my needs. It took me a bit to figure out how, so I decided to package it up: EmbeddedPropertyList.If you run into any issues using it, either reply here on open an issue on Github.