[WebKit]遭遇Mac OS私有API

简介: WebKit并不是完全开源的, Apple封装了一部代码在一个静态库(libWebKitSystemInterfaceXXXX.a)中,并没有提供源代码。

WebKit并不是完全开源的, Apple封装了一部代码在一个静态库(libWebKitSystemInterfaceXXXX.a)中,并没有提供源代码。而且不同版本的OS (包括iOS),会有特定的版本。

这就是我今天从分析中了解到的, 觉得过程比较有趣,记录一下。

1. 在WebKit中有这样一段源代码 (Laguage.mm):

static String httpStyleLanguageCode(NSString *languageCode)
{
    ASSERT(isMainThread());

    // Look up the language code using CFBundle.
    RetainPtr<CFStringRef> preferredLanguageCode(AdoptCF, wkCopyCFLocalizationPreferredName((CFStringRef)languageCode));

其中wkCopyCFLocalizationPreferredName只有如下的定义,找不到实现代码:
extern CFStringRef (*wkCopyCFLocalizationPreferredName)(CFStringRef);

2. 在运行时,查询wkCopyCFLocalizationPreferredName的地址信息:
(lldb) p wkCopyCFLocalizationPreferredName
(CFStringRef (*)(CFStringRef)) $0 = 0x0000000100478a49 
(WebKit2`WKCopyCFLocalizationPreferredName)


(lldb) image lookup -s WKCopyCFLocalizationPreferredName
1 symbols match 'WKCopyCFLocalizationPreferredName' in /Volumes/Data/Project/Webkit/webkitSvn/Build/Products/Debug/WebKit2.framework/Versions/A/WebKit2:
        Address: WebKit2[0x0000000000464a49] (WebKit2.__TEXT.__text + 4600745)
        Summary: WebKit2`WKCopyCFLocalizationPreferredName
1 symbols match 'WKCopyCFLocalizationPreferredName' in /Volumes/Data/Project/Webkit/webkitSvn/Build/Products/Debug/WebKit.framework/Versions/A/WebKit:
        Address: WebKit[0x00000000001b8275] (WebKit.__TEXT.__text + 1795141)
        Summary: WebKit`WKCopyCFLocalizationPreferredName

可以看到代码是位于WebKit2.framework中的, 但没有源代码信息,所以必然是link了一个静态库进来。


3. 查看项目的编译设置,可以发现要链接进来的库:


还可以在WEBKIT_SYSTEM_INTERFACE_LIBRARY的定义中发现有不同系统的版本。

可以找到一个正在使用的库看看:
  

4. 用IDA(试用版)打开找找里面有没有WKCopyCFLocalizationPreferredName:


也可以使用nm看看源文件,显然WebKitSystemInterface.o找不到对应的源代码:
nm -a libWebKitSystemInterfaceLion.a
/XXXXXX/Build/Products/Debug/libWebKitSystemInterfaceLion.a(WebKitSystemInterface.o):
0000000000002591 t -[NSWindowGraphicsContext(WebKitSystemInterface) _WebKitSystemInterface_setGraphicsPort:]
0000000000008d98 s -[NSWindowGraphicsContext(WebKitSystemInterface) _WebKitSystemInterface_setGraphicsPort:].eh
00000000000090a8 S _WKCopyBundleURLForExecutableURL.eh
00000000000006c7 T _WKCopyCFLocalizationPreferredName
0000000000008200 S _WKCopyCFLocalizationPreferredName.eh

反汇编可以看到如下的代码:
function _WKCopyCFLocalizationPreferredName {
    CFBundleGetLocalizationInfoForLocalization(arg_0, &var_32, &var_28, &var_24, &var_20);
    rax = CFBundleCopyLocalizationForLocalizationInfo(var_32, var_28, var_24, var_20);
    return rax;
}

很简单,就是涉及到两个函数调用。问题是,这两个函数并没有在开发文档里。


5 继续查找libWebKitSystemInterfaceXXX.a的来历。WebKit的工程都是通过gyp来生成的,打开果然里面提到了这样一段描述:
WebCore.gyp
 ['OS == "mac"', {
      'targets': [
        {
          # On the Mac, libWebKitSystemInterface*.a is used to help WebCore
          # interface with the system.  This library is supplied as a static
          # library in binary format.  At present, it contains many global
          # symbols not marked private_extern.  It should be considered an
          # implementation detail of WebCore, and does not need these symbols
          # to be exposed so widely.
          #
          # This target contains an action that cracks open the existing
          # static library and rebuilds it with these global symbols
          # transformed to private_extern.
          'target_name': 'webkit_system_interface',

它只以二进制形式提供。没问题,有反汇编的结果,写出一个一样的函数也不是问题。


6. 找到两个私有API的来历。
使用 image lookup -s可以很容易确定两个函数是在CoreFundation.framework中的。在Apple Open Source中也可以查得到声明(class-dump对C接口就不灵光了):
   CFBundlePriv.h on opensource.apple.com
    CFBundleGetLocalizationInfoForLocalization
    CFBundleCopyLocalizationForLocalizationInfo

最后添加如下的声明就可以使用了:
extern "C" {
CF_EXPORT Boolean CFBundleGetLocalizationInfoForLocalization(CFStringRef localizationName, SInt32 *languageCode, SInt32 *regionCode, SInt32 *scriptCode, CFStringEncoding *stringEncoding);
CF_EXPORT CFStringRef CFBundleCopyLocalizationForLocalizationInfo(SInt32 languageCode, SInt32 regionCode, SInt32 scriptCode, CFStringEncoding stringEncoding);
}


目录
相关文章
|
4月前
|
iOS开发 MacOS
MAC OS更新系统后IDEA中的SVN报错无法使用
MAC OS更新系统后IDEA中的SVN报错无法使用
|
12月前
|
消息中间件 Dubbo 中间件
在 Docker 中运行 Mac OS 是什么样的体验?
在 Docker 中运行 Mac OS 是什么样的体验?
|
7月前
|
前端开发 安全 Go
在Mac OS X上运行Go语言的GUI程序
在Mac OS X上运行Go语言的GUI程序
200 3
|
11月前
|
iOS开发 MacOS
MAC OS更新系统后IDEA中的SVN报错无法使用
IntelliJ IDEA无法正常使用SVN 报Cannot run program “svn” (in directory “/XXXX/XXXX/XXXX/XXX”): error=2错误! 解决方法来了!
1034 0
|
Shell API Python
OS库常用API讲解
OS库常用API讲解
246 0
|
Oracle Java 关系型数据库
珠联壁合地设天造|M1 Mac os(Apple Silicon)基于vscode(arm64)配置搭建Java开发环境(集成web框架Springboot)
也许有人从未听说过Python,但是不会有人没听说过Java,它作为一个拥有悠久历史的老牌编程语言,常年雄踞TIOBE编程语言榜首,其顶尖的霸主地位不可撼动,而M1 mac业已发布了一段时间,作为跨时代的顶级芯片系统,这两大巨头能否珠联璧合,让开发者们猛虎添翼、更上层楼?本次我们尝试在M1 mac系统中搭建Java开发环境,并且集成目前Web开发领域红的发紫的Springboot框架,另外,谁说玩儿Java就必须得用Eclipse或者IntelliJ IDEA?我们就骄傲地使用Vscode。
珠联壁合地设天造|M1 Mac os(Apple Silicon)基于vscode(arm64)配置搭建Java开发环境(集成web框架Springboot)
|
Shell 调度 iOS开发
奇技淫巧玄妙无穷| M1 mac os(苹果/AppleSilicon)系统的基本操作和设置
最近有个朋友跟我说,说他新入职了一家公司,公司还不错,给他配了一台Mac,但是呢他以前一直在Windows环境下开发,对Mac os并不了解,他感到很彷徨,所以本次呢,我们来分享一下,当手头儿有一部崭新的Mac,我们应该怎么上手操作和配置,让它成为我们开发的好帮手。
奇技淫巧玄妙无穷| M1 mac os(苹果/AppleSilicon)系统的基本操作和设置
|
机器学习/深度学习 机器人 PyTorch
金玉良缘易配而木石前盟难得|M1 Mac os(Apple Silicon)天生一对Python3开发环境搭建(集成深度学习框架Tensorflow/Pytorch)
笔者投入M1的怀抱已经有一段时间了,俗话说得好,但闻新人笑,不见旧人哭,Intel mac早已被束之高阁,而M1 mac已经不能用真香来形容了,简直就是“香透满堂金玉彩,扇遮半面桃花开!”,轻抚M1 mac那滑若柔荑的秒控键盘,别说996了,就是007,我们也能安之若素,也可以笑慰平生。好了,日常吹M1的环节结束,正所谓剑虽利,不厉不断,材虽美,不学不高。本次我们尝试在M1 Mac os 中搭建Python3的开发环境。
金玉良缘易配而木石前盟难得|M1 Mac os(Apple Silicon)天生一对Python3开发环境搭建(集成深度学习框架Tensorflow/Pytorch)
|
机器学习/深度学习 开发框架 Java
别梦依稀咒逝川,Ruby二十八年前|M1芯片Mac os系统配置Ruby(3.0.0) on Rails(6.1.1)开发环境
在每个开发者心里,都会有一门“最好”的语言,在这个世界的某个深处,在一些矫矫不群的人们心中,这门语言的名字叫做Ruby,它今年二十八岁了,历史和Java一样的悠久,但是它没有大厂背书、它的性能被开发者诟病、时至今日依然无法高效利用多核资源,甚至于它每年都要被“死亡”一次,相比于有太阳计算机系统、甲骨文、IBM 这些大公司支持的 Java,它是那么的一无所有,但是,它又拥有全世界最虔诚的“信徒”,拥有最活跃的开发者社区,这一切,又让它是那么的应有尽有。是的,这就是Rubyist的理念:有的时候,你想证明给一万个人看,到后来,你发现只得到了一个明白的人,那就够了。
别梦依稀咒逝川,Ruby二十八年前|M1芯片Mac os系统配置Ruby(3.0.0) on Rails(6.1.1)开发环境
|
开发工具 iOS开发 MacOS
mac OS简单实用的包管理器Homebrew,真的非常好用
今天安装zookeeper时使用的是brew方式来安装,才深深的体会到brew的厉害之处,闲话少叙,进入正题。
285 0