LoginSignup
2
1

macOSは動的ライブラリがファイルシステムから見えないらしい

Posted at

TL;DR

macOS Big Sur 11.0.1 以降だと、ダイナミックリンクライブラリがキャッシュされていてファイルシステムから見えなくなっている(Finder.appから見えない)

ことの発端

Ghidraを使ってバイナリを見ていたところ、ダイナミックリンクライブラリが見つからないとエラーが出た。

Ghidraのエラー
----- Loading /Users/XXXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXX -----
Linking external programs to XXXXXXXXXXXXXXXXXXXXX...
  [/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation] -> not found
  [/System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork] -> not found
  [/usr/lib/libresolv.9.dylib] -> not found
  [/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation] -> not found
  [/System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement] -> not found
  [/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration] -> not found
  [/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices] -> not found
  [/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit] -> not found
  [/usr/lib/libobjc.A.dylib] -> not found
  [/System/Library/Frameworks/Security.framework/Versions/A/Security] -> not found
  [/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit] -> not found
  [/System/Library/Frameworks/Virtualization.framework/Versions/A/Virtualization] -> not found
  [/System/Library/Frameworks/Hypervisor.framework/Versions/A/Hypervisor] -> not found
  [/usr/lib/libSystem.B.dylib] -> not found

/usr/lib/libSystem.B.dylib とかは明らかにシステムに無くてはならないものなのに、見つからないのはおかしい。

本当に存在しないlibSystem.B.dylib
cha84rakanal@ ~ % ls /usr/lib/libSystem.B.dylib
ls: /usr/lib/libSystem.B.dylib: No such file or directory
cha84rakanal@ ~ % 

公式ドキュメントより

New in macOS Big Sur 11.0.1, the system ships with a built-in dynamic linker cache of all system-provided libraries. As part of this change, copies of dynamic libraries are no longer present on the filesystem. Code that attempts to check for dynamic library presence by looking for a file at a path or enumerating a directory will fail. Instead, check for library presence by attempting to dlopen() the path, which will correctly check for the library in the cache. (62986286)

macOS Big Sur 11.0.1 よりダイナミックリンクライブラリはファイルシステム上に存在しなくなりました。と書いてありました。プログラムの実行時、OS側がよしなに取り扱っているわけですね。ちなみに、ダイナミックリンクライブラリのキャッシュの実体は、 /System/Library/dyld においてあります。

dlopenは動作する

ファイルシステム上に存在しないパスに対して、ダイナミックリンクライブラリを動的にロードする dlopen 関数が動作するか確認してみる。確認には、次のプログラムを使った。

dltest.c
#include <mach-o/dyld.h>
#include <dlfcn.h>
#include <stdio.h>

int library_exists(const char* path) {
    void* handle = dlopen(path, RTLD_LAZY);
    if (handle == NULL) return 0;
    dlclose(handle);
    return 1;
}

int main(void) {
    int result;
    char* path = "/System/Library/Frameworks/Virtualization.framework/Versions/A/Virtualization";
    result = library_exists(path);
    printf("library_exists(%s) == %d", path, result);
}
cha84rakanal % ls /System/Library/Frameworks/Virtualization.framework/Versions/A/Virtualization
ls: /System/Library/Frameworks/Virtualization.framework/Versions/A/Virtualization: No such file or directory
cha84rakanal % cc -g dltest.c && ./a.out 
library_exists(/System/Library/Frameworks/Virtualization.framework/Versions/A/Virtualization) == 1
cha84rakanal % 

ファイルが無いので、 0 を期待しましたが1 が帰ってきてるのでdlopen 関数が動作していますね。

dyldの dlopen 関数の解剖については、WIPです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1