-
Notifications
You must be signed in to change notification settings - Fork 35
/
BTM.m
executable file
·174 lines (138 loc) · 4.44 KB
/
BTM.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
//
// BTM.m
// KnockKnock
//
// Created by Patrick Wardle on 6/26/23.
// Copyright (c) 2023 Objective-See. All rights reserved.
#import "BTM.h"
#import "File.h"
#import "dumpBTM.h"
#import "Utilities.h"
//plugin name
#define PLUGIN_NAME @"Background Managed Tasks"
//plugin description
#define PLUGIN_DESCRIPTION NSLocalizedString(@"background agents, daemons, & login items", @"background agents, daemons, & login items")
//plugin icon
#define PLUGIN_ICON @"btmIcon"
@implementation BTM
//init
// set name, description, etc
-(id)init
{
//super
self = [super init];
if(self)
{
//set name
self.name = PLUGIN_NAME;
//set description
self.description = PLUGIN_DESCRIPTION;
//set icon
self.icon = PLUGIN_ICON;
}
return self;
}
//scan for btm items
-(void)scan
{
//only available on macOS 13+
if(@available(macOS 13, *))
{
//contents
NSDictionary* contents = nil;
//items
NSMutableDictionary* items = nil;
//items sorted
NSArray* itemsSorted = nil;
//paths (for dups)
NSMutableSet* paths = nil;
//parse BTM db
contents = parseBTM(nil);
if(noErr != [contents[KEY_BTM_ERROR] integerValue])
{
//error
goto bail;
}
//init
items = [NSMutableDictionary dictionary];
//init
paths = [NSMutableSet set];
//iterate over all items
// sorted by each user uuid
for(NSString* uuid in contents[KEY_BTM_ITEMS_BY_USER_ID])
{
//iterate over each item
for(NSDictionary* item in contents[KEY_BTM_ITEMS_BY_USER_ID][uuid])
{
//File obj
File* fileObj = nil;
//params to init file object
NSMutableDictionary* parameters = nil;
//path
NSString* path = nil;
//plist
NSString* plist = nil;
//params
parameters = [NSMutableDictionary dictionary];
//ignore any items that have "embeddded item ids"
// these seem to be parents, and not the actual items persisted
if(nil != item[KEY_BTM_ITEM_EMBEDDED_IDS])
{
//skip
continue;
}
//executable path
path = item[KEY_BTM_ITEM_EXE_PATH];
if(nil == path)
{
//no path
// skip item
continue;
}
//(optional) plist
plist = item[KEY_BTM_ITEM_PLIST_PATH];
//init params w/ self
parameters[KEY_RESULT_PLUGIN] = self;
//init params w/ path
parameters[KEY_RESULT_PATH] = path;
//got plist?
if(nil != plist)
{
//init params w/ plist
parameters[KEY_RESULT_PLIST] = plist;
}
//init file obj with params (path, etc)
fileObj = [[File alloc] initWithParams:parameters];
if(nil == fileObj)
{
//error
// skip item
continue;
}
//new?
// save
if(YES != [paths containsObject:fileObj.path])
{
//save path
[paths addObject:fileObj.path];
//save
items[item[KEY_BTM_ITEM_UUID]] = fileObj;
}
}
}
//sort by name
itemsSorted = [[items allValues] sortedArrayUsingComparator:^NSComparisonResult(File* itemOne, File* itemTwo) {
return [itemOne.name compare:itemTwo.name];
}];
//add each to UI
for(File* item in itemsSorted)
{
//process item
// save and report to UI
[super processItem:item];
}
bail:
return;
}//macOS 13+
}
@end