diff --git a/KnockKnock.xcodeproj/project.pbxproj b/KnockKnock.xcodeproj/project.pbxproj index 868247f..5994123 100755 --- a/KnockKnock.xcodeproj/project.pbxproj +++ b/KnockKnock.xcodeproj/project.pbxproj @@ -968,7 +968,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 2.4.0; + CURRENT_PROJECT_VERSION = 2.4.1; DEVELOPMENT_TEAM = VBG97UB4TA; ENABLE_HARDENED_RUNTIME = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -985,7 +985,7 @@ "$(PROJECT_DIR)/Libraries/BTM", ); MACOSX_DEPLOYMENT_TARGET = 10.11; - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = KnockKnock; @@ -1002,7 +1002,7 @@ CODE_SIGN_IDENTITY = "Developer ID Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 2.4.0; + CURRENT_PROJECT_VERSION = 2.4.1; DEVELOPMENT_TEAM = VBG97UB4TA; ENABLE_HARDENED_RUNTIME = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -1019,7 +1019,7 @@ "$(PROJECT_DIR)/Libraries/BTM", ); MACOSX_DEPLOYMENT_TARGET = 10.11; - MARKETING_VERSION = 2.4.0; + MARKETING_VERSION = 2.4.1; ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.objective-see.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = KnockKnock; diff --git a/Libraries/BTM/dumpBTM.h b/Libraries/BTM/dumpBTM.h index 77d8b76..07c2632 100644 --- a/Libraries/BTM/dumpBTM.h +++ b/Libraries/BTM/dumpBTM.h @@ -24,18 +24,16 @@ #define KEY_BTM_ITEM_DISPOSITION_DETAILS @"dispositionDetails" #define KEY_BTM_ITEM_ID @"id" #define KEY_BTM_ITEM_URL @"url" -#define KEY_BTM_ITEM_EXE_PATH @"exePath" #define KEY_BTM_ITEM_GENERATION @"generation" #define KEY_BTM_ITEM_BUNDLE_ID @"bundleID" #define KEY_BTM_ITEM_ASSOCIATED_IDS @"associatedBundleIDs" #define KEY_BTM_ITEM_PARENT_ID @"parentID" #define KEY_BTM_ITEM_EMBEDDED_IDS @"embeddedIDs" +#define KEY_BTM_ITEM_PLIST_PATH @"plistPath" +#define KEY_BTM_ITEM_EXE_PATH @"executablePath" + //APIs // note: path is optional NSInteger dumpBTM(NSURL* path); NSDictionary* parseBTM(NSURL* path); - - - - diff --git a/Libraries/BTM/libDumpBTM.a b/Libraries/BTM/libDumpBTM.a index 6b50ed5..6a3e82e 100644 Binary files a/Libraries/BTM/libDumpBTM.a and b/Libraries/BTM/libDumpBTM.a differ diff --git a/Plugins/BTM.m b/Plugins/BTM.m index 10945c4..5ece375 100755 --- a/Plugins/BTM.m +++ b/Plugins/BTM.m @@ -48,7 +48,6 @@ -(void)scan //only available on macOS 13+ if(@available(macOS 13, *)) { - //contents NSDictionary* contents = nil; @@ -61,9 +60,6 @@ -(void)scan //paths (for dups) NSMutableSet* paths = nil; - //parents - NSMutableArray* parents = nil; - //parse BTM db contents = parseBTM(nil); if(noErr != [contents[KEY_BTM_ERROR] integerValue]) @@ -74,10 +70,7 @@ -(void)scan //init items = [NSMutableDictionary dictionary]; - - //init - parents = [NSMutableArray array]; - + //init paths = [NSMutableSet set]; @@ -91,8 +84,8 @@ -(void)scan //File obj File* fileObj = nil; - //type - NSUInteger type = 0; + //params to init file object + NSMutableDictionary* parameters = nil; //path NSString* path = nil; @@ -100,99 +93,52 @@ -(void)scan //plist NSString* plist = nil; - //parent identifier - NSString* parentID = nil; - - //extract type - type = [item[KEY_BTM_ITEM_TYPE] unsignedIntegerValue]; + //params + parameters = [NSMutableDictionary dictionary]; //ignore any items that have "embeddded item ids" - // these seems to be parents, and not the actual items persisted + // these seem to be parents, and not the actual items persisted if(nil != item[KEY_BTM_ITEM_EMBEDDED_IDS]) { //skip continue; } - //agent / daemon - if( (type & 0x8) || - (type & 0x10) ) + //executable path + path = item[KEY_BTM_ITEM_EXE_PATH]; + if(nil == path) { - //path - path = item[KEY_BTM_ITEM_EXE_PATH]; - - //plist - plist = [item[KEY_BTM_ITEM_URL] path]; + //no path + // skip item + continue; } - //login item - // don't have full path, so construct via parent - else if(type & 0x4) - { - //parent id - parentID = item[KEY_BTM_ITEM_PARENT_ID]; - - //find parent - for(NSDictionary* parent in contents[KEY_BTM_ITEMS_BY_USER_ID][uuid]) - { - //no match? - if(YES != [parent[KEY_BTM_ITEM_ID] isEqualToString:parentID]) - { - //skip - continue; - } - - //path = parent URL + login item URL - path = [NSString stringWithFormat:@"%@%@", [parent[KEY_BTM_ITEM_URL] path], [item[KEY_BTM_ITEM_URL] path]]; - - //update path from app's bundle to executable - path = [[NSBundle bundleWithPath:path] executablePath]; - - //save parent uuid - [parents addObject:parent[KEY_BTM_ITEM_UUID]]; - - //done - break; - } - } + //(optional) plist + plist = item[KEY_BTM_ITEM_PLIST_PATH]; - //app - else if(type & 0x2) - { - //extract path - path = [item[KEY_BTM_ITEM_URL] path]; - - //update path from app's bundle to executable - path = [[NSBundle bundleWithPath:path] executablePath]; - } + //init params w/ self + parameters[KEY_RESULT_PLUGIN] = self; - //sanity check - if( (nil == path) && - (nil == plist) ) - { - //next - continue; - } + //init params w/ path + parameters[KEY_RESULT_PATH] = path; - //plist nil - // ...will for non agents/daemons - if(nil == plist) + //got plist? + if(nil != plist) { - //init w/o plist - fileObj = [[File alloc] initWithParams:@{KEY_RESULT_PLUGIN:self, KEY_RESULT_PATH:path}]; - } - else - { - fileObj = [[File alloc] initWithParams:@{KEY_RESULT_PLUGIN:self, KEY_RESULT_PATH:path, KEY_RESULT_PLIST:plist}]; + //init params w/ plist + parameters[KEY_RESULT_PLIST] = plist; } - //error in init? + //init file obj with params (path, etc) + fileObj = [[File alloc] initWithParams:parameters]; if(nil == fileObj) { + //error + // skip item continue; } - //new + //new? // save if(YES != [paths containsObject:fileObj.path]) { @@ -202,17 +148,9 @@ -(void)scan //save items[item[KEY_BTM_ITEM_UUID]] = fileObj; } - } } - //remove all parents - for(NSString* key in parents) - { - //remove - [items removeObjectForKey:key]; - } - //sort by name itemsSorted = [[items allValues] sortedArrayUsingComparator:^NSComparisonResult(File* itemOne, File* itemTwo) { return [itemOne.name compare:itemTwo.name];