添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

MacOS hook

背景

最近被Python libclang一个pthread.h文件打开被关闭的问题困扰,所以简单研究了下MacOS的hook。

使用工具是frida-trace。

要求:

(1)hook open/close,并打印出调用栈。

(2)hook的是Python进程。

操作

1、下载frida-trace。用的brew install frida-tools。

2、启动Python进程,需要注意的是MacOS不允许hook系统目录下的进程。所以这里我使用的是brew安装的python,例如这里我用的是前些日子刚发布的python3.11。

运行示例:python3.11 build.py

3、编写js脚本

语法请参考 JavaScript API

支持open、close的trace.js。

需要注意的是backtrace需要使用默认的,如果使用FUZZY,不准确。

var path;
var array;
Interceptor.attach(Module.getExportByName(null, "open"), {
    onEnter(args) {
        path = args[0].readUtf8String();
        //if (path == "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/pthread.h") {
        array = Thread.backtrace(this.context);
    onLeave(retvalue) {
        fd = retvalue.toInt32();
        if (fd > 0) {
            console.log("");
            console.log(`"valid ${fd} ${path}"`);
            array.forEach(element => {
                        const symbol = DebugSymbol.fromAddress(element);
                        console.log(`"${symbol}"`);
        } else {
            console.log("");
            console.log(`"invalid ${path}"`);
            array.forEach(element => {
                        const symbol = DebugSymbol.fromAddress(element);
                        console.log(`"${symbol}"`);
Interceptor.attach(Module.getExportByName(null, "close"), {
    onEnter(args) {
        fd = args[0].toInt32();
        array = Thread.backtrace(this.context);
        console.log("");
        console.log(`"close ${fd} ${path}"`);
        array.forEach(element => {
                    const symbol = DebugSymbol.fromAddress(element);
                    console.log(`"${symbol}"`);

4、监听目标进程

ps aux | grep Python查找目标进程pid,例如进程id是1818。

frida-trace -p 1818 -S ./trace.js

5、示例输出

先聚焦到pthread.h

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/pthread.h

"0x10bd3e87b libclang.dylib!llvm::sys::fs::openFile(llvm::Twine const&, int&, llvm::sys::fs::CreationDisposition, llvm::sys::fs::FileAccess, llvm::sys::fs::OpenFlags, unsigned int)"
"0x10bd3cbfe libclang.dylib!llvm::sys::fs::openFileForRead(llvm::Twine const&, int&, llvm::sys::fs::OpenFlags, llvm::SmallVectorImpl<char>*)"
"0x10bd3e92b libclang.dylib!llvm::sys::fs::openNativeFileForRead(llvm::Twine const&, llvm::sys::fs::OpenFlags, llvm::SmallVectorImpl<char>*)"
"0x10bd0ef62 libclang.dylib!(anonymous namespace)::RealFileSystem::openFileForRead(llvm::Twine const&)"
"0x109c6f9fb libclang.dylib!clang::FileSystemStatCache::get(llvm::StringRef, llvm::vfs::Status&, bool, std::__1::unique_ptr<llvm::vfs::File, std::__1::default_delete<llvm::vfs::File> >*, clang::FileSystemStatCache*, llvm::vfs::FileSystem&)"
"0x109c6c0fb libclang.dylib!clang::FileManager::getStatValue(llvm::StringRef, llvm::vfs::Status&, bool, std::__1::unique_ptr<llvm::vfs::File, std::__1::default_delete<llvm::vfs::File> >*)"
"0x109c6c4d9 libclang.dylib!clang::FileManager::getFileRef(llvm::StringRef, bool, bool)"
"0x109fa7e10 libclang.dylib!clang::HeaderSearch::getFileAndSuggestModule(llvm::StringRef, clang::SourceLocation, clang::DirectoryEntry const*, bool, clang::Module*, clang::ModuleMap::KnownHeader*)"
"0x109fa866e libclang.dylib!clang::DirectoryLookup::LookupFile(llvm::StringRef&, clang::HeaderSearch&, clang::SourceLocation, llvm::SmallVectorImpl<char>*, llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, bool&, bool&, bool&, llvm::SmallVectorImpl<char>&) const"
"0x109faa13d libclang.dylib!clang::HeaderSearch::LookupFile(llvm::StringRef, clang::SourceLocation, bool, clang::detail::SearchDirIteratorImpl<true>, clang::detail::SearchDirIteratorImpl<true>*, llvm::ArrayRef<std::__1::pair<clang::FileEntry const*, clang::DirectoryEntry const*> >, llvm::SmallVectorImpl<char>*, llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, bool*, bool*, bool, bool)"
"0x109fede4f libclang.dylib!clang::Preprocessor::LookupFile(clang::SourceLocation, llvm::StringRef, bool, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*, clang::detail::SearchDirIteratorImpl<true>*, llvm::SmallVectorImpl<char>*, llvm::SmallVectorImpl<char>*, clang::ModuleMap::KnownHeader*, bool*, bool*, bool)"
"0x10a00d3f3 libclang.dylib!EvaluateHasIncludeCommon(clang::Token&, clang::IdentifierInfo*, clang::Preprocessor&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)"
"0x10a00a1f5 libclang.dylib!clang::Preprocessor::ExpandBuiltinMacro(clang::Token&)"
"0x10a0089c6 libclang.dylib!clang::Preprocessor::HandleMacroExpandedIdentifier(clang::Token&, clang::MacroDefinition const&)"
"0x10a026a85 libclang.dylib!clang::Preprocessor::HandleIdentifier(clang::Token&)"
"0x109fc3e94 libclang.dylib!clang::Lexer::LexTokenInternal(clang::Token&, bool)"

跟这个调用栈一样的还有RTK_device_methods.h(不过找不到这个文件):

ExpandBuiltinMacro的场景

"0x1160e687b libclang.dylib!llvm::sys::fs::openFile(llvm::Twine const&, int&, llvm::sys::fs::CreationDisposition, llvm::sys::fs::FileAccess, llvm::sys::fs::OpenFlags, unsigned int)"
"0x1160e4bfe libclang.dylib!llvm::sys::fs::openFileForRead(llvm::Twine const&, int&, llvm::sys::fs::OpenFlags, llvm::SmallVectorImpl<char>*)"
"0x1160e692b libclang.dylib!llvm::sys::fs::openNativeFileForRead(llvm::Twine const&, llvm::sys::fs::OpenFlags, llvm::SmallVectorImpl<char>*)"
"0x1160b6f62 libclang.dylib!(anonymous namespace)::RealFileSystem::openFileForRead(llvm::Twine const&)"
"0x1140179fb libclang.dylib!clang::FileSystemStatCache::get(llvm::StringRef, llvm::vfs::Status&, bool, std::__1::unique_ptr<llvm::vfs::File, std::__1::default_delete<llvm::vfs::File> >*, clang::FileSystemStatCache*, llvm::vfs::FileSystem&)"
"0x1140140fb libclang.dylib!clang::FileManager::getStatValue(llvm::StringRef, llvm::vfs::Status&, bool, std::__1::unique_ptr<llvm::vfs::File, std::__1::default_delete<llvm::vfs::File> >*)"
"0x1140144d9 libclang.dylib!clang::FileManager::getFileRef(llvm::StringRef, bool, bool)"
"0x11434fe10 libclang.dylib!clang::HeaderSearch::getFileAndSuggestModule(llvm::StringRef, clang::SourceLocation, clang::DirectoryEntry const*, bool, clang::Module*, clang::ModuleMap::KnownHeader*)"
"0x11435066e libclang.dylib!clang::DirectoryLookup::LookupFile(llvm::StringRef&, clang::HeaderSearch&, clang::SourceLocation, llvm::SmallVectorImpl<char>*, llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, bool&, bool&, bool&, llvm::SmallVectorImpl<char>&) const"
"0x11435213d libclang.dylib!clang::HeaderSearch::LookupFile(llvm::StringRef, clang::SourceLocation, bool, clang::detail::SearchDirIteratorImpl<true>, clang::detail::SearchDirIteratorImpl<true>*, llvm::ArrayRef<std::__1::pair<clang::FileEntry const*, clang::DirectoryEntry const*> >, llvm::SmallVectorImpl<char>*, llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, bool*, bool*, bool, bool)"
"0x114395e4f libclang.dylib!clang::Preprocessor::LookupFile(clang::SourceLocation, llvm::StringRef, bool, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*, clang::detail::SearchDirIteratorImpl<true>*, llvm::SmallVectorImpl<char>*, llvm::SmallVectorImpl<char>*, clang::ModuleMap::KnownHeader*, bool*, bool*, bool)"
"0x1143b53f3 libclang.dylib!EvaluateHasIncludeCommon(clang::Token&, clang::IdentifierInfo*, clang::Preprocessor&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)"
"0x1143b21f5 libclang.dylib!clang::Preprocessor::ExpandBuiltinMacro(clang::Token&)"
"0x1143b09c6 libclang.dylib!clang::Preprocessor::HandleMacroExpandedIdentifier(clang::Token&, clang::MacroDefinition const&)"
"0x1143cea85 libclang.dylib!clang::Preprocessor::HandleIdentifier(clang::Token&)"
"0x11436be94 libclang.dylib!clang::Lexer::LexTokenInternal(clang::Token&, bool)"

不泄漏的场景

open

"valid 207 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/stdint.h"
"0x1160e687b libclang.dylib!llvm::sys::fs::openFile(llvm::Twine const&, int&, llvm::sys::fs::CreationDisposition, llvm::sys::fs::FileAccess, llvm::sys::fs::OpenFlags, unsigned int)"
"0x1160e4bfe libclang.dylib!llvm::sys::fs::openFileForRead(llvm::Twine const&, int&, llvm::sys::fs::OpenFlags, llvm::SmallVectorImpl<char>*)"
"0x1160e692b libclang.dylib!llvm::sys::fs::openNativeFileForRead(llvm::Twine const&, llvm::sys::fs::OpenFlags, llvm::SmallVectorImpl<char>*)"
"0x1160b6f62 libclang.dylib!(anonymous namespace)::RealFileSystem::openFileForRead(llvm::Twine const&)"
"0x1140179fb libclang.dylib!clang::FileSystemStatCache::get(llvm::StringRef, llvm::vfs::Status&, bool, std::__1::unique_ptr<llvm::vfs::File, std::__1::default_delete<llvm::vfs::File> >*, clang::FileSystemStatCache*, llvm::vfs::FileSystem&)"
"0x1140140fb libclang.dylib!clang::FileManager::getStatValue(llvm::StringRef, llvm::vfs::Status&, bool, std::__1::unique_ptr<llvm::vfs::File, std::__1::default_delete<llvm::vfs::File> >*)"
"0x1140144d9 libclang.dylib!clang::FileManager::getFileRef(llvm::StringRef, bool, bool)"
"0x11434fe10 libclang.dylib!clang::HeaderSearch::getFileAndSuggestModule(llvm::StringRef, clang::SourceLocation, clang::DirectoryEntry const*, bool, clang::Module*, clang::ModuleMap::KnownHeader*)"
"0x11435066e libclang.dylib!clang::DirectoryLookup::LookupFile(llvm::StringRef&, clang::HeaderSearch&, clang::SourceLocation, llvm::SmallVectorImpl<char>*, llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, bool&, bool&, bool&, llvm::SmallVectorImpl<char>&) const"
"0x11435213d libclang.dylib!clang::HeaderSearch::LookupFile(llvm::StringRef, clang::SourceLocation, bool, clang::detail::SearchDirIteratorImpl<true>, clang::detail::SearchDirIteratorImpl<true>*, llvm::ArrayRef<std::__1::pair<clang::FileEntry const*, clang::DirectoryEntry const*> >, llvm::SmallVectorImpl<char>*, llvm::SmallVectorImpl<char>*, clang::Module*, clang::ModuleMap::KnownHeader*, bool*, bool*, bool, bool)"
"0x114395e4f libclang.dylib!clang::Preprocessor::LookupFile(clang::SourceLocation, llvm::StringRef, bool, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*, clang::detail::SearchDirIteratorImpl<true>*, llvm::SmallVectorImpl<char>*, llvm::SmallVectorImpl<char>*, clang::ModuleMap::KnownHeader*, bool*, bool*, bool)"
"0x11439e41f libclang.dylib!clang::Preprocessor::LookupHeaderIncludeOrImport(clang::detail::SearchDirIteratorImpl<true>*, llvm::StringRef&, clang::SourceLocation, clang::CharSourceRange, clang::Token const&, bool&, bool, bool&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*, llvm::StringRef&, llvm::SmallVectorImpl<char>&, llvm::SmallVectorImpl<char>&, clang::ModuleMap::KnownHeader&, bool)"
"0x11439cdb9 libclang.dylib!clang::Preprocessor::HandleHeaderIncludeOrImport(clang::SourceLocation, clang::Token&, clang::Token&, clang::SourceLocation, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)"
"0x114396f14 libclang.dylib!clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation, clang::Token&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)"
"0x114397a15 libclang.dylib!clang::Preprocessor::HandleDirective(clang::Token&)"
"0x11436bdeb libclang.dylib!clang::Lexer::LexTokenInternal(clang::Token&, bool)"

close

"close 207 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/stdint.h"
"0x1160e82bc libclang.dylib!llvm::sys::Process::SafelyCloseFileDescriptor(int)"
"0x1160b815c libclang.dylib!(anonymous namespace)::RealFile::~RealFile()"
"0x114015d00 libclang.dylib!clang::FileManager::getBufferForFile(clang::FileEntry const*, bool, bool)"
"0x114032cd6 libclang.dylib!clang::SrcMgr::ContentCache::getBufferOrNone(clang::DiagnosticsEngine&, clang::FileManager&, clang::SourceLocation) const"
"0x1143a9438 libclang.dylib!clang::Preprocessor::EnterSourceFile(clang::FileID, clang::detail::SearchDirIteratorImpl<true>, clang::SourceLocation, bool)"
"0x11439e101 libclang.dylib!clang::Preprocessor::HandleHeaderIncludeOrImport(clang::SourceLocation, clang::Token&, clang::Token&, clang::SourceLocation, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)"
"0x114396f14 libclang.dylib!clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation, clang::Token&, clang::detail::SearchDirIteratorImpl<true>, clang::FileEntry const*)"
"0x114397a15 libclang.dylib!clang::Preprocessor::HandleDirective(clang::Token&)"
"0x11436bdeb libclang.dylib!clang::Lexer::LexTokenInternal(clang::Token&, bool)"
"0x1143cf0e9 libclang.dylib!clang::Preprocessor::Lex(clang::Token&)"