diff --git a/AppDelegate.h b/AppDelegate.h index 203a0e2..492715c 100755 --- a/AppDelegate.h +++ b/AppDelegate.h @@ -85,9 +85,6 @@ //spinner @property (weak) IBOutlet NSProgressIndicator *progressIndicator; -//status msg -@property (weak) IBOutlet NSTextField *statusText; - //non-UI thread that performs actual scan @property(nonatomic, strong)NSThread *scannerThread; @@ -166,6 +163,15 @@ //custom search field for items @property(nonatomic, retain)CustomTextField* customItemsFilter; +//overlay view for filter +@property (weak) IBOutlet NSView *filteringOverlay; + +//activity indicator for filtering +@property (weak) IBOutlet NSProgressIndicator *filteringIndicator; + +//message for filtering +@property (weak) IBOutlet NSTextField *filteringMessage; + /* METHODS */ //complete a few inits @@ -236,6 +242,12 @@ // ->handle auto-complete filterings -(void)filterAutoComplete:(NSTextView*)textField; +//show the filter overlay, etc +-(void)prepUIForFiltering:(NSUInteger)pane; + +//hide overlay, etc +-(void)unprepUIForFiltering; + //code to complete filtering/search // ->reload table/scroll to top etc -(void)finalizeFiltration:(NSUInteger)pane; diff --git a/AppDelegate.m b/AppDelegate.m index 275feb1..a89a93a 100755 --- a/AppDelegate.m +++ b/AppDelegate.m @@ -41,9 +41,12 @@ @synthesize taskViewFormat; @synthesize commandHandling; @synthesize completePosting; +@synthesize filteringMessage; +@synthesize filteringOverlay; @synthesize customItemsFilter; @synthesize customTasksFilter; @synthesize progressIndicator; +@synthesize filteringIndicator; @synthesize taskTableController; @synthesize bottomViewController; @synthesize aboutWindowController; @@ -76,6 +79,9 @@ // ->install exception handlers! installExceptionHandlers(); + //for autolayout + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"]; + //init virus total object virusTotalObj = [[VirusTotal alloc] init]; @@ -690,6 +696,9 @@ bail: //stop progress indicator [self.bottomPaneSpinner stopAnimation:nil]; + //hide + self.bottomPaneSpinner.hidden = YES; + //invoke refresh [(id)self.bottomViewController reloadTable]; @@ -698,7 +707,6 @@ bail: { //how self.noItemsLabel.hidden = NO; - } //got items? else @@ -1439,6 +1447,9 @@ bail: //reload to clear [(id)self.bottomViewController reloadTable]; + //show spinner + self.bottomPaneSpinner.hidden = NO; + //start progress indicator [self.bottomPaneSpinner startAnimation:nil]; @@ -1451,6 +1462,9 @@ bail: //reload to clear [(id)self.bottomViewController reloadTable]; + //start spinner + self.bottomPaneSpinner.hidden = NO; + //start progress indicator [self.bottomPaneSpinner startAnimation:nil]; } @@ -1467,6 +1481,13 @@ bail: //remove all task's dylibs [self.currentTask.dylibs removeAllObjects]; + //skip kernel + if(0 == self.currentTask.pid.intValue) + { + //skip + break; + } + //(re)enumerate dylibs via XPC // ->triggers table reload when done [self.currentTask enumerateDylibs:self.taskEnumerator.dylibs]; @@ -1482,6 +1503,13 @@ bail: //remove all task's dylibs [self.currentTask.files removeAllObjects]; + //skip kernel + if(0 == self.currentTask.pid.intValue) + { + //skip + break; + } + //(re)enumerate files via XPC // ->triggers table reload when done [self.currentTask enumerateFiles]; @@ -1494,6 +1522,13 @@ bail: //init placeholder text for network filterPlaceholder = @"Filter Connections"; + //skip kernel + if(0 == self.currentTask.pid.intValue) + { + //skip + break; + } + //(re)enumerate network connections via XPC // ->triggers table reload when done [self.currentTask enumerateNetworking]; @@ -1514,6 +1549,15 @@ bail: //set placeholder [[self.filterItemsBox cell] setPlaceholderString:filterPlaceholder]; + + //kernel + // ->didn't enum so reload + if(0 == self.currentTask.pid.intValue) + { + //reload + [self reloadBottomPane:self.currentTask itemView:segmentTag]; + } + }); } //in main thread already @@ -1522,12 +1566,18 @@ bail: { //set placeholder [[self.filterItemsBox cell] setPlaceholderString:filterPlaceholder]; + + //kernel + // ->didn't enum so reload + if(0 == self.currentTask.pid.intValue) + { + //reload + [self reloadBottomPane:self.currentTask itemView:segmentTag]; + } } - //bail bail: - return; } @@ -1680,10 +1730,129 @@ bail: return; } +//config/show the filter overlay +// ->also disable all inputs/buttons +-(void)prepUIForFiltering:(NSUInteger)pane +{ + //pre-req + [self.filteringOverlay setWantsLayer:YES]; + + //rounded corners + self.filteringOverlay.layer.cornerRadius = 20.0; + + //maks + self.filteringOverlay.layer.masksToBounds = YES; + + //set overlay's view color to black + self.filteringOverlay.layer.backgroundColor = [NSColor grayColor].CGColor; + + //make it semi-transparent + self.filteringOverlay.alphaValue = 0.95; + + //show overlay + self.filteringOverlay.hidden = NO; + + //set text + // top pane + if(PANE_TOP == pane) + { + //set text + self.filteringMessage.stringValue = [NSString stringWithFormat:@"filtering tasks (%@)", self.filterTasksBox.stringValue]; + } + //set text + // bottom pane + else + { + //set text + self.filteringMessage.stringValue = [NSString stringWithFormat:@"filtering dylibs (%@)", self.filterItemsBox.stringValue]; + } + + //start spinner + [self.filteringIndicator startAnimation:nil]; + + //disable view switcher + self.viewSelector.enabled = NO; + + //disable filter box + self.filterTasksBox.enabled = NO; + + //disable bottom pane switcher + self.bottomPaneBtn.enabled = NO; + + //disable bottom filter item box + self.filterItemsBox.enabled = NO; + + //disable refresh + self.refreshButton.enabled = NO; + + //disable search + self.searchButton.enabled = NO; + + //disable save + self.saveButton.enabled = NO; + + //disable flagged + self.flaggedButton.enabled = NO; + + //disable task table + self.taskTableController.itemView.enabled = NO; + + //disable item table + self.bottomViewController.itemView.enabled = NO; + + return; +} + +//roll back changes to UI due to filtering +// ->hide overlay and enable all inputs/buttons +-(void)unprepUIForFiltering +{ + //always (attempt to) hide filter overlay + self.filteringOverlay.hidden = YES; + + //stop spinner + [self.filteringIndicator stopAnimation:nil]; + + //enable view switcher + self.viewSelector.enabled = YES; + + //enable filter box + self.filterTasksBox.enabled = YES; + + //enable bottom pane switcher + self.bottomPaneBtn.enabled = YES; + + //enable bottom filter item box + self.filterItemsBox.enabled = YES; + + //enable refresh + self.refreshButton.enabled = YES; + + //enable search + self.searchButton.enabled = YES; + + //enable save + self.saveButton.enabled = YES; + + //enable flagged + self.flaggedButton.enabled = YES; + + //enable task table + self.taskTableController.itemView.enabled = YES; + + //enable item table + self.bottomViewController.itemView.enabled = YES; + + return; +} + //code to complete filtering/search // ->reload table/scroll to top etc -(void)finalizeFiltration:(NSUInteger)pane { + //hide overlay, etc + [self unprepUIForFiltering]; + //top pane (task) if(PANE_TOP == pane) { @@ -1982,32 +2151,48 @@ bail: //set iVar flag self.commandHandling = YES; - //init invocation - textViewInvocationForSelector = [NSInvocation invocationWithMethodSignature:[textView methodSignatureForSelector:commandSelector]]; - - //set target - [textViewInvocationForSelector setTarget:textView]; - - //set selector - [textViewInvocationForSelector setSelector:commandSelector]; - - //invoke selector - [textViewInvocationForSelector invoke]; - - //unset iVar - self.commandHandling = NO; - - //indicate that selector was performed - didPerformRequestedSelectorOnTextView = YES; - + //handle 'enter' + // ->but only for #'s + if( (commandSelector == @selector(insertNewline:)) && + (YES == [filterObj isKeyword:textView.string]) ) + { + //filter + [self filterAutoComplete:textView]; + + //unset iVar + self.commandHandling = NO; + + //set flag + didPerformRequestedSelectorOnTextView = YES; + } + //just invoke system handler for rest... + else + { + //init invocation + textViewInvocationForSelector = [NSInvocation invocationWithMethodSignature:[textView methodSignatureForSelector:commandSelector]]; + + //set target + [textViewInvocationForSelector setTarget:textView]; + + //set selector + [textViewInvocationForSelector setSelector:commandSelector]; + + //invoke selector + [textViewInvocationForSelector invoke]; + + //unset iVar + self.commandHandling = NO; + + //indicate that selector was performed + didPerformRequestedSelectorOnTextView = YES; + } //bail bail: return didPerformRequestedSelectorOnTextView; } - - + //callback for custom search fields // ->handle auto-complete filterings -(void)filterAutoComplete:(NSTextView*)textView @@ -2021,32 +2206,56 @@ bail: //handle top pane (tasks) if(textView == self.customTasksFilter) { + //set flag + self.taskTableController.isFiltered = YES; + //sync @synchronized(self.taskTableController.filteredItems) { + //remove all filtered tasks + [self.taskTableController.filteredItems removeAllObjects]; + + //update ui + [self finalizeFiltration:PANE_TOP]; + //filter [self.filterObj filterTasks:filterString items:self.taskEnumerator.tasks results:self.taskTableController.filteredItems]; } - //set flag - self.taskTableController.isFiltered = YES; - - //finalize filtering - [self finalizeFiltration:PANE_TOP]; - + //refresh/update UI when not a keyword search + // ->keyword search are done in background, and will call this directly when pau + if(YES != [filterString hasPrefix:@"#"]) + { + //finalize filtering + [self finalizeFiltration:PANE_TOP]; + } } //handle bottom pane // ->just dylibs else if(textView == self.customItemsFilter) { - //filter - [self.filterObj filterFiles:filterString items:self.currentTask.dylibs results:self.bottomViewController.filteredItems]; - //set flag self.bottomViewController.isFiltered = YES; - //finalize filtering - [self finalizeFiltration:PANE_BOTTOM]; + @synchronized (self.bottomViewController.filteredItems) + { + //remove all filtered tasks + [self.bottomViewController.filteredItems removeAllObjects]; + + //update ui + [self finalizeFiltration:PANE_BOTTOM]; + + //filter + [self.filterObj filterFiles:filterString items:self.currentTask.dylibs results:self.bottomViewController.filteredItems]; + } + + //refresh/update UI when not a keyword search + // ->keyword search are done in background, and will call this directly when pau + if(YES != [filterString hasPrefix:@"#"]) + { + //finalize filtering + [self finalizeFiltration:PANE_BOTTOM]; + } } //bail @@ -2081,14 +2290,10 @@ bail: //assign for return fieldEditor = self.customItemsFilter; } - - + //bail bail: return fieldEditor; } - - - @end diff --git a/CustomTextField.h b/CustomTextField.h index 9c45e60..558ada3 100644 --- a/CustomTextField.h +++ b/CustomTextField.h @@ -17,6 +17,10 @@ } //'owner' -@property (nonatomic, retain)id owner; +@property(nonatomic, retain)id owner; + +//last movement +// ->helps avoid 2x 'Enter' +@property NSInteger lastMovement; @end diff --git a/CustomTextField.m b/CustomTextField.m index 6b0ccab..8a936d0 100644 --- a/CustomTextField.m +++ b/CustomTextField.m @@ -12,6 +12,7 @@ @implementation CustomTextField @synthesize owner; +@synthesize lastMovement; //subclass override // ->see: http://stackoverflow.com/questions/5163646/how-to-make-nssearchfield-send-action-upon-autocompletion/5360535#5360535 @@ -24,6 +25,17 @@ goto bail; } + //ignore if 2x 'enter' + if( (movement == NSReturnTextMovement) && + (self.lastMovement == NSReturnTextMovement) ) + { + //bail + goto bail; + } + + //update + self.lastMovement = movement; + //show full replacements if(0 != charRange.location) { @@ -44,7 +56,6 @@ { //call up into owner to process [owner filterAutoComplete:self]; - //[((AppDelegate*)[[NSApplication sharedApplication] delegate]) filterAutoComplete:self]; } //bail @@ -53,4 +64,4 @@ bail: return; } -@end \ No newline at end of file +@end diff --git a/Filter.h b/Filter.h index e94412a..167483b 100644 --- a/Filter.h +++ b/Filter.h @@ -43,6 +43,9 @@ // ->determine if binary is packed -(BOOL)isPacked:(Binary*)item; +//keyword filter '#notfound' +-(BOOL)notFound:(Binary*)item; + //filter tasks -(void)filterTasks:(NSString*)filterText items:(NSMutableDictionary*)items results:(NSMutableArray*)results; diff --git a/Filter.m b/Filter.m index 10924e2..3a2ab04 100644 --- a/Filter.m +++ b/Filter.m @@ -5,15 +5,17 @@ // Created by Patrick Wardle on 2/21/15. // Copyright (c) 2015 Objective-See. All rights reserved. // + +#import "Task.h" #import "Consts.h" #import "Filter.h" -#import "Utilities.h" -#import "Task.h" #import "ItemBase.h" +#import "Utilities.h" #import "Connection.h" +#import "AppDelegate.h" //binary filter keywords -NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#unsigned", @"#flagged", @"#encrypted", @"#packed"}; +NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#unsigned", @"#flagged", @"#encrypted", @"#packed", @"#notfound"}; @implementation Filter @@ -49,32 +51,8 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un { //for now just check in binary keywords return [self.binaryFilters containsObject:searchString]; - - /* - //flag - BOOL isKeyword = NO; - - //iterate over all keywords - // ->check for match - for(NSUInteger i=0; i < sizeof(KEYWORDS)/sizeof(KEYWORDS[0]); i++) - { - //check - if(YES == [KEYWORDS[i] isEqualToString:searchString]) - { - //match - isKeyword = YES; - - //bail - break; - } - } - - return isKeyword; - */ - } - //filter tasks // ->name, path, pid -(void)filterTasks:(NSString*)filterText items:(NSMutableDictionary*)items results:(NSMutableArray*)results @@ -82,38 +60,44 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un //task Task* task = nil; - //flag for keyword filter - BOOL isKeyword = NO; - - //first reset filter'd items + //first reset any previous filter'd items [results removeAllObjects]; - //set keyword flag + //process #keyword filtering // ->note: already checked its a full/matching keyword - isKeyword = [filterText hasPrefix:@"#"]; - - //sync - @synchronized(items) + if(YES == [filterText hasPrefix:@"#"]) { - - //iterate over all tasks - for(NSNumber* taskKey in items) - { - //extract task - task = items[taskKey]; + //prep UI for filtering + // ->config/show overlay, etc + [((AppDelegate*)[[NSApplication sharedApplication] delegate]) prepUIForFiltering:PANE_TOP]; - //handle keyword filtering - if( (YES == isKeyword) && - (YES == [self binaryFulfillsKeyword:filterText binary:task.binary]) ) + //in background filter by keyword + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + //nap a 1/2second to let message show up + [NSThread sleepForTimeInterval:0.5]; + + //filter + // ->calls back in UI to refresh when done! + [self filterByKeyword:(NSString*)filterText items:items.allValues results:(NSMutableArray*)results]; + + }); + } + + //not keyword + // ->do normal search here... + else + { + //sync + @synchronized(items) { - //add - [results addObject:task]; - }//keywords - - //no keyword search - else + //iterate over all tasks + for(NSNumber* taskKey in items) { + //extract task + task = items[taskKey]; + //check path first // ->mostly likely to match if( (nil != task.binary.path) && @@ -146,12 +130,81 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un //next continue; } - } - }//all tasks - - }//sync + }//all tasks + }//sync + + }//normal filtering + + return; +} + +//filter tasks +// ->name, path, pid +-(void)filterByKeyword:(NSString*)filterText items:(NSArray*)items results:(NSMutableArray*)results +{ + //pane + NSUInteger pane = PANE_TOP; + + //sync + @synchronized(items) + { + //sanity check + if(0 == items.count) + { + //bail + goto bail; + } + + //handle tasks + if(YES == [items.firstObject isKindOfClass:[Task class]]) + { + //set pane + pane = PANE_TOP; + + //iterate over all items + for(id item in items) + { + //check if task's binary matches filter + if(YES == [self binaryFulfillsKeyword:filterText binary:((Task*)item).binary]) + { + //add + [results addObject:item]; + } + } + } + //handle dylibs + else if(YES == [items.firstObject isKindOfClass:[Binary class]]) + { + //set pane + pane = PANE_BOTTOM; + + //iterate over all items + for(id item in items) + { + //check if dylib's binary matches filter + if(YES == [self binaryFulfillsKeyword:filterText binary:((Binary*)item)]) + { + //add + [results addObject:item]; + } + } + } + + } //sync + + //tell the UI we are done + dispatch_async(dispatch_get_main_queue(), ^{ + + //finalize UI + [((AppDelegate*)[[NSApplication sharedApplication] delegate]) finalizeFiltration:pane]; + + }); + +//bail +bail: + return; } @@ -159,36 +212,41 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un // ->name and path -(void)filterFiles:(NSString*)filterText items:(NSMutableArray*)items results:(NSMutableArray*)results { - //flag for keyword filter - BOOL isKeyword = NO; - //first reset filter'd items [results removeAllObjects]; - //set keyword flag + //process #keyword filtering for dylibs // ->note: already checked its a full/matching keyword - isKeyword = [filterText hasPrefix:@"#"]; - - //sync - @synchronized(items) + if( (YES == [filterText hasPrefix:@"#"]) && + (YES == [items.firstObject isKindOfClass:[Binary class]]) ) { - - //iterate over all tasks - for(ItemBase* item in items) + //prep UI for filtering + // ->config/show overlay, etc + [((AppDelegate*)[[NSApplication sharedApplication] delegate]) prepUIForFiltering:PANE_BOTTOM]; + + //in background filter by keyword + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + + //nap a 1/2second to let message show up + [NSThread sleepForTimeInterval:0.5]; + + //filter + // ->calls back in UI to refresh when done! + [self filterByKeyword:(NSString*)filterText items:items results:(NSMutableArray*)results]; + + }); + } + + //not keyword + // ->do normal search here... + else { - //handle keyword filtering - // ->for now, only for dylibs (binaries) - if( (YES == [item isKindOfClass:[Binary class]]) && - (YES == isKeyword) && - (YES == [self binaryFulfillsKeyword:filterText binary:(Binary*)item]) ) + //sync + @synchronized(items) { - //add - [results addObject:item]; - }//keywords - - //no keyword search - else + //iterate over all items + for(ItemBase* item in items) { //check path first // ->most likely to match @@ -212,12 +270,12 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un //next continue; } - } + + }//all items + + }//sync - }//all items - - //sync - } + }//normal filtering return; } @@ -417,6 +475,16 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un goto bail; } + //handle '#notfound' + else if( (YES == [keyword isEqualToString:@"#notfound"]) && + (YES == [self notFound:binary]) ) + { + //happy + fulfills = YES; + + //bail + goto bail; + } //bail bail: @@ -533,4 +601,10 @@ bail: return item.isPacked; } +//keyword filter '#notfound' +-(BOOL)notFound:(Binary *)item +{ + return item.notFound; +} + @end diff --git a/FlaggedItemWindowController.m b/FlaggedItemWindowController.m index 7165be4..feed9c7 100644 --- a/FlaggedItemWindowController.m +++ b/FlaggedItemWindowController.m @@ -312,6 +312,9 @@ bail: //row NSInteger itemRow = 0; + //file open error alert + NSAlert* errorAlert = nil; + //grab sender's row itemRow = [self.flaggedItemTable rowForView:sender]; @@ -349,11 +352,18 @@ bail: goto bail; } - //open Finder - // ->will reveal binary - [[NSWorkspace sharedWorkspace] selectFile:path inFileViewerRootedAtPath:@""]; - - //bail + //open item in Finder + // ->error alert shown if file open fails + if(YES != [[NSWorkspace sharedWorkspace] selectFile:path inFileViewerRootedAtPath:@""]) + { + //alloc/init alert + errorAlert = [NSAlert alertWithMessageText:[NSString stringWithFormat:@"ERROR:\nfailed to open %@", path] defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"errno value: %d", errno]; + + //show it + [errorAlert runModal]; + } + +//bail bail: return; diff --git a/ItemView.m b/ItemView.m index 6881c3e..bd4e2fd 100644 --- a/ItemView.m +++ b/ItemView.m @@ -337,7 +337,7 @@ NSAttributedString* initBinaryString(id item, BOOL isSearchWindow) [taskString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@", " attributes:attributes]]; } //dylibs - // ->open parents + // ->open'(' else { //open @@ -362,6 +362,65 @@ NSAttributedString* initBinaryString(id item, BOOL isSearchWindow) [taskString appendAttributedString:[[NSAttributedString alloc] initWithString:@"packed" attributes:attributes]]; } + //dylib, need to close string here unless binary not found, then going to add that + // ->normally it doesn't have anything after... + if( (YES != [item isKindOfClass:[Task class]]) && + (YES != binary.notFound)) + { + //init color for closing + attributes = [NSDictionary dictionaryWithObject:[NSColor lightGrayColor] forKey:NSForegroundColorAttributeName]; + + //close string + [taskString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@")" attributes:attributes]]; + } + + }//encrypted or packed + + //add 'not found' + if(YES == binary.notFound) + { + //add ',' + if( (YES == binary.isEncrypted) || + (YES == binary.isPacked) ) + { + //init color for comma, + // ->light gray + attributes = [NSDictionary dictionaryWithObject:[NSColor lightGrayColor] forKey:NSForegroundColorAttributeName]; + + //add + [taskString appendAttributedString:[[NSAttributedString alloc] initWithString:@", " attributes:attributes]]; + } + //open string + else + { + //init color for comma, etc + // ->light gray + attributes = [NSDictionary dictionaryWithObject:[NSColor lightGrayColor] forKey:NSForegroundColorAttributeName]; + + //tasks + //add comma string + if(YES == [item isKindOfClass:[Task class]]) + { + //close + [taskString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@", " attributes:attributes]]; + } + //dylibs + // ->open'(' + else + { + //open + [taskString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@" (" attributes:attributes]]; + } + + } + + //init color + // ->red + attributes = [NSDictionary dictionaryWithObject:[NSColor redColor] forKey:NSForegroundColorAttributeName]; + + //add + [taskString appendAttributedString:[[NSAttributedString alloc] initWithString:@"not found" attributes:attributes]]; + //dylib, need to close string here // ->normally it doesn't have anything after... if(YES != [item isKindOfClass:[Task class]]) @@ -373,7 +432,7 @@ NSAttributedString* initBinaryString(id item, BOOL isSearchWindow) [taskString appendAttributedString:[[NSMutableAttributedString alloc] initWithString:@")" attributes:attributes]]; } - }//encrypted or packed + }//not found } //task diff --git a/Items/Binary.h b/Items/Binary.h index f8b57db..525442d 100644 --- a/Items/Binary.h +++ b/Items/Binary.h @@ -46,6 +46,9 @@ //packed flag @property BOOL isPacked; +//not found +@property BOOL notFound; + /* VIRUS TOTAL INFO */ //dictionary returned by VT diff --git a/Items/Binary.m b/Items/Binary.m index d94d7ae..9fbab4f 100644 --- a/Items/Binary.m +++ b/Items/Binary.m @@ -21,6 +21,7 @@ @synthesize parser; @synthesize vtInfo; @synthesize isPacked; +@synthesize notFound; @synthesize isEncrypted; @synthesize signingInfo; @synthesize isTaskBinary; @@ -47,6 +48,9 @@ // ->either from bundle or just use system icon self.icon = [self getIcon]; + //determine if its on disk + self.notFound = ![[NSFileManager defaultManager] fileExistsAtPath:self.path]; + //grab attributes //self.attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:self.path error:nil]; } @@ -73,7 +77,7 @@ bail: parser = [[MachO alloc] init]; //parse - if(YES != [self.parser parse:self.path]) + if(YES != [self.parser parse:self.path classify:YES]) { //unset parser self.parser = nil; diff --git a/NSApplicationKeyEvents.m b/NSApplicationKeyEvents.m index 5a1e2a1..d224d25 100644 --- a/NSApplicationKeyEvents.m +++ b/NSApplicationKeyEvents.m @@ -27,21 +27,12 @@ if ([self sendAction:@selector(paste:) to:nil from:self]) return; } - else if ([[event charactersIgnoringModifiers] isEqualToString:@"z"]) { - if ([self sendAction:@selector(undo:) to:nil from:self]) - return; - } else if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) { if ([self sendAction:@selector(selectAll:) to:nil from:self]) return; } } - else if (([event modifierFlags] & NSDeviceIndependentModifierFlagsMask) == (NSCommandKeyMask | NSShiftKeyMask)) { - if ([[event charactersIgnoringModifiers] isEqualToString:@"Z"]) { - if ([self sendAction:@selector(redo:) to:nil from:self]) - return; - } - } + } [super sendEvent:event]; } diff --git a/TaskEnumerator.m b/TaskEnumerator.m index 231c06f..c9c3832 100644 --- a/TaskEnumerator.m +++ b/TaskEnumerator.m @@ -195,6 +195,13 @@ //get task newTask = newTasks[key]; + //skip kernel + if(0 == newTask.pid.intValue) + { + //skip + continue; + } + //enumerate [newTask enumerateDylibs:self.dylibs]; @@ -210,6 +217,13 @@ //get task newTask = newTasks[key]; + //skip kernel + if(0 == newTask.pid.intValue) + { + //skip + continue; + } + //enumerate [newTask enumerateFiles]; @@ -225,6 +239,13 @@ //get task newTask = newTasks[key]; + //skip kernel + if(0 == newTask.pid.intValue) + { + //skip + continue; + } + //enumerate [newTask enumerateNetworking]; diff --git a/TaskExplorer.xcodeproj/project.pbxproj b/TaskExplorer.xcodeproj/project.pbxproj index 19be8dc..96b3ffc 100755 --- a/TaskExplorer.xcodeproj/project.pbxproj +++ b/TaskExplorer.xcodeproj/project.pbxproj @@ -670,7 +670,7 @@ 1D21BC43172AF43D009D1CFD /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0800; ORGANIZATIONNAME = "Lucas Derraugh"; TargetAttributes = { 1D21BC4A172AF43D009D1CFD = { @@ -886,17 +886,23 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)"; COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -906,7 +912,9 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; ONLY_ACTIVE_ARCH = YES; @@ -921,20 +929,28 @@ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; ONLY_ACTIVE_ARCH = YES; diff --git a/TaskExplorer.xcodeproj/project.xcworkspace/xcshareddata/TaskExplorer.xcscmblueprint b/TaskExplorer.xcodeproj/project.xcworkspace/xcshareddata/TaskExplorer.xcscmblueprint index b0bb6fb..9a4b8b4 100644 --- a/TaskExplorer.xcodeproj/project.xcworkspace/xcshareddata/TaskExplorer.xcscmblueprint +++ b/TaskExplorer.xcodeproj/project.xcworkspace/xcshareddata/TaskExplorer.xcscmblueprint @@ -9,8 +9,8 @@ }, "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "FE4103FE-6F26-4639-8C9F-D8D32C76D6A9", "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { - "61F07AFB33748EF0C810BEEF6126283DAC63A899" : "TaskExplorer", - "7564E3FECD3AE625755C217749E31B3EE2B69E20" : "machO\/" + "61F07AFB33748EF0C810BEEF6126283DAC63A899" : "TaskExplorer\/", + "7564E3FECD3AE625755C217749E31B3EE2B69E20" : "MachO\/" }, "DVTSourceControlWorkspaceBlueprintNameKey" : "TaskExplorer", "DVTSourceControlWorkspaceBlueprintVersion" : 204, diff --git a/TaskExplorer.xcodeproj/project.xcworkspace/xcuserdata/patrickw.xcuserdatad/UserInterfaceState.xcuserstate b/TaskExplorer.xcodeproj/project.xcworkspace/xcuserdata/patrickw.xcuserdatad/UserInterfaceState.xcuserstate index fba96b5..ce4eb58 100644 Binary files a/TaskExplorer.xcodeproj/project.xcworkspace/xcuserdata/patrickw.xcuserdatad/UserInterfaceState.xcuserstate and b/TaskExplorer.xcodeproj/project.xcworkspace/xcuserdata/patrickw.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/TaskExplorer.xcodeproj/xcuserdata/patrickw.xcuserdatad/xcschemes/TaskExplorer.xcscheme b/TaskExplorer.xcodeproj/xcuserdata/patrickw.xcuserdatad/xcschemes/TaskExplorer.xcscheme index 30281bd..db1c013 100644 --- a/TaskExplorer.xcodeproj/xcuserdata/patrickw.xcuserdatad/xcschemes/TaskExplorer.xcscheme +++ b/TaskExplorer.xcodeproj/xcuserdata/patrickw.xcuserdatad/xcschemes/TaskExplorer.xcscheme @@ -1,6 +1,6 @@ get task if(YES != self.isBottomPane) @@ -549,9 +552,17 @@ bail: goto bail; } - //open Finder - // ->will reveal binary - [[NSWorkspace sharedWorkspace] selectFile:path inFileViewerRootedAtPath:@""]; + //open item in Finder + // ->error alert shown if file open fails + if(YES != [[NSWorkspace sharedWorkspace] selectFile:path inFileViewerRootedAtPath:@""]) + { + //alloc/init alert + errorAlert = [NSAlert alertWithMessageText:[NSString stringWithFormat:@"ERROR:\nfailed to open %@", path] defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"errno value: %d", errno]; + + //show it + [errorAlert runModal]; + } + //bail bail: diff --git a/UI/FileInfoWindow.xib b/UI/FileInfoWindow.xib index 397aaef..ec4a444 100644 --- a/UI/FileInfoWindow.xib +++ b/UI/FileInfoWindow.xib @@ -1,8 +1,8 @@ - + - + diff --git a/UI/FlaggedItems.xib b/UI/FlaggedItems.xib index 6631e4b..bdd1ace 100644 --- a/UI/FlaggedItems.xib +++ b/UI/FlaggedItems.xib @@ -1,8 +1,8 @@ - - + + - + @@ -17,7 +17,7 @@ - + @@ -26,11 +26,11 @@ - + - + @@ -53,7 +53,7 @@ - + @@ -61,7 +61,7 @@ - + @@ -69,7 +69,7 @@ - + @@ -77,7 +77,7 @@ - - + @@ -103,26 +103,29 @@ - + + + + - - + @@ -134,7 +137,7 @@ - - + @@ -162,18 +165,28 @@ + + + - - + + + - + + + + - + + + + diff --git a/UI/FlatView.xib b/UI/FlatView.xib index 311662e..71f9556 100755 --- a/UI/FlatView.xib +++ b/UI/FlatView.xib @@ -1,9 +1,10 @@ - - + + - - + + + @@ -15,23 +16,23 @@ - + - + - + - + - + @@ -45,10 +46,10 @@ - + - + @@ -56,7 +57,7 @@ - + @@ -64,16 +65,19 @@ - + + + + - - - + + @@ -98,27 +102,30 @@ - - + + + + + - - - + + @@ -129,8 +136,8 @@ - - - + + @@ -157,18 +164,28 @@ - - + + + + - - + + + + + + + + - + + + @@ -176,10 +193,10 @@ - + - + @@ -189,19 +206,20 @@ + - - - + + @@ -221,18 +239,21 @@ - - + + + + + - - - + + @@ -252,8 +273,8 @@ - - - + + @@ -281,32 +302,44 @@ + + + + + + + + + - + - + + + + - - - + + @@ -332,16 +365,19 @@ - - + + + + + - - - + + @@ -368,10 +404,17 @@ + + + + + + + @@ -380,35 +423,41 @@ - + - + - - + + - - + + + + + - + + + + - - - + + @@ -435,11 +484,17 @@ + + - + + + - - + + + + @@ -457,8 +512,8 @@ - diff --git a/UI/SearchWindow.xib b/UI/SearchWindow.xib index 853e85d..b661ad8 100644 --- a/UI/SearchWindow.xib +++ b/UI/SearchWindow.xib @@ -1,8 +1,10 @@ - - + + - + + + @@ -21,14 +23,14 @@ - + - + - + @@ -55,10 +57,10 @@ - + - + @@ -66,7 +68,7 @@ - + @@ -74,7 +76,7 @@ - + @@ -82,7 +84,7 @@ - - + @@ -108,7 +110,7 @@ - + @@ -116,10 +118,10 @@ - - + @@ -139,7 +141,7 @@ - - + @@ -167,18 +169,31 @@ + + + + + + - + - + - - + + + + + + + + + @@ -186,10 +201,10 @@ - + - + @@ -197,7 +212,7 @@ - + @@ -205,7 +220,7 @@ - - + @@ -231,15 +246,15 @@ - - + + - - + @@ -267,16 +282,24 @@ - + + + + - - - + + + + + + + + @@ -284,18 +307,18 @@ - + - + - - + + - + @@ -303,7 +326,7 @@ - + @@ -311,7 +334,7 @@ - - + @@ -339,13 +362,20 @@ - + + + - - - + + + + + + + + @@ -372,7 +402,7 @@ - + @@ -383,14 +413,14 @@ - + - + - - + + - + + - + + + diff --git a/UI/TreeView.xib b/UI/TreeView.xib index 50630cc..7be5b7c 100755 --- a/UI/TreeView.xib +++ b/UI/TreeView.xib @@ -1,9 +1,8 @@ - - + + - - + @@ -15,23 +14,23 @@ - + - + - + - + - + @@ -45,10 +44,10 @@ - + - + @@ -56,7 +55,7 @@ - + @@ -64,16 +63,16 @@ - - + + - - - + + @@ -98,27 +97,30 @@ - - + + + + + - - - + + @@ -129,8 +131,8 @@ - - - + + @@ -157,18 +159,29 @@ - - + + + - + + + + + + + + + - + + + - - + + @@ -184,10 +197,9 @@ - -