Mac系统下lipo, ar, nm等工具的使用简介

引言

很多第三方库开发者工作敷衍, 技术不清(高德地图, 就是在说你), 不知道符号隐藏, 把一堆其他第三方库的符号暴露出来, 导致链接时产生符号重复. 如下图所示

一个地图库把整个libjepg的符号列表导出来了, 搞毛线. 更要命的是, 如果用户链接了其他版本的libjpeg, 会直接因为入口地址不正确让程序直接崩溃

这个问题找官方显然是无法解决的, 毕竟三个大版本了(2.4版本到4.0版本)完全没有改变的意思, 根本就不懂嘛. 求人不如求己, 本文就从这个问题入手, 简要介绍Mac OS X系统下几个常用二进制文件修改工具的使用

概述

我们都知道, 代码到可执行文件需要经过编译(compile)和链接(link)两个主要步骤. 编译是把程序语言转换为机器指令, 这个不在本文的讨论范围.

链接是把分块编译的对象文件(obj)合并成一个完整的程序, 主要解决函数入口重定向的问题. 其功能主要就是把所有的对象文件打个包, 生成一个导出符号表, 让其他程序可以知道本文件的结构.

而对于苹果系统来说, 丰富的设备包含了多种架构平台, armv7, arm64, i386, x86_64是最常见的指令集, 一个程序库为了兼容各个平台, 常常要把不同平台编译的程序合并起来, 生成所谓的胖文件(Fat File), 这样子开发者就不需要专门准备一套真机版本库和模拟器版本库了(在早期, 很多第三方库确实是提供了不同版本的二进制文件来减少库文件大小).

因此对于一个可执行文件, 其实包含了3层结构: Universal Fat File -> Single Architecture Binary File -> Mach-O Object.

本文将要介绍的lipo, ar, nm, strip, ld等工具的功能就是对这三层结构进行转换和修改.

本文以高德地图iOS SDK MAMapKit.framework 4.0.3为例, 演示如何从这个库文件里剔除暴露的png符号.

工具介绍

lipo

lipo是管理Fat File的工具, 可以查看平台列表, 提取特定平台, 重新打包.

首先运行 lipo -info MAMapKit

可以看出这个文件包含了4个平台的代码. 接下来的所有操作都是要针对单一平台进行的, 因此先提取出来armv7平台,

lipo -thin armv7 MAMapKit -output MAMapKit.armv7

可以看出单平台的程序文件要小得多.

接下来我们来查看一下这个文件的符号表

nm

nm用来显示一个程序包的符号表, 默认会显示入口地址, 符号类型, 符号名.

nm -j MAMapKit.armv7  | grep png > symbols 可以获得所有的libpng导出符号, 存入到symbols文件, 为接下来的工作做准备. -j 选项控制只输出符号名.

strip

strip用来删除程序里的符号表. -R 用来指定一个要删除的符号列表, 使用上述生成的symbols文件. 添加 -S 选项来保留其他符号.

strip -S -R symbols MAMapKit.armv7 -o MAMapKit.armv7.strip

可以验证生成的新文件已经没有了png符号.

我们用这个方法应用到其他所有平台.

ar

我们用上述方法处理arm64时遇到了问题

这个文件里的一些符号用作了重定向入口, strip命令不允许删除, 这时就需要更强力的工具ld登场了. ld 其实苹果系统下的链接器, 可以更精确的控制符号表的导出.

ld的操作对象是obj, 因此我们需要先用到ar打包工具. ar可以查看一个程序包里的对象文件列表, 解压出其中的对象文件并重新打包.

ar -t MAMapKit.arm64

可以看到整个包就包含了一个主对象文件, 纳尼? 真是囫囵吞枣一把抓.

使用 -x 解压出来, 接下来就要轮到 ld 上场了.

ld

本问题需要的ld功能和strip基本一致, 使用下述命令

ld -x -r -unexported_symbols_list symbols MAMapKit-arm64-master.o -o MAMapKit-arm64-master.o.strip

由此生成对象文件就剔除了png符号表

接下来要做的就是上述逆过程, 对象文件合并成程序文件

ar -r MAMapKit.arm64 MAMapKit-arm64-master.o.strip Pods-MAMapKit-dummy.o

最后是把各个平台的程序打包成Fat File即可.

时间: 2024-08-25 09:20:49

Mac系统下lipo, ar, nm等工具的使用简介的相关文章

Mac系统下虚拟机VMware Fusion下Win10如何通过Navcat连接Mysql 5.7

