[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);
}


目录
相关文章
|
8月前
|
编解码 Android开发
Android获取设备各项信息(设备id、ip地址、设备名称、运行商、品牌、型号、分辨率、处理器、国家码、系统语言、网络类型、oaid、android版本、操作系统版本、mac地址、应用程序签名..)1
Android获取设备各项信息(设备id、ip地址、设备名称、运行商、品牌、型号、分辨率、处理器、国家码、系统语言、网络类型、oaid、android版本、操作系统版本、mac地址、应用程序签名..)
491 1
|
8月前
|
iOS开发 MacOS
MAC OS更新系统后IDEA中的SVN报错无法使用
MAC OS更新系统后IDEA中的SVN报错无法使用
|
3月前
|
Linux C语言 iOS开发
MacOS环境-手写操作系统-06-在mac下通过交叉编译:C语言结合汇编
MacOS环境-手写操作系统-06-在mac下通过交叉编译:C语言结合汇编
56 0
|
8月前
|
编解码 开发工具 Android开发
Android获取设备各项信息(设备id、ip地址、设备名称、运行商、品牌、型号、分辨率、处理器、国家码、系统语言、网络类型、oaid、android版本、操作系统版本、mac地址、应用程序签名..)2
Android获取设备各项信息(设备id、ip地址、设备名称、运行商、品牌、型号、分辨率、处理器、国家码、系统语言、网络类型、oaid、android版本、操作系统版本、mac地址、应用程序签名..)2
485 2
|
7月前
|
XML API 开发工具
微信mac协议API
微信mac协议API
|
8月前
|
安全 Java iOS开发
MAC OS X 硬盘安装详细分解教程
MAC OS X 硬盘安装详细分解教程
245 1
|
8月前
|
编解码 Oracle iOS开发
VirtualBox虚拟机安装Mac OS X Lion系统详解
VirtualBox虚拟机安装Mac OS X Lion系统详解
353 1
|
8月前
|
安全 iOS开发 MacOS
Mac pro升级 MacOS 10.15 Catalina 后根目录是只读的, Recovery OS不能访问
Mac pro升级 MacOS 10.15 Catalina 后根目录是只读的, Recovery OS不能访问
160 0
|
Cloud Native 编译器 Linux
如何在Windows、Mac和Linux操作系统上安装Protocol Buffers(protobuf)编译器
如何在Windows、Mac和Linux操作系统上安装Protocol Buffers(protobuf)编译器
535 0