菜鸟教程小白 发表于 2022-12-12 14:31:06

ios - 如何在 Mach-O 文件中编辑加载命令并在 tvOS 上成功链接它?


                                            <p><p>假设我有一个 .a fat 库,它是为多种架构构建的(例如 armv7、armv7s、i386、x86_64、arm64)。库是为 iOS 构建的(其中包含 cmd LC_VERSION_MIN_IPHONEOS 和 6.0 版)。例如,当我运行 <strong><em>$ otool -lv</em></strong> 时,我得到了带有这样加载命令的部分:</p>

<pre><code>Load command 1
      cmd LC_VERSION_MIN_IPHONEOS
cmdsize 16
version 6.0
      sdk n/a
</code></pre>

<p>我想将其替换为:</p>

<pre><code>Load command 1
      cmd LC_VERSION_MIN_TVOS
cmdsize 16
version 9.0
      sdk n/a
</code></pre>

<p>有谁知道我该怎么做,或者可以指出一些有用的资源吗?
我还能在 tvOS 上链接修改后的库吗?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>如果您可以访问源代码,最好的解决方案显然是为 tvOS 重新编译它。</p>

<p>如果您无权访问源代码,快速而肮脏的解决方案是在十六进制编辑器中打开库,搜索这些字节(每个目标文件一次):</p>

<pre class="lang-none prettyprint-override"><code>25000000 10000000 00000600 00000000
</code></pre>

<p>并用这些替换它们:</p>

<pre class="lang-none prettyprint-override"><code>2f000000 10000000 00000900 00000000
</code></pre>

<p>一个更稳定的解决方案是编写一个小的 C 程序来解析和编辑目标文件的 header 。在安装了 Xcode 的 Mac 上,您需要的所有信息(以及有用的评论)都可以从 <code>&lt;mach-o/loader.h&gt;</code> 获得。头文件。对于其他人,该文件也可以从 <a href="https://opensource.apple.com/source/xnu/xnu-4570.1.46/EXTERNAL_HEADERS/mach-o/loader.h.auto.html" rel="noreferrer noopener nofollow">the XNU source code</a> 获得。 .</p>

<p>迭代所有加载命令的基本思想如下所示,给定一个字符缓冲区 <code>file</code>包含一个 Mach-O:</p>

<pre class="lang-c prettyprint-override"><code>struct mach_header_64 *hdr = (struct mach_header_64*)file;
for(struct load_command *cmd = (struct load_command*)(hdr + 1),
                        *end = (struct load_command*)((uintptr_t)cmd + hdr-&gt;sizeofcmds);
    cmd &lt; end;
    cmd = (struct load_command*)((uintptr_t)cmd + cmd-&gt;cmdsize)
)
{
    // ...
}
</code></pre>

<p>现在为了您的目的,您需要迭代直到找到带有 <code>cmd-&gt;cmd == LC_VERSION_MIN_IPHONEOS</code> 的加载命令, 并将其替换为 <code>LC_VERSION_MIN_TVOS</code> .您还需要将该加载命令转换为 <code>struct version_min_command*</code>然后,其定义如下:</p>

<pre><code>struct version_min_command {
    uint32_t cmd;
    uint32_t cmdsize;
    uint32_t version;   /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
    uint32_t sdk;       /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
};
</code></pre>

<p>所以为了得到版本号<code>9.0</code> ,你会分配 <code>version</code> <code>(9 &lt;&lt; 16)</code> 的值.</p>

<p>然后将文件保存回来就大功告成了。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何在 Mach-O 文件中编辑加载命令并在 tvOS 上成功链接它?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/48301420/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/48301420/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何在 Mach-O 文件中编辑加载命令并在 tvOS 上成功链接它?