最近一直在折腾Mac系统,原先对Mac使用也不是很熟悉,所以安装过程中出现了很多问题.为了以后查阅方便,当然也为了使得和我一样的小白少踩一些坑, 所以就记录一下这些问题. 首先说一下VMware Fusion这个虚拟机软件吧.我下载的官方最新的版本8.5.7.然后开始安装,安装比较容易.最麻烦的就是如何安装WIn10系统呢?一开始我采取按部就班的方法,通过Mac自带的浏览器Safari去下载Win10 ISO的文件.结果速度太让人崩溃了,非常慢.后来我尝试把ISO通过百度网盘离线下载的方式先下载

在Linux系统下运行微信Web开发者工具

微信Web开发者工具只有window版本和mac版本,如果想要在Linux系统下运行微信Web开发者工具,需要花费很大周折. 注:带 * 的步骤或文件为不确定是否管用的步骤或文件.本人系统为Linux Mint 18.1版本. 1.下载nwjs 下载nwjs的SDK. 2.将微信web开发者工具拷贝到nwjs 将在window系统下安装的微信web开发者工具文件夹中的package.nw.icon.ico.* 微信web开发者工具.exe拷贝到nwjs sdk解压后的文件夹内. * 解压 微信w

Mac系统下使用VirtualBox虚拟机安装win7--第一步 安装vbox虚拟机

Mac系统下使用VirtualBox虚拟机安装win7操作步骤: 第一步 安装vbox虚拟机 1.先下载vbox,下载地址:: https://www.virtualbox.org/wiki/Downloads ,在页面中点击“VirtualBox 5.0.16 for OS X hosts amd64”下载链接,如图所示: 下载好了以后,在 Finder 中的下载目录中,找到“VirtualBox-5.0.16-105871-OSX.dmg”文件,运行安装,如图所示: 打开以后,双击安装界面中

[视频]mac系统下虚拟机parallels安装ubuntu 14.04视频教程

此文是http://www.mr-wu.cn/install-ubuntu-14-04-on-parallels-for-mac/这篇博文的补充,为整个ubuntu 14.04安装过程的视频录像. mac系统很棒,mac下的开发环境也很棒,但有时你还得需要ubuntu开发环境,比如进行嵌入式Linux交叉编译,使用Linaro toolchain-其实mac系统下使用parallels虚拟机安装ubuntu相当的容易,下边讲一下mac系统下使用parallels虚拟机安装ubuntu 14.04

mac系统下为emacs设置中文字体,解决乱码问题

最近换了个系统,现在用mac系统. 当打开emacs后,中文支持的不是很好.有的地方能显示,在.el文件的注释里显示为口口口口口口口口这样的框,如下图所示 找了半天,是因为中文字体的问题,只要设置好中文字体就行了. 以前在Linux下中文就支持的很好,不用配制中文字体就能显示. 配制代码如下(将其放到.emacs文件或init.el里就OK): ;; -------------------------------------------------------------------------

mac系统下的常用命令

这是我日常在mac下记录的一些常用终端命令: 1 java 2 javac 3 exit 4 /Users/lianxumac/Desktop/apktool1.5.2/反编译 ; exit; 5 /Users/lianxumac/Desktop/apktool1.5.2/反编译 ; exit; 6 /Users/lianxumac/Desktop/apktool1.5.2/反编译 ; exit; 7 /Users/lianxumac/Desktop/apktool1.5.2/反编译 ; exi

Mac系统下brew安装指定版本的nodejs小笔记

http://www.jincon.com/archives/429/ Mac系统下brew安装指定版本的nodejs小笔记

mac系统下(os x 10)手动设置IP提示无效服务器IP的解决方法

在mac系统下(os x 10),手动设置ip地址后,弹出错误提示"无效的服务器地址 " 解决的办法是:  ~ networksetup -listallnetworkservices  列出所有网络服务信息  ~ networksetup -setv6off "Ethernet"   停止对应网卡的ipV6服务                                    ~ networksetup -setmanual "Ethernet&q

mac系统下虚拟机parallels安装ubuntu 14.04

mac系统很棒,mac下的开发环境也很棒,但有时你还得需要ubuntu开发环境,比如进行嵌入式Linux交叉编译,使用Linaro toolchain- 其实mac系统下使用parallels虚拟机安装ubuntu相当的容易,下边讲一下mac系统下使用parallels虚拟机安装ubuntu 14.04桌面系统环境 视频教程 http://www.mr-wu.cn/video-tutorial-for-install-ubuntu-14-04-on-parallels-for-mac/ 下载Ub