我正在学习为 macOS 编写 EndpointSecurity 客户端。 客户端正在运行,并观察来自“/”(root)的所有路径的所有通知,因为它以 root 身份运行。我已将所有系统路径静音。
我需要的是观察 /Users/anoopvaidya 的路径以了解任何文件更改。但这永远不会发生,我错过了什么?
我了解到,如果有多个通知,它可能会在队列中被跳过。
那么有没有办法将除目标之外的所有人静音?
非常感谢任何线索/指导。
完整代码如下:
static void handleEvent(es_client_t *client, const es_message_t *msg)
{
char const *filePath = msg->process->executable->path.data;
NSString *filePathString = [[NSString alloc] initWithFormat:@"%s", filePath];
// TODO: need to check the user who logged in, is this possible?
NSString *path = [NSString stringWithFormat:@"/Users/%@/Documents", @"anoopvaidya"];
os_log(OS_LOG_DEFAULT, "filePathString = %@, path = %@", filePathString, path);
// check if the events are from path
if ([filePathString hasPrefix:path]) {
os_log(OS_LOG_DEFAULT, "Compare - filePathString = %@, path = %@", filePathString, path);
os_log(OS_LOG_DEFAULT, "proceeding...");
}
else {
return;
}
switch (msg->event_type) {
case ES_EVENT_TYPE_NOTIFY_EXEC:
os_log(OS_LOG_DEFAULT, "%{public}s (pid: %d) | EXEC: New image: %{public}s",
msg->process->executable->path.data,
audit_token_to_pid(msg->process->audit_token),
msg->event.exec.target->executable->path.data);
break;
case ES_EVENT_TYPE_NOTIFY_FORK:
os_log(OS_LOG_DEFAULT, "%{public}s (pid: %d) | FORK: Child pid: %d",
msg->process->executable->path.data,
audit_token_to_pid(msg->process->audit_token),
audit_token_to_pid(msg->event.fork.child->audit_token));
break;
case ES_EVENT_TYPE_NOTIFY_EXIT:
os_log(OS_LOG_DEFAULT, "%{public}s (pid: %d) | EXIT: status: %d",
msg->process->executable->path.data,
audit_token_to_pid(msg->process->audit_token),
msg->event.exit.stat);
break;
case ES_EVENT_TYPE_NOTIFY_OPEN:
os_log(OS_LOG_DEFAULT, "Open event");
break;
case ES_EVENT_TYPE_NOTIFY_CLOSE:
os_log(OS_LOG_DEFAULT, "Close event");
break;
default:
os_log_error(OS_LOG_DEFAULT, "Unexpected event type encountered: %d\n", msg->event_type);
break;
}
}
void mutePath(es_client_t *client) {
NSArray<NSString *> *paths = @[
@"/bin/", @"/private/", @"/Applications/",
@"/var/", @"/cores/", @"/dev/", @"/opt/", @"/private/", @"/System/", @"/Library/",
@"/sbin/", @"/usr/"
];
for (NSString *e in paths) {
es_mute_path_prefix(client, [e UTF8String]);
}
}
int main(int argc, char *argv[])
{
// Create the client
es_client_t *client = NULL;
es_new_client_result_t newClientResult = es_new_client(&client, ^(es_client_t *c, const es_message_t *message) {
handleEvent(client, message);
});
if (newClientResult != ES_NEW_CLIENT_RESULT_SUCCESS) {
return 1;
}
mutePath(client);
es_event_type_t events[] = {
ES_EVENT_TYPE_NOTIFY_CREATE, //create file
ES_EVENT_TYPE_NOTIFY_OPEN, // open file
ES_EVENT_TYPE_NOTIFY_RENAME, // rename file
ES_EVENT_TYPE_NOTIFY_CLOSE, // close file
ES_EVENT_TYPE_NOTIFY_WRITE, // write to file
ES_EVENT_TYPE_NOTIFY_UNLINK, // delete
ES_EVENT_TYPE_NOTIFY_EXIT };
if (es_subscribe(client, events, sizeof(events) / sizeof(events[0])) != ES_RETURN_SUCCESS) {
os_log(OS_LOG_DEFAULT, "Failed to subscribe to events");
es_delete_client(client);
return 1;
}
dispatch_main();
}
有一种方法可以做到这一点,即使用 es_invert_muting() 函数(在 MacOS 13.0 及更高版本中可用)。
你可以这样做:
es_unmute_all_target_paths(client)
es_invert_muting(client, ES_MUTE_INVERSION_TYPE_TARGET_PATH)
es_mute_path(client, path, ES_MUTE_PATH_TYPE_TARGET_PREFIX)
这会删除默认的静音列表,“反转”静音逻辑,因此仅选择静音路径,然后选择一个路径 p[refix 进行监视。
请注意,ES_MUTE_PATH_TYPE_PREFIX 和 ES_MUTE_PATH_TYPE_TARGET_PREFIX 之间存在差异。前者是指触发事件的可执行文件的路径,后者是被访问的文件的路径。