You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MacOS下C++编写Dylib注入后无通知输出问题求助

问题:MacOS下注入Dylib后无法显示通知

在MacOS上编写C++动态库(.dylib),期望通过DYLD_INSERT_LIBRARIES注入目标进程后显示系统通知,但程序无错误输出也无通知弹出。尝试过system调用osascript、Objective-C实现通知逻辑,均未生效。

代码实现

main.cpp

#include <cstdio>
#include <syslog.h>
#include <iostream>
#include <unistd.h>
#include <mach/mach.h>
#include <mach-o/dyld.h>
#include "NotificationHelper.h"
#include <cstdlib>

void displayNotification(const char* message) {
    std::string command = "osascript -e 'display notification \"";
    command += message;
    command += "\" with title \"Notification from dylib\"'";
    system(command.c_str());
}

__attribute__((constructor))
static void beckett() {
    displayNotification("Hello from dylib");
}

NotificationHelper.h

#ifndef NotificationHelper_h
#define NotificationHelper_h

void displayNotification(const char* message);

#endif /* NotificationHelper_h */

编译与注入方式

编译命令:

g++ -dynamiclib -framework Foundation main.cpp -o libNotify.dylib

注入命令:

DYLD_INSERT_LIBRARIES=./libNotify.dylib /path/to/target/program

问题排查与解决方案

1. 核心问题分析

  • 构造函数执行时机过早:__attribute__((constructor))标记的函数会在进程初始化早期执行,此时目标进程可能未完成环境变量初始化,system调用无法正确启动osascript进程。
  • Sandbox限制:若注入到受Sandbox保护的进程(如Safari、系统自带应用),Sandbox会拦截子进程创建操作,导致osascript被禁止执行,无任何反馈。

2. 可行解决方案

方案一:用Objective-C++直接调用系统通知API(推荐)

将main.cpp后缀改为main.mm(转为C++/Objective-C混合文件),直接调用Foundation框架的通知接口,无需创建子进程:

#include <cstdio>
#include <syslog.h>
#include <unistd.h>
#include <Foundation/Foundation.h>

__attribute__((constructor))
static void beckett() {
    @autoreleasepool {
        NSUserNotification *notification = [[NSUserNotification alloc] init];
        notification.title = @"Notification from dylib";
        notification.informativeText = @"Hello from dylib";
        notification.soundName = NSUserNotificationDefaultSoundName;
        
        [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
    }
}

编译命令保持不变:

g++ -dynamiclib -framework Foundation main.mm -o libNotify.dylib

方案二:延迟执行通知逻辑

若必须使用system调用,可通过线程延迟执行,确保进程环境初始化完成:

#include <cstdio>
#include <syslog.h>
#include <unistd.h>
#include <cstdlib>
#include <pthread.h>

void* delayedNotification(void*) {
    sleep(3); // 延迟3秒,等待进程环境初始化
    std::string command = "osascript -e 'display notification \"Hello from dylib\" with title \"Notification from dylib\"'";
    system(command.c_str());
    return nullptr;
}

__attribute__((constructor))
static void beckett() {
    pthread_t thread;
    pthread_create(&thread, nullptr, delayedNotification, nullptr);
    pthread_detach(thread);
}

3. 调试验证技巧

  • 确认Dylib是否被加载执行:在构造函数中添加系统日志输出,通过「控制台.app」查看日志:
    openlog("DylibNotify", LOG_PID | LOG_CONS, LOG_USER);
    syslog(LOG_INFO, "Dylib loaded and constructor executed");
    closelog();
    
  • 单独测试通知命令:直接在终端运行osascript命令,验证通知功能本身是否正常:
    osascript -e 'display notification "Hello from dylib" with title "Notification from dylib"'
    

内容的提问来源于stack exchange,提问作者J.O.S.H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 17:27:30