Analysis of the Facebook.app for iOS

Posted Oct 18, 2016

Did you ever wonder why the Facebook.app for iOS is such a big download? This post tries to give some answers. The version 66.0 (released on 7 October 2016) was analyzed on an iPad Air 2 (64-bit).

Here is what you see when downloading Facebook on an iPad Air 2:

App content

A scan of the content of the Facebook app using GrandPerspective gives already a good overview:

As you can see more than 100 MB are taken by the binary itself. The images (Assets.car), the localizations and other resources are only responsible for a small part of the size.

One note: The Facebook app seems to use the open source JSC framework. Unless there is a technical reason to use it, Facebook could remove this framework and use instead the JavaScriptCore framework built in iOS. JavaScriptCore is available on iOS 7 and later and Facebook targets iOS 8 and later.

Slicing

One important point to note is that the Facebook binary I downloaded only contains 64-bit code. There is no 32-bit code. Facebook uses the Slicing mechanism which is described by Apple here:

Slicing is the process of creating and delivering variants of the app bundle for different target devices. A variant contains only the executable architecture and resources that are needed for the target device.

Entropy

Let’s look at the Facebook binary. The entropy graph generated by Hopper gives a good idea of the content:

The red part (with biggest entropy) is actual code while the green and orange parts are other sections (strings, constants, …). Just by looking at the entropy graph, we know that around 50% of the binary is code.

Sections

By looking at the sections of the binary we indeed see that the (__TEXT, __text) section is more than 50 MB. Here is the list of sections sorted by size:

(__TEXT, __text): 56.60 MB
(__DATA, __objc_const): 16.57 MB
(__RODATA, __cstring): 5.02 MB
(__RODATA, __objc_methname): 4.55 MB
(__DATA, __const): 4.46 MB
(__RODATA, __gcc_except_tab): 3.87 MB
(__RODATA, __objc_methtype): 2.66 MB
(__DATA, __objc_data): 2.41 MB
(__DATA, __cfstring): 2.20 MB
(__DATA, __data): 1.66 MB
(__TEXT, __unwind_info): 1.58 MB
(__RODATA, __objc_classname): 1.42 MB
(__RODATA, __const): 1.40 MB
(__DATA, __bss): 0.89 MB
(__DATA, __objc_selrefs): 0.80 MB
(__DATA, __common): 0.54 MB
(__DATA, __objc_ivar): 0.38 MB
(__DATA, __objc_classlist): 0.24 MB
(__DATA, __objc_classrefs): 0.18 MB
(__DATA, __objc_superrefs): 0.13 MB
(__TEXT, __const): 0.07 MB
(__DATA, __objc_protolist): 0.06 MB
(__TEXT, __stubs): 0.02 MB
(__TEXT, __stub_helper): 0.02 MB
(__DATA, __la_symbol_ptr): 0.01 MB
(__DATA, __got): 0.01 MB
(__TEXT, __ustring): 0.01 MB
(__DATA, fbsessiongks): 0.01 MB
(__TEXT, __eh_frame): 0.01 MB
(__DATA, __mod_init_func): 0.00 MB
(__DATA, __objc_protorefs): 0.00 MB
(__DATA, __objc_catlist): 0.00 MB
(__DATA, __objc_nlclslist): 0.00 MB
(__DATA, FBInjectable): 0.00 MB
(__DATA, __mod_term_func): 0.00 MB
(__DATA, __objc_imageinfo): 0.00 MB

__RODATA segment

If you read carefully the list of sections, you did notice that the Facebook.app has a __RODATAsegment containing sections generally found inside the __TEXT segment. The reason for this oddity is to work around an App Review limitation. As you can read on the App Review page:

Each Mach-O executable file (for example, app_name.app/app_name) must not exceed these limits:

  • For apps whose MinimumOSVersion is less than 7.0: maximum of 80 MB for the total of all __TEXT sections in the binary.
  • For apps whose MinimumOSVersion is 7.x through 8.x: maximum of 60 MB per slice for the __TEXT section of each architecture slice in the binary.
  • For apps whose MinimumOSVersion is 9.0 or greater: maximum of 400 MB for the size of the Mach-O binary file.

Facebook targets iOS 8.0 and later and as such its __TEXT segment should not exceed 60 MB. But if you sum up the __TEXT and __RODATA segments, you end up with more than 77 MB:

Total size of the __TEXT sections: 58.3 MB
Total size of the __RODATA sections: 18.9 MB

Facebook avoids this limitation by moving some if the __TEXT sections into the read only __RODATAsegment. Implementing this trick is really simple: you just need to add a linker flag to rename the chosen sections. And it appears you need absolutely nothing at runtime: the renamed sections will be found automatically. This linker flag is described in the ld man page:

-rename_section orgSegment orgSection newSegment newSection

Renames section orgSegment/orgSection to newSegment/newSection.

You could use it to rename the (__TEXT, __cstring) section to (__RODATA, __cstring) by simply adding this line into the Other Linker Flags (OTHER_LDFLAGS):

-Wl,-rename_section,__TEXT,__cstring,__RODATA,__cstring

You can download a sample macOS Xcode project here. If you load the original binary (without the section rename) using MachOView, you will see the (__TEXT, __cstring) section:

After adding the linker flag and recompiling, a (__RODATA, __cstring) section will be visible and the binary will run as expected:

Note that this workaround is only needed as long as Facebook supports iOS 8. When targeting iOS 9 or later, the limitation is 400 MB which should be enough without splitting the __TEXT segment.

Third party libraries

So what does the code contain? Sadly I could not find a license/readme file containing the list of third party libraries. Also the Info view in Settings.app > Facebook > Settings > Infos is desperately empty - this seems like a Facebook.app bug.

By looking at the class names, I could build a list of third party libraries used. This list is most likely incomplete but hopefully correct:

Objective-C awards

The awards for the best Objective-C classes is attributed to:

NTNativeTemplateHackyWorkaroundBecauseNSMapTableIsBuggyContainer

The award for the longest Objective-C method is attributed to:

- (void)[FBComposerCompositionStateMutation matchBootstrap:
activityAttachmentUpdatedMutation:
activitySharingComposition:
albumDescription:
albumTitle:
appProvidedHashtag:
audienceMutation:
audienceTouchedByUser:
author:
clearContent:
containerPublishTargetForMediaCollection:
composerCancelAnalytics:
defaultAudienceMutation:
destinationMutation:
feedOnlyToggleState:
hashtags:
inspirationMutation:
isImplicitLocationExplicitlyBlockedByUser:
lifeEventDateMutation:
lifeEventRelationshipUpdated:
lifeEventTitleOrIconUpdated:
linkShareMutation:
shareOriginalPostMutation:
removeMediaAttachmentWithAssetID:
replaceAllExistingMediaAttachments:
addSingleMediaAttachment:
replaceSingleExistingMediaAttachmentIfExisting:
mediaAttachmentCaptionMutation:
mediaAttachmentMentionsMutation:
mediaReorderingMutation:
mentions:
moviesComposition:
moviesLoadedTaggedUsers:
photoAutoTaggingState:
photoTaggingAssetMutation:
placeMutation:
placeSuggestions:
placeTaggingState:
platformLoadedActionMutation:
platformLoadedAppAttribution:
platformLoadedImageAttachments:
platformLoadedOGMediaAttachmentsMutation:
platformLoadedPlaceMutation:
platformLoadedRef:
platformLoadedRobotext:
platformLoadedTaggedUsers:
platformLoadedVideoAttachment:
postContentTypeMutation:
postPromptPayload:
publishAsQuestionAndAnswerSession:
togglePublishAsQuestionAndAnswerSession:
preferredMarketplaceMutation:
productItemCategoryGraphQLID:
productItemPickupDeliveryInfo:
productItemPriceMutation:
productItemShouldPostToMarketplace:
productItemSuggestedPlace:
productItemSuggestedZipCode:
productItemTitle:
publishTarget:
remoteImageAttachments:
removeSponsor:
removeStorylineAttachment:
removeStickerAttachment:
replaceStorylineAttachmentWithMediaAttachments:
selectedStarRating:
shouldCreateProfileBadge:
statusTextMutation:
stickers:
taggableActivityComposition:
targeting:
withTagsMutation:
poll:
sponsor:
videoAttachmentMutation:
videoTaggingAssetMutation:
videoTaggingAnalytics:
boostedComponentData:
albumTracker:]

Conclusion

The Facebook app is a complex app and not just a simple web view. It contains a lot of third party libraries and even splits its __TEXT segment in order to not reach the 60 MB limit imposed by Apple.

Update 10.04.2017:

There is a newer blog post about the version 87.0: Analysis of the Facebook.app for iOS [v. 87.0]https://blog.timac.org/2017/0410-analysis-of-the-facebook-app-for-ios-v-87-0

https://blog.timac.org/2016/1018-analysis-of-the-facebook-app-for-ios/

Analysis of the Facebook.app for iOS的更多相关文章

  1. Using Qt to build an Omi App for iOS (and Android)

    JUNE 6, 2014 / HHARTZ Working on projects where the technology is pre-determined, it's often difficu ...

  2. 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native

    [源码下载] 不可或缺 Windows Native (25) - C++: windows app native, android app native, ios app native 作者:web ...

  3. To create my first app in iOS with Xcode(在Xcode创建我的第一个iOS app )

    To create my first app in iOS create the project. In the welcome window, click “Create a new Xcode p ...

  4. 你可能需要为你的 APP 适配 iOS 11

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/AZFrqL9dnlgA6Vt2sVhxIw 作者:s ...

  5. 將UNITY作品上傳到Facebook App!

    前言 大家好,今天要來介紹如何用UNITY 將製作好的遊戲上傳到Facebook,也就是Facebook App.近期Facebook與Unity合作而推出了新的插件,利用插件可上傳分數.邀請好友.P ...

  6. 如何玩facebook app上的H5游戏

    一.下载facebook app facebook链接 二.下载vpn 国内是访问不了的,必须vpn 因为vpn被封了厉害 我随便百度了个狸猫加速器,没付费,时断时续... 没有推荐的vpn,哪位大佬 ...

  7. Redesign Your App for iOS 7 之 页面布局

    Redesign Your App for iOS 7 之 页面布局 http://www.vinqon.com/codeblog/?detail/11109

  8. 支付宝APP支付IOS手机端java后台版

    版权声明:http://blog.csdn.net/u012131769/article/details/76639527#t8 转载:http://blog.csdn.net/u012131769/ ...

  9. Facebook App 的头文件会有更多的收获

    最近在看一些 App 架构相关的文章,也看了 Facebook 分享的两个不同时期的架构(2013 和 2014),于是就想一窥 Facebook App 的头文件,看看会不会有更多的收获,确实有,还 ...

随机推荐

  1. layedit图片上传接口案列

    html部分 <divclass="layui-form-item"> <labelfor="tname"class="layui- ...

  2. 洛谷P3704 [SDOI2017]数字表格

    题目描述 Doris刚刚学习了fibonacci数列.用f[i]f[i] 表示数列的第ii 项,那么 f[0]=0f[0]=0 ,f[1]=1f[1]=1 , f[n]=f[n-1]+f[n-2],n ...

  3. 列表查询组件代码, 简化拼接条件SQL语句的麻烦

    列表查询组件代码, 简化拼接条件SQL语句的麻烦 多条件查询

  4. ContentType 列表

    CONTENTTYPE是html里面都带有的,ASP只是设置当前的CONTENTTYPE在浏览器中,ContentType一般指定当前的文档内容,浏览器即根据相应的MIME及Content-Type映 ...

  5. ZBrush国庆中秋大放价,优惠提前享!

    没记错的话,上次的ZBrush活动应该是17年春节吧,悄么蔫地就把端午节等一系列节日忽略了,这让苦苦等待的小伙伴们情何以堪,这试用版用的也不得劲儿! 终于等到你,ZBrush官方消息称,17年中秋国庆 ...

  6. LeetCode Golang 单向链表相加 反向实现

    LeetCode 两数之和, 反向实现 1 -> 2 -> 3 -> 4 +                  3 -> 4 ------------------------- ...

  7. 11 个使用 GNOME 3 桌面环境的理由

    11 个使用 GNOME 3 桌面环境的理由 作者: David Both 译者: LCTT geekpi | 2017-08-22 11:43   评论: 27 GNOME 3 桌面的设计目的是简单 ...

  8. 工作流Activiti学习地址

    http://blog.csdn.net/xnf1991/article/details/52610277

  9. [剑指offer] 7. 斐波那契数列 (递归 时间复杂度)

    简介: 杨辉三角每条斜线上的数之和就构成斐波那契数列. 思路: 参考文章:https://mp.weixin.qq.com/s?src=11&timestamp=1551321876& ...

  10. [luogu] P4155 [SCOI2015]国旗计划(贪心)

    P4155 [SCOI2015]国旗计划 题目描述 A 国正在开展一项伟大的计划 -- 国旗计划.这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈.这项计划需要多名边防战士以接力的形式共同完成,为此 ...