initial commit

This commit is contained in:
Patrick Wardle
2015-06-13 16:51:34 -10:00
commit e8ce5006bb
144 changed files with 21324 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
//
// HyperlinkTextField.h
// NSTextFieldHyperlinks
//
// Created by Toomas Vahter on 25.12.12.
// Copyright (c) 2012 Toomas Vahter. All rights reserved.
//
// This content is released under the MIT License (http://www.opensource.org/licenses/mit-license.php).
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Cocoa/Cocoa.h>
@interface HyperlinkTextField : NSTextField
@end
+153
View File
@@ -0,0 +1,153 @@
//
// HyperlinkTextField.m
// NSTextFieldHyperlinks
//
// Created by Toomas Vahter on 25.12.12.
// Copyright (c) 2012 Toomas Vahter. All rights reserved.
//
// This content is released under the MIT License (http://www.opensource.org/licenses/mit-license.php).
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "HyperlinkTextField.h"
@interface HyperlinkTextField ()
@property (nonatomic, readonly) NSArray *hyperlinkInfos;
@property (nonatomic, readonly) NSTextView *textView;
- (void)_resetHyperlinkCursorRects;
@end
#define kHyperlinkInfoCharacterRangeKey @"range"
#define kHyperlinkInfoURLKey @"url"
#define kHyperlinkInfoRectKey @"rect"
@implementation HyperlinkTextField
- (void)_hyperlinkTextFieldInit
{
[self setEditable:NO];
[self setSelectable:NO];
}
- (id)initWithFrame:(NSRect)frame
{
if ((self = [super initWithFrame:frame]))
{
[self _hyperlinkTextFieldInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)coder
{
if ((self = [super initWithCoder:coder]))
{
[self _hyperlinkTextFieldInit];
}
return self;
}
- (void)resetCursorRects
{
[super resetCursorRects];
[self _resetHyperlinkCursorRects];
}
- (void)_resetHyperlinkCursorRects
{
for (NSDictionary *info in self.hyperlinkInfos)
{
[self addCursorRect:[[info objectForKey:kHyperlinkInfoRectKey] rectValue] cursor:[NSCursor pointingHandCursor]];
}
}
#pragma mark -
#pragma mark Accessors
- (NSArray *)hyperlinkInfos
{
NSMutableArray *hyperlinkInfos = [[NSMutableArray alloc] init];
NSRange stringRange = NSMakeRange(0, [self.attributedStringValue length]);
__block NSTextView *textView = self.textView;
[self.attributedStringValue enumerateAttribute:NSLinkAttributeName inRange:stringRange options:0 usingBlock:^(id value, NSRange range, BOOL *stop)
{
if (value)
{
NSUInteger rectCount = 0;
NSRectArray rectArray = [textView.layoutManager rectArrayForCharacterRange:range withinSelectedCharacterRange:range inTextContainer:textView.textContainer rectCount:&rectCount];
for (NSUInteger i = 0; i < rectCount; i++)
{
[hyperlinkInfos addObject:@{kHyperlinkInfoCharacterRangeKey : [NSValue valueWithRange:range], kHyperlinkInfoURLKey : value, kHyperlinkInfoRectKey : [NSValue valueWithRect:rectArray[i]]}];
}
}
}];
return [hyperlinkInfos count] ? hyperlinkInfos : nil;
}
- (NSTextView *)textView
{
// Font used for displaying and frame calculations must match
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedStringValue];
NSFont *font = [attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL];
if (!font)
[attributedString addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [attributedString length])];
NSRect textViewFrame = [self.cell titleRectForBounds:self.bounds];
NSTextView *textView = [[NSTextView alloc] initWithFrame:textViewFrame];
[textView.textStorage setAttributedString:attributedString];
return textView;
}
#pragma mark -
#pragma mark Mouse Events
- (void)mouseUp:(NSEvent *)theEvent
{
NSTextView *textView = self.textView;
NSPoint localPoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
NSUInteger index = [textView.layoutManager characterIndexForPoint:localPoint inTextContainer:textView.textContainer fractionOfDistanceBetweenInsertionPoints:NULL];
if (index != NSNotFound)
{
for (NSDictionary *info in self.hyperlinkInfos)
{
NSRange range = [[info objectForKey:kHyperlinkInfoCharacterRangeKey] rangeValue];
if (NSLocationInRange(index, range))
{
NSURL *url = [info objectForKey:kHyperlinkInfoURLKey];
[[NSWorkspace sharedWorkspace] openURL:url];
}
}
}
}
@end
+39
View File
@@ -0,0 +1,39 @@
//
// OrderedDictionary.h
// OrderedDictionary
//
// Created by Matt Gallagher on 19/12/08.
// Copyright 2008 Matt Gallagher. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software. Permission is granted to anyone to
// use this software for any purpose, including commercial applications, and to
// alter it and redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source
// distribution.
//
#import <Cocoa/Cocoa.h>
@interface OrderedDictionary : NSMutableDictionary
{
NSMutableDictionary *dictionary;
NSMutableArray *array;
}
- (void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex;
- (id)keyAtIndex:(NSUInteger)anIndex;
- (NSUInteger)indexOfKey:(id)aKey;
- (NSEnumerator *)reverseKeyEnumerator;
-(void)reverse;
@end
+160
View File
@@ -0,0 +1,160 @@
//
// OrderedDictionary.m
// OrderedDictionary
//
// Created by Matt Gallagher on 19/12/08.
// Copyright 2008 Matt Gallagher. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software. Permission is granted to anyone to
// use this software for any purpose, including commercial applications, and to
// alter it and redistribute it freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be
// appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source
// distribution.
//
#import "OrderedDictionary.h"
NSString *DescriptionForObject(NSObject *object, id locale, NSUInteger indent)
{
NSString *objectString;
if ([object isKindOfClass:[NSString class]])
{
objectString = (NSString *)object;
}
else if ([object respondsToSelector:@selector(descriptionWithLocale:indent:)])
{
objectString = [(NSDictionary *)object descriptionWithLocale:locale indent:indent];
}
else if ([object respondsToSelector:@selector(descriptionWithLocale:)])
{
objectString = [(NSSet *)object descriptionWithLocale:locale];
}
else
{
objectString = [object description];
}
return objectString;
}
@implementation OrderedDictionary
-(id)init
{
return [self initWithCapacity:0];
}
- (id)initWithCapacity:(NSUInteger)capacity
{
self = [super init];
if (self != nil)
{
dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
array = [[NSMutableArray alloc] initWithCapacity:capacity];
}
return self;
}
- (id)copy
{
return [self mutableCopy];
}
- (void)setObject:(id)anObject forKey:(id)aKey
{
if(![dictionary objectForKey:aKey])
{
//
[array addObject:aKey];
}
[dictionary setObject:anObject forKey:aKey];
}
- (void)removeObjectForKey:(id)aKey
{
[dictionary removeObjectForKey:aKey];
[array removeObject:aKey];
}
- (NSUInteger)count
{
return [dictionary count];
}
- (id)objectForKey:(id)aKey
{
return [dictionary objectForKey:aKey];
}
- (NSEnumerator *)keyEnumerator
{
return [array objectEnumerator];
}
/*
- (NSEnumerator *)reverseKeyEnumerator
{
return [array reverseObjectEnumerator];
}
*/
-(void)insertObject:(id)anObject forKey:(id)aKey atIndex:(NSUInteger)anIndex
{
if([dictionary objectForKey:aKey])
{
[self removeObjectForKey:aKey];
}
[array insertObject:aKey atIndex:anIndex];
[dictionary setObject:anObject forKey:aKey];
}
-(id)keyAtIndex:(NSUInteger)anIndex
{
return [array objectAtIndex:anIndex];
}
//given an key
// ->return its index
-(NSUInteger)indexOfKey:(id)aKey
{
return [array indexOfObject:aKey];
}
-(void)reverse
{
array = [[[array reverseObjectEnumerator] allObjects] mutableCopy];
}
/*
- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSMutableString *indentString = [NSMutableString string];
NSUInteger i, count = level;
for (i = 0; i < count; i++)
{
[indentString appendFormat:@" "];
}
NSMutableString *description = [NSMutableString string];
[description appendFormat:@"%@{\n", indentString];
for (NSObject *key in self)
{
[description appendFormat:@"%@ %@ = %@;\n",
indentString,
DescriptionForObject(key, locale, level),
DescriptionForObject([self objectForKey:key], locale, level)];
}
[description appendFormat:@"%@}\n", indentString];
return description;
}
*/
@end
+15
View File
@@ -0,0 +1,15 @@
//
// TAAdaptiveSpaceItem.h
// TAAdaptiveSpaceItem
//
// Created by Timothy Armes on 17/02/2014.
// Copyright (c) 2014 Timothy Armes. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface TAAdaptiveSpaceItem : NSToolbarItem
- (void)updateWidth;
@end
+72
View File
@@ -0,0 +1,72 @@
//
// TAAdaptiveSpaceItem.m
// TAAdaptiveSpaceItem
//
// Created by Timothy Armes on 17/02/2014.
// Copyright (c) 2014 Timothy Armes. All rights reserved.
//
#import "TAAdaptiveSpaceItem.h"
#import "TAAdaptiveSpaceItemView.h"
@implementation TAAdaptiveSpaceItem
- (void)awakeFromNib
{
TAAdaptiveSpaceItemView *adaptiveSpaceItemView = [[TAAdaptiveSpaceItemView alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)];
adaptiveSpaceItemView.adaptiveSpaceItem = self;
self.view = adaptiveSpaceItemView;
}
- (NSString *)label
{
return @"";
}
- (NSString *)paletteLabel
{
return NSLocalizedString(@"Adaptive Space Item", @"Palette name when customising toolbar");
}
- (NSSize)minSize
{
NSArray *items = [self.toolbar items];
NSInteger index = [items indexOfObject:self];
if (index != NSNotFound) {
NSRect thisFrame = self.view.superview.frame;
if (thisFrame.origin.x > 0) {
CGFloat space = 0;
if (items.count > index + 1) {
NSToolbarItem *nextItem = [items objectAtIndex:index + 1];
NSRect nextFrame = nextItem.view.superview.frame;
NSRect toolbarFrame = nextItem.view.superview.superview.frame;
space = (toolbarFrame.size.width - nextFrame.size.width) / 2 - thisFrame.origin.x - 6;
if (space < 0)
space = 0;
}
NSSize size = [super minSize];
return NSMakeSize(space, size.height);
}
}
return [super minSize];
}
- (NSSize)maxSize
{
NSSize size = [super maxSize];
return NSMakeSize([self minSize].width, size.height);
}
- (void)updateWidth
{
[self setMinSize:[self minSize]];
[self setMaxSize:[self maxSize]];
}
@end
+16
View File
@@ -0,0 +1,16 @@
//
// TAAdaptiveSpaceItemView.h
// TAAdaptiveSpaceItem
//
// Created by Timothy Armes on 17/02/2014.
// Copyright (c) 2014 Timothy Armes. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@class TAAdaptiveSpaceItem;
@interface TAAdaptiveSpaceItemView : NSView
@property (weak) TAAdaptiveSpaceItem *adaptiveSpaceItem;
@end
+35
View File
@@ -0,0 +1,35 @@
//
// TAAdaptiveSpaceItemView.m
// TAAdaptiveSpaceItem
//
// Created by Timothy Armes on 17/02/2014.
// Copyright (c) 2014 Timothy Armes. All rights reserved.
//
#import "TAAdaptiveSpaceItemView.h"
#import "TAAdaptiveSpaceItem.h"
@implementation TAAdaptiveSpaceItemView
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
return NO;
}
- (void)viewDidMoveToWindow
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowResized:) name:NSWindowDidResizeNotification object:[self window]];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)windowResized:(NSNotification *)notification;
{
[_adaptiveSpaceItem updateWidth];
}
@end
+27
View File
@@ -0,0 +1,27 @@
//
// PrefsWindowController.h
// DHS
//
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface AboutWindowController : NSWindowController <NSWindowDelegate>
{
}
/* PROPERTIES */
//version label/string
@property (weak) IBOutlet NSTextField *versionLabel;
/* METHODS */
//invoked when user clicks 'more info' button
// ->open KK's webpage
- (IBAction)moreInfo:(id)sender;
@end
+54
View File
@@ -0,0 +1,54 @@
//
// PrefsWindowController.m
// KnockKnock
//
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
//
#import "Utilities.h"
#import "AppDelegate.h"
#import "AboutWindowController.h"
@implementation AboutWindowController
@synthesize versionLabel;
//automatically called when nib is loaded
// ->center window
-(void)awakeFromNib
{
//center
[self.window center];
}
//automatically invoked when window is loaded
// ->set to white
-(void)windowDidLoad
{
//super
[super windowDidLoad];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//set version sting
[self.versionLabel setStringValue:[NSString stringWithFormat:@"version: %@", getAppVersion()]];
return;
}
//automatically invoked when user clicks 'more info'
// ->load knockknock's html page
- (IBAction)moreInfo:(id)sender
{
//open URL
// ->invokes user's default browser
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://objective-see.com/products/knockknock.html"]];
return;
}
@end
Executable
+183
View File
@@ -0,0 +1,183 @@
//
// AppDelegate.h
// KnockKnock
//
// Created by Patrick Wardle
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "Binary.h"
#import "ItemBase.h"
#import "Filter.h"
#import "VirusTotal.h"
#import "TaskTableController.h"
#import "TreeViewController.h"
#import "AboutWindowController.h"
#import "PrefsWindowController.h"
#import "ResultsWindowController.h"
#import "RequestRootWindowController.h"
#import "Task.h"
#import "TaskEnumerator.h"
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate, NSTableViewDataSource, NSTableViewDelegate, NSMenuDelegate>
{
//NSViewController *bottomViewController;
}
//@property (readonly) NSViewController *currentViewController;
@property(nonatomic, retain)NSViewController *currentViewController;
//(current) bottom view controller
@property(nonatomic, retain)TaskTableController *bottomViewController;
@property (weak) IBOutlet NSView *topPane;
//@property (weak) IBOutlet NSScrollView *taskScrollView;
//task enumerator object
@property(nonatomic, retain)TaskEnumerator* taskEnumerator;
//task table controller object
@property (nonatomic, retain)TaskTableController *taskTableController;
//tree (outline) controller
@property (nonatomic, retain)TreeViewController* treeViewController;
//array to hold binary objects that are in array
//@property (nonatomic, retain)NSMutableArray *tableContents;
//drop-down view selector
@property (weak) IBOutlet NSPopUpButton *viewSelector;
//segmented button for button pane
// ->select to view dylib, files, network, etc
@property (weak) IBOutlet NSSegmentedControl *bottomPaneBtn;
//action when segmented button is clicked
-(IBAction)selectBottomPaneContent:(id)sender;
//bottom pane view
@property (weak) IBOutlet NSView *bottomPane;
@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSButton *logoButton;
@property (weak) IBOutlet NSButton *showPreferencesButton;
//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;
//filter object
@property(nonatomic, retain)Filter* filterObj;
//virus total object
@property(nonatomic, retain)VirusTotal* virusTotalObj;
//array for all virus total threads
@property(nonatomic, retain)NSMutableArray* vtThreads;
//request root window controller
@property(nonatomic, retain)RequestRootWindowController* requestRootWindowController;
//preferences window controller
@property(nonatomic, retain)PrefsWindowController* prefsWindowController;
//about window controller
@property(nonatomic, retain)AboutWindowController* aboutWindowController;
//results window controller
@property(nonatomic, retain)ResultsWindowController* resultsWindowController;
//currently selected task
@property(nonatomic, retain)Task* currentTask;
//activity indicator for bottom pane
@property (weak) IBOutlet NSProgressIndicator *bottomPaneSpinner;
//'no items' found label for bottom pane
@property (weak) IBOutlet NSTextField *noItemsLabel;
/* METHODS */
- (IBAction)switchView:(id)sender;
//init tracking areas for buttons
// ->provide mouse over effects
-(void)initTrackingAreas;
//create instances of all registered plugins
//-(NSMutableArray*)instantiatePlugins;
//callback method, invoked by plugin(s) when item is found
// ->update the 'total' count and the item table (if active plugin is selected in UI)
-(void)itemFound:(Task*)task;
//callback method, invoked by virus total when plugin's items have been processed
// ->reload table if plugin matches active plugin
//-(void)itemsProcessed:(PluginBase*)plugin;
//callback method, invoked by category table controller when user selects category
// ->save the selected plugin & reload the item table
-(void)categorySelected:(NSUInteger)rowIndex;
//callback when user has updated prefs
// ->reload table, etc
-(void)applyPreferences;
//update a single row
-(void)itemProcessed:(Binary*)fileObj rowIndex:(NSUInteger)rowIndex;
//action
// ->invoked when user clicks 'About/Info' or Objective-See logo in main UI
-(void)displayScanStats;
-(IBAction)scanButtonHandler:(id)sender;
//button handler for when settings icon (gear) is clicked
-(IBAction)showPreferences:(id)sender;
//kickoff a thread to query VT
//-(void)queryVT:(PluginBase*)plugin;
//button handler for logo
-(IBAction)logoButtonHandler:(id)sender;
//action for 'about' in menu/logo in UI
-(IBAction)about:(id)sender;
//TODO add this, and move into properties
//version string
@property (weak) IBOutlet NSTextField *versionString;
//reload (to re-draw) a specific row in table
-(void)reloadRow:(Task*)task item:(ItemBase*)item pane:(NSUInteger)pane;
//reload task table
-(void)reloadTaskTable;
//smartly, reload bottom pane
// ->checks if task & item type (e.g. files) are both selected
-(void)reloadBottomPane:(Task*)task itemView:(NSUInteger)itemView;
//begin task enumeration
-(void)exploreTasks;
@end
Executable
+1430
View File
File diff suppressed because it is too large Load Diff
+299
View File
@@ -0,0 +1,299 @@
//
// Consts.h
// DHS
//
// Created by Patrick Wardle on 2/4/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#ifndef KK_Consts_h
#define KK_Consts_h
//button text, start scan
#define START_SCAN @"Start Scan"
//button text, stop scan
#define STOP_SCAN @"Stop Scan"
//status msg
#define SCAN_MSG_STARTED @"scanning started"
//status msg
#define SCAN_MSG_STOPPED @"scan stopped"
//status msg
#define SCAN_MSG_COMPLETE @"scan complete"
//success
#define STATUS_SUCCESS 0
//keys for signing stuff
#define KEY_SIGNATURE_STATUS @"signatureStatus"
#define KEY_SIGNING_AUTHORITIES @"signingAuthorities"
//OS version x
#define OS_MAJOR_VERSION_X 10
//OS version lion
#define OS_MINOR_VERSION_LION 8
//OS version yosemite
#define OS_MINOR_VERSION_YOSEMITE 10
//executable path
#define EXECUTABLE_PATH @"@executable_path"
//loader path
#define LOADER_PATH @"@loader_path"
//rpath
#define RUN_SEARCH_PATH @"@rpath"
//path to LSOF
#define LSOF @"/usr/sbin/lsof"
//hash key, SHA1
#define KEY_HASH_SHA1 @"sha1"
//hash key, MD5
#define KEY_HASH_MD5 @"md5"
//path to system profiler
#define SYSTEM_PROFILER @"/usr/sbin/system_profiler"
//dyld_ key for launch items
#define LAUNCH_ITEM_DYLD_KEY @"EnvironmentVariables"
//dyld_ key for applications
#define APPLICATION_DYLD_KEY @"LSEnvironment"
//menu
//tag for prefs menu item
#define PREF_MENU_ITEM_TAG 1
//main window
//space for File's button in time table (w/ VT info)
#define TABLE_BUTTONS_FILE 225
//space for Extension's button in time table
#define TABLE_BUTTONS_EXTENTION 135
//scan button
#define SCAN_BUTTON_TAG 1000
//pref button
#define PREF_BUTTON_TAG 1001
//logo button
#define LOGO_BUTTON_TAG 1002
//category table
//id (tag) for detailed text in category table
#define TABLE_ROW_NAME_TAG 100
//id (tag) for detailed text in category table
#define TABLE_ROW_SUB_TEXT_TAG 101
//id (tag) for total's msg
#define TABLE_ROW_TOTAL_TAG 102
//item table
//id (tag) for signed icon
#define TABLE_ROW_SIGNATURE_ICON 100
//id (tag) for path
#define TABLE_ROW_PATH_LABEL 101
//id (tag) for plist
#define TABLE_ROW_PID_LABEL 102
//id (tag) for 'virus total' button
#define TABLE_ROW_VT_BUTTON 103
//id (tag) for 'info' button
#define TABLE_ROW_INFO_BUTTON 105
//id (tag) for 'show' button
#define TABLE_ROW_SHOW_BUTTON 107
//ellipis
// ->for long paths...
#define ELLIPIS @"..."
//known file hashes
#define WHITE_LISTED_FILES @"whitelistedFiles"
//known commands
#define WHITE_LISTED_COMMANDS @"whitelistedCommands"
//known extension hashes
#define WHITE_LISTED_EXTENSIONS @"whitelistedExtensions"
//scanner option key
// ->filter apple signed/known items
#define KEY_SCANNER_FILTER @"filterItems"
//plugin key
//#define KEY_RESULT_PLUGIN @"plugin"
//XPC Service name
#define XPC_SERVICE @"remoteTaskService.xpc"
//location of kernel in pre-Yosemite
#define KERNEL_PRE_YOSEMITE @"/System/Library/Kernels/kernel"
//location of kernel in Yosemite
#define KERNEL_YOSEMITE @"/System/Library/Kernels/kernel"
//top pane
//top
#define PANE_TOP 0x0
//for prefs
//#define PREF_FIRST_RUN @"isFirstRun"
//flat view
#define FLAT_VIEW 100
//tree view
#define TREE_VIEW 101
//bottom pane
//top
#define PANE_BOTTOM 0x1
//any view
// ->not in UI
#define CURRENT_VIEW -1
//dylib view
#define DYLIBS_VIEW 0
//file view
#define FILES_VIEW 1
//networking view
#define NETWORKING_VIEW 2
//pid
#define KEY_RESULT_PID @"pid"
//name key
#define KEY_RESULT_NAME @"name"
//path key
#define KEY_RESULT_PATH @"path"
//plist key
#define KEY_RESULT_PLIST @"plist"
//extension id key
#define KEY_EXTENSION_ID @"id"
//extension description key
#define KEY_EXTENSION_DETAILS @"details"
//extension (host) browser key
#define KEY_EXTENSION_BROWSER @"browser"
/* VIRUS TOTAL */
//query url
#define VT_QUERY_URL @"https://www.virustotal.com/partners/sysinternals/file-reports?apikey="
//requery url
#define VT_REQUERY_URL @"https://www.virustotal.com/vtapi/v2/file/report"
//rescan url
#define VT_RESCAN_URL @"https://www.virustotal.com/vtapi/v2/file/rescan"
//submit url
#define VT_SUBMIT_URL @"https://www.virustotal.com/vtapi/v2/file/scan"
//api key
#define VT_API_KEY @"233f22e200ca5822bd91103043ccac138b910db79f29af5616a9afe8b6f215ad"
//user agent
#define VT_USER_AGENT @"VirusTotal"
//query count
#define VT_MAX_QUERY_COUNT 25
//results
#define VT_RESULTS @"data"
//results response code
#define VT_RESULTS_RESPONSE @"response_code"
//result url
#define VT_RESULTS_URL @"permalink"
//result hash
#define VT_RESULT_HASH @"hash"
//results positives
#define VT_RESULTS_POSITIVES @"positives"
//results total
#define VT_RESULTS_TOTAL @"total"
//results scan id
#define VT_RESULTS_SCANID @"scan_id"
//output file
#define OUTPUT_FILE @"kkFindings.txt"
//keys/types for XPC dictionaries
//descriptor type
#define KEY_DESCRIPTOR_TYPE @"descriptorType"
//file path
#define KEY_FILE_PATH @"filePath"
//socket local ip addr
#define KEY_LOCAL_ADDR @"localIPAddr"
//socket local port
#define KEY_LOCAL_PORT @"localPort"
//socket remote ip addr
#define KEY_REMOTE_ADDR @"remoteIPAddr"
//socket remote port
#define KEY_REMOTE_PORT @"remotePort"
//socket state
#define KEY_SOCKET_STATE @"socketState"
//socket type
#define KEY_SOCKET_TYPE @"socketType"
//socket family
#define KEY_SOCKET_FAMILY @"socketFamily"
//socket protocol
#define KEY_SOCKET_PROTO @"socketProto"
//listening socket
#define SOCKET_LISTENING @"listening"
//connected socket
#define SOCKET_ESTABLISHED @"connected"
#endif
Executable
+20
View File
@@ -0,0 +1,20 @@
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
#import <syslog.h>
#import <signal.h>
//install exception/signal handlers
void installExceptionHandlers();
//exception handler for Obj-C exceptions
void exceptionHandler(NSException *exception);
//signal handler for *nix style exceptions
void signalHandler(int signal, siginfo_t *info, void *context);
//display an alert
void showAlert();
Executable
+157
View File
@@ -0,0 +1,157 @@
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
#import "Consts.h"
#import "Exception.h"
#import "Utilities.h"
//install exception/signal handlers
void installExceptionHandlers()
{
//sigaction struct
struct sigaction sa = {0};
//init struct
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = signalHandler;
//exception handler
NSSetUncaughtExceptionHandler(&exceptionHandler);
//install signal handlers
sigaction(SIGILL, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGBUS, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
sigaction(SIGTRAP, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
return;
}
//display error alert
void showAlert()
{
//response
// ->index of button click
NSModalResponse response = 0;
//alert box
NSAlert* fullScanAlert = nil;
//alloc/init alert
fullScanAlert = [NSAlert alertWithMessageText:@"ERROR: detected unrecoverable fault" defaultButton:@"Exit" alternateButton:@"Info" otherButton:nil informativeTextWithFormat:@"click 'Info' to help fix the issue!"];
//and show it
response = [fullScanAlert runModal];
//handle case where user clicks 'Info'
// ->take 'em to error page
if(0 == response)
{
//open page in browser
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://objective-see.com/errors.html"]];
}
//kill app
exit(0);
return;
}
//exception handler
// will be invoked for Obj-C exceptions
void exceptionHandler(NSException *exception)
{
//error msg
NSString* errMsg = nil;
//err msg
syslog(LOG_ERR, "OBJECTIVE-SEE ERROR: OS version: %s /App version: %s", [[[NSProcessInfo processInfo] operatingSystemVersionString] UTF8String], [getAppVersion() UTF8String]);
//create error msg
errMsg = [NSString stringWithFormat:@"unhandled obj-c exception caught [name: %@ / reason: %@]", [exception name], [exception reason]];
//err msg
syslog(LOG_ERR, "OBJECTIVE-SEE ERROR: %s", [errMsg UTF8String]);
//err msg
syslog(LOG_ERR, "OBJECTIVE-SEE ERROR: %s", [[[NSThread callStackSymbols] description] UTF8String]);
//main thread
// ->just show UI alert
if(YES == [NSThread isMainThread])
{
//show
showAlert();
}
//back thread
// ->have to show it on main thread
else
{
//show alert
// ->in main UI thread
dispatch_sync(dispatch_get_main_queue(), ^{
//show
showAlert();
});
}
return;
}
//handler for signals
// will be invoked for BSD/*nix signals
void signalHandler(int signal, siginfo_t *info, void *context)
{
//error msg
NSString* errMsg = nil;
//context
ucontext_t *uContext = NULL;
//err msg
syslog(LOG_ERR, "OBJECTIVE-SEE ERROR: OS version: %s /App version: %s", [[[NSProcessInfo processInfo] operatingSystemVersionString] UTF8String], [getAppVersion() UTF8String]);
//typecast context
uContext = (ucontext_t *)context;
//create error msg
errMsg = [NSString stringWithFormat:@"unhandled exception caught, si_signo: %d /si_code: %s /si_addr: %p /rip: %p",
info->si_signo, (info->si_code == SEGV_MAPERR) ? "SEGV_MAPERR" : "SEGV_ACCERR", info->si_addr, (unsigned long*)uContext->uc_mcontext->__ss.__rip];
//err msg
syslog(LOG_ERR, "OBJECTIVE-SEE ERROR: %s", [errMsg UTF8String]);
//err msg
syslog(LOG_ERR, "OBJECTIVE-SEE ERROR: %s", [[[NSThread callStackSymbols] description] UTF8String]);
//main thread
// ->just show UI alert
if(YES == [NSThread isMainThread])
{
//show
showAlert();
}
//back thread
// ->have to show it on main thread
else
{
//show alert
// ->in main UI thread
dispatch_sync(dispatch_get_main_queue(), ^{
//show
showAlert();
});
}
return;
}
+45
View File
@@ -0,0 +1,45 @@
//
// Filter.h
// KnockKnock
//
// Created by Patrick Wardle on 2/21/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "File.h"
#import "Binary.h"
#import <Foundation/Foundation.h>
@interface Filter : NSObject
{
}
//white listed file hashes
@property(nonatomic, retain)NSDictionary* trustedFiles;
//white listed commands
@property(nonatomic, retain)NSDictionary* knownCommands;
//white listed extensions
@property(nonatomic, retain)NSDictionary* trustedExtensions;
/* METHODS */
//load a (JSON) white list
// ->file hashes, known commands, etc
-(NSDictionary*)loadWhitelist:(NSString*)fileName;
//check if a File obj is whitelisted
-(BOOL)isTrustedFile:(Binary*)fileObj;
//check if a Command obj is whitelisted
//-(BOOL)isKnownCommand:(Command*)commandObj;
//check if a Extension obj is whitelisted
//-(BOOL)isTrustedExtension:(Extension*)extensionObj;
@end
+104
View File
@@ -0,0 +1,104 @@
//
// Filter.m
// KnockKnock
//
// Created by Patrick Wardle on 2/21/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "Consts.h"
#import "Filter.h"
#import "Utilities.h"
@implementation Filter
@synthesize trustedFiles;
@synthesize knownCommands;
@synthesize trustedExtensions;
#define SOFTWARE_SIGNING @"Software Signing"
#define APPLE_SIGNING_AUTH @"Apple Code Signing Certification Authority"
#define APPLE_ROOT_CA @"Apple Root CA"
//init
-(id)init
{
//super
self = [super init];
if(self)
{
//load known file hashes
self.trustedFiles = [self loadWhitelist:WHITE_LISTED_FILES];
//load known commands
self.knownCommands = [self loadWhitelist:WHITE_LISTED_COMMANDS];
//load known extensions
self.trustedExtensions = [self loadWhitelist:WHITE_LISTED_EXTENSIONS];
}
return self;
}
//load a (JSON) white list
// ->file hashes, known commands, etc
-(NSDictionary*)loadWhitelist:(NSString*)fileName
{
//whitelisted data
NSDictionary* whiteList = nil;
//path
NSString* path = nil;
//error var
NSError *error = nil;
//json data
NSData* whiteListJSON = nil;
//init path
path = [[NSBundle mainBundle] pathForResource:fileName ofType: @"json"];
//load whitelist file data
whiteListJSON = [NSData dataWithContentsOfFile:path];
//convert JSON into dictionary
whiteList = [NSJSONSerialization JSONObjectWithData:whiteListJSON options:kNilOptions error:&error];
return whiteList;
}
//check if a File obj is known
// ->whitelisted *or* signed by apple
-(BOOL)isTrustedFile:(Binary*)fileObj
{
//flag
BOOL isTrusted = NO;
//known hashes for file name
NSArray* knownHashes = nil;
//lookup based on name
knownHashes = self.trustedFiles[fileObj.path];
//first check if hash is known
if( (nil != knownHashes) &&
(YES == [knownHashes containsObject:[fileObj.hashes[KEY_HASH_MD5] lowercaseString]]) )
{
//got match
isTrusted = YES;
}
//then check if its signed by apple
// ->apple-signed files are always trusted
else
{
//check for apple signature
isTrusted = isApple(fileObj.path);
}
return isTrusted;
}
@end
+65
View File
@@ -0,0 +1,65 @@
//
// InfoWindowController.h
// KnockKnock
//
// Created by Patrick Wardle on 2/21/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@class ItemBase;
@interface InfoWindowController : NSWindowController <NSWindowDelegate>
{
}
//properties in window
// ->attributes about the item
@property(weak)IBOutlet NSImageView *icon;
@property(weak)IBOutlet NSTextField *name;
@property(weak)IBOutlet NSTextField *path;
@property(weak)IBOutlet NSTextField *date;
//task-specific outlets
@property (weak) IBOutlet NSTextField *arguments;
//file window specific outlets
@property(weak)IBOutlet NSTextField *hashes;
@property(weak)IBOutlet NSTextField *size;
@property(weak)IBOutlet NSTextField *sign;
@property (weak) IBOutlet NSTextField *plist;
//extension window specific outlets
@property (weak) IBOutlet NSTextField *details;
@property (weak) IBOutlet NSTextField *identifier;
//window controller
@property(nonatomic, strong)InfoWindowController *windowController;
//item
@property(nonatomic, retain)ItemBase* itemObj;
/* METHODS */
//init method
// ->save item and load nib
-(id)initWithItem:(id)selectedItem;
//configure window
// ->add item's attributes (name, path, etc.)
-(void)configure;
//check if something is nil
// ->if so, return the default
-(NSString*)valueForStringItem:(NSString*)item default:(NSString*)defaultValue;
//close button handler
-(IBAction)closeWindow:(id)sender;
@end
+315
View File
@@ -0,0 +1,315 @@
//
// InfoWindowController.m
// KnockKnock
//
// Created by Patrick Wardle on 2/21/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "Task.h"
#import "File.h"
#import "Binary.h"
#import "Connection.h"
#import "Consts.h"
#import "Utilities.h"
#import "InfoWindowController.h"
@interface InfoWindowController ()
@end
@implementation InfoWindowController
@synthesize itemObj;
//automatically invoked when window is loaded
// ->set to white
-(void)windowDidLoad
{
//super
[super windowDidLoad];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
return;
}
//init method
// ->save item and load nib
-(id)initWithItem:(id)selectedItem
{
self = [super init];
if(nil != self)
{
//load task info window
if(YES == [selectedItem isKindOfClass:[Task class]])
{
//load nib
self.windowController = [[InfoWindowController alloc] initWithWindowNibName:@"TaskInfoWindow"];
}
//load binary info window
else if(YES == [selectedItem isKindOfClass:[Binary class]])
{
//load nib
self.windowController = [[InfoWindowController alloc] initWithWindowNibName:@"DylibInfoWindow"];
}
/*TODO: delete this and xibs?
//load file info window
else if(YES == [selectedItem isKindOfClass:[File class]])
{
//load nib
self.windowController = [[InfoWindowController alloc] initWithWindowNibName:@"FileInfoWindow"];
}
//load extension info window
else if(YES == [selectedItem isKindOfClass:[Connection class]])
{
//load nib
self.windowController = [[InfoWindowController alloc] initWithWindowNibName:@"ConnectionInfoWindow"];
}
*/
//save item
self.windowController.itemObj = selectedItem;
}
return self;
}
//automatically called when nib is loaded
// ->save self into iVar, and center window
-(void)awakeFromNib
{
//configure UI
[self configure];
//center
[self.window center];
}
//configure window
// ->add item's attributes (name, path, etc.)
-(void)configure
{
//task
// ->when showing info about a task
Task* task = nil;
//binary
// ->when showing info about a dylib
Binary* dylib = nil;
//handle tasks
if(YES == [self.itemObj isKindOfClass:[Task class]])
{
//cast as task
task = (Task*)self.itemObj;
//set icon
self.icon.image = task.binary.icon;
//set name
[self.name setStringValue:[self valueForStringItem:task.binary.name default:@"unknown"]];
//set command line
// ->done just in time (first time)
if(nil == task.arguments)
{
//get args
[((Task*)self.itemObj) getArguments];
}
//set args
[self.arguments setStringValue:[self valueForStringItem:[task.arguments componentsJoinedByString:@""] default:@"no arguments"]];
/*
//flagged files
// ->make name red!
if( (nil != ((File*)self.itemObj).vtInfo) &&
(0 != [((File*)self.itemObj).vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
{
//set color (light red)
self.name.textColor = [NSColor redColor];
}
*/
//set path
[self.path setStringValue:[self valueForStringItem:task.binary.path default:@"unknown"]];
//set hash
[self.hashes setStringValue:[NSString stringWithFormat:@"%@ / %@", task.binary.hashes[KEY_HASH_MD5], task.binary.hashes[KEY_HASH_SHA1]]];
//set size
[self.size setStringValue:[NSString stringWithFormat:@"%llu bytes", task.binary.attributes.fileSize]];
//set date
[self.date setStringValue:[NSString stringWithFormat:@"%@ (created) / %@ (modified)", task.binary.attributes.fileCreationDate, task.binary.attributes.fileModificationDate]];
//set signing info
[self.sign setStringValue:[self valueForStringItem:[task.binary formatSigningInfo] default:@"not signed"]];
}
//handle tasks
else if(YES == [self.itemObj isKindOfClass:[Binary class]])
{
//type cast
dylib = (Binary*)self.itemObj;
//set icon
self.icon.image = dylib.icon;
//set name
[self.name setStringValue:[self valueForStringItem:dylib.name default:@"unknown"]];
/*
//flagged files
// ->make name red!
if( (nil != ((File*)self.itemObj).vtInfo) &&
(0 != [((File*)self.itemObj).vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
{
//set color (light red)
self.name.textColor = [NSColor redColor];
}
*/
//set path
[self.path setStringValue:[self valueForStringItem:dylib.path default:@"unknown"]];
//set hash
[self.hashes setStringValue:[NSString stringWithFormat:@"%@ / %@", dylib.hashes[KEY_HASH_MD5], task.binary.hashes[KEY_HASH_SHA1]]];
//set size
[self.size setStringValue:[NSString stringWithFormat:@"%llu bytes", dylib.attributes.fileSize]];
//set date
[self.date setStringValue:[NSString stringWithFormat:@"%@ (created) / %@ (modified)", dylib.attributes.fileCreationDate, task.binary.attributes.fileModificationDate]];
//set signing info
[self.sign setStringValue:[self valueForStringItem:[dylib formatSigningInfo] default:@"not signed"]];
}
//handle File class
else if(YES == [self.itemObj isKindOfClass:[File class]])
{
//set icon
self.icon.image = getIconForBinary(self.itemObj.path, ((File*)itemObj).bundle);
//set name
[self.name setStringValue:self.itemObj.name];
/*
//flagged files
// ->make name red!
if( (nil != ((Binary*)self.itemObj).vtInfo) &&
(0 != [((File*)self.itemObj).vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
{
//set color (light red)
self.name.textColor = [NSColor redColor];
}
*/
//set path
[self.path setStringValue:self.itemObj.path];
//set hash
[self.hashes setStringValue:[NSString stringWithFormat:@"%@ / %@", ((File*)self.itemObj).hashes[KEY_HASH_MD5], ((File*)self.itemObj).hashes[KEY_HASH_SHA1]]];
//set size
[self.size setStringValue:[NSString stringWithFormat:@"%llu bytes", ((File*)self.itemObj).attributes.fileSize]];
//set date
[self.date setStringValue:[NSString stringWithFormat:@"%@ (created) / %@ (modified)", ((File*)self.itemObj).attributes.fileCreationDate, ((File*)self.itemObj).attributes.fileModificationDate]];
//set plist
if(nil != ((File*)self.itemObj).plist)
{
//set
[self.plist setStringValue:((File*)self.itemObj).plist];
}
//no plist
else
{
//set
[self.plist setStringValue:@"no plist for item"];
}
//set signing info
[self.sign setStringValue:[(File*)self.itemObj formatSigningInfo]];
}
/*
//handle Extension class
if(YES == [self.itemObj isKindOfClass:[Extension class]])
{
//set icon
self.icon.image = getIconForBinary(((Extension*)itemObj).browser, nil);
//set name
[self.name setStringValue:self.itemObj.name];
//set path
[self.path setStringValue:self.itemObj.path];
//set description
// ->optional
if(nil != ((Extension*)self.itemObj).details)
{
//set
[self.details setStringValue:[NSString stringWithFormat:@"%@", ((Extension*)self.itemObj).details]];
}
//set id
[self.identifier setStringValue:[NSString stringWithFormat:@"%@", ((Extension*)self.itemObj).identifier]];
//set date
[self.date setStringValue:[NSString stringWithFormat:@"%@ (created) / %@ (modified)", ((File*)self.itemObj).attributes.fileCreationDate, ((File*)self.itemObj).attributes.fileModificationDate]];
//set signing info
//[self.sign setStringValue:[(File*)self.itemObj formatSigningInfo]];
}
*/
return;
}
//check if something is nil
// ->if so, return the default
-(NSString*)valueForStringItem:(NSString*)item default:(NSString*)defaultValue
{
//return value
NSString* value = nil;
//check if item is nil/blank
if( (nil != item) &&
(item.length != 0))
{
//just set to item
value = item;
}
else
{
//set to default
value = defaultValue;
}
return value;
}
//automatically invoked when user clicks 'close'
// ->just close window
-(IBAction)closeWindow:(id)sender
{
//close
[self.window close];
}
@end
+39
View File
@@ -0,0 +1,39 @@
//
// ItemView.h
// TaskExplorer
//
// Created by Patrick Wardle on 5/23/15.
// Copyright (c) 2015 Lucas Derraugh. All rights reserved.
//
#import "File.h"
#import "Task.h"
#import "Binary.h"
#import "Connection.h"
#import <Foundation/Foundation.h>
/* METHODS */
//create customize item view
NSTableCellView* createItemView(NSTableView* tableView, id owner, id item);
//create & customize task view
NSTableCellView* createTaskView(NSTableView* tableView, id owner, id item);
//create & customize dylib view
NSTableCellView* createDylibView(NSTableView* tableView, id owner, Binary* dylib);
//create & customize file view
NSTableCellView* createFileView(NSTableView* tableView, id owner, File* file);
//create & customize networking view
NSTableCellView* createNetworkView(NSTableView* tableView, id owner, Connection* connection);
//add a tracking area to a view within the item view
void addTrackingArea(NSTableCellView* itemView, NSUInteger subviewTag, id owner);
//set code signing image
// ->either signed, unsigned, or unknown
NSImage* getCodeSigningIcon(Binary* binary);
+737
View File
@@ -0,0 +1,737 @@
//
// ItemView.m
// TaskExplorer
//
// Created by Patrick Wardle on 5/23/15.
// Copyright (c) 2015 Lucas Derraugh. All rights reserved.
//
#import "Consts.h"
#import "ItemView.h"
#import "VTButton.h"
#import "AppDelegate.h"
#import "3rdParty/OrderedDictionary.h"
//create customize item view
NSTableCellView* createItemView(NSTableView* tableView, id owner, id item)
{
//item cell
NSTableCellView *itemCell = nil;
//signature icon
NSImageView* signatureImageView = nil;
//VT detection ratio
NSString* vtDetectionRatio = nil;
//virus total button
// ->for File objects only...
VTButton* vtButton;
//(for files) signed/unsigned icon
NSImage* signatureStatus = nil;
//task's name frame
CGRect nameFrame = {0};
//attribute dictionary
NSMutableDictionary *stringAttributes = nil;
//paragraph style
NSMutableParagraphStyle *paragraphStyle = nil;
//binary obj
ItemBase* baseItem = nil;
//truncated path
//NSString* truncatedPath = nil;
//truncated plist
//NSString* truncatedPlist = nil;
//tracking area
NSTrackingArea* trackingArea = nil;
//flag indicating row has tracking area
// ->ensures we don't add 2x
BOOL hasTrackingArea = NO;
//sanity chec
if(nil == item)
{
//bail
goto bail;
}
//logic to create task view
if(YES == [item isKindOfClass:[Task class]])
{
//create & config view
itemCell = createTaskView(tableView, owner, item);
}
//logic to create dylib view
else if(YES == [item isKindOfClass:[Binary class]])
{
//create & config view
itemCell = createDylibView(tableView, owner, item);
}
//logic to create file view
else if(YES == [item isKindOfClass:[File class]])
{
//create & config view
itemCell = createFileView(tableView, owner, item);
}
//logic to create network view
else if(YES == [item isKindOfClass:[Connection class]])
{
//create & config view
itemCell = createNetworkView(tableView, owner, item);
}
return itemCell;
/*
//set
baseItem = ((Task*)item).binary;
}
//otherwise just assign
else
{
//set
baseItem = item;
}
//bail if base item is nil
// ->e.g. task doesn't have any dylibs, etc
if(nil == baseItem)
{
//bail
goto bail;
}
//make table cell
itemCell = [tableView makeViewWithIdentifier:@"TaskCell" owner:owner];
if(nil == itemCell)
{
//bail
goto bail;
}
//check if cell was previously used (by checking the item name)
// ->if so, set flag to indicated tracking area does not need to be added
if(YES != [itemCell.textField.stringValue isEqualToString:@"Item Name"])
{
//set flag
hasTrackingArea = YES;
}
//default
// ->set main textfield's color to black
itemCell.textField.textColor = [NSColor blackColor];
//set main text
// ->name
[itemCell.textField setStringValue:baseItem.name];
//get name frame
nameFrame = itemCell.textField.frame;
//adjust width to fit text
nameFrame.size.width = [itemCell.textField.stringValue sizeWithAttributes: @{NSFontAttributeName: itemCell.textField.font}].width + 5;
//disable autolayout
itemCell.textField.translatesAutoresizingMaskIntoConstraints = YES;
//update frame
// ->should now be exact size of text
itemCell.textField.frame = nameFrame;
//[itemCell.textField setDrawsBackground:YES];
//NSLog(@"size after: %f", itemCell.textField.frame.size.width);
//itemCell.textField.backgroundColor = [NSColor redColor];
*/
//set pid for tasks
if(YES == [item isKindOfClass:[Task class]])
{
//set pid
[((NSTextField*)[itemCell viewWithTag:TABLE_ROW_PID_LABEL]) setStringValue:[NSString stringWithFormat:@"(%@)", ((Task*)item).pid]];
}
//otherwise nil out pid
else
{
//set to nil to hide
[((NSTextField*)[itemCell viewWithTag:TABLE_ROW_PID_LABEL]) setStringValue:@""];
}
//only have to add tracking area once
// ->add it the first time
if(NO == hasTrackingArea)
{
//init tracking area
// ->for 'show' button
trackingArea = [[NSTrackingArea alloc] initWithRect:[[itemCell viewWithTag:TABLE_ROW_SHOW_BUTTON] bounds]
options:(NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways)
owner:owner userInfo:@{@"tag":[NSNumber numberWithUnsignedInteger:TABLE_ROW_SHOW_BUTTON]}];
//add tracking area to 'show' button
[[itemCell viewWithTag:TABLE_ROW_SHOW_BUTTON] addTrackingArea:trackingArea];
//init tracking area
// ->for 'info' button
trackingArea = [[NSTrackingArea alloc] initWithRect:[[itemCell viewWithTag:TABLE_ROW_INFO_BUTTON] bounds]
options:(NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways)
owner:owner userInfo:@{@"tag":[NSNumber numberWithUnsignedInteger:TABLE_ROW_INFO_BUTTON]}];
//add tracking area to 'info' button
[[itemCell viewWithTag:TABLE_ROW_INFO_BUTTON] addTrackingArea:trackingArea];
}
//set detailed text
// ->path
//if(YES == [item isKindOfClass:[File class]])
//{
//grab virus total button
// ->need it for frame computations, etc
vtButton = [itemCell viewWithTag:TABLE_ROW_VT_BUTTON];
//set image
// ->app's icon
itemCell.imageView.image = [baseItem icon];
//Tasks and Dylibs
// ->set signature icon
if( (YES == [item isKindOfClass:[Task class]]) ||
(YES == [item isKindOfClass:[Binary class]]) )
{
//get signature image view
signatureImageView = [itemCell viewWithTag:TABLE_ROW_SIGNATURE_ICON];
//set signature status icon
// note: if binary doesn't have signing info, default ('?') is shown...
if(nil != ((Binary*)baseItem).signingInfo)
{
if(STATUS_SUCCESS == [((Binary*)baseItem).signingInfo[KEY_SIGNATURE_STATUS] integerValue])
{
//signed
signatureImageView.image = [NSImage imageNamed:@"signed"];
}
else
{
//unsigned
signatureImageView.image = [NSImage imageNamed:@"unsigned"];
}
}
//show signature icon
signatureImageView.hidden = NO;
}
//non-executable files
// ->hide signature icon
else
{
//hide
signatureImageView.hidden = YES;
}
//set detailed text
// ->always item's path
[[itemCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:baseItem.path];
/*
//for files w/ plist
// ->set/show
if(nil != task.plist)
{
//shift up frame
pathFrame.origin.y = 20;
//set new frame
((NSTextField*)[itemCell viewWithTag:TABLE_ROW_PATH_LABEL]).frame = pathFrame;
//truncate plist
truncatedPlist = stringByTruncatingString([itemCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG], ((File*)item).plist, itemCell.frame.size.width-TABLE_BUTTONS_FILE);
//set plist
[((NSTextField*)[itemCell viewWithTag:TABLE_ROW_PLIST_LABEL]) setStringValue:truncatedPlist];
//show
[((NSTextField*)[itemCell viewWithTag:TABLE_ROW_PLIST_LABEL]) setHidden:NO];
}
*/
/*
//configure/show VT info
// ->only if 'disable' preference not set
if(YES != ((AppDelegate*)[[NSApplication sharedApplication] delegate]).prefsWindowController.disableVTQueries)
{
//set button delegate
vtButton.delegate = self;
//save file obj
vtButton.fileObj = task
//check if have vt results
if(nil != ((File*)item).vtInfo)
{
//set font
[vtButton setFont:[NSFont fontWithName:@"Menlo-Bold" size:25]];
//enable
vtButton.enabled = YES;
//got VT results
// ->check 'permalink' to determine if file is known to VT
// then, show ratio and set to red if file is flagged
if(nil != ((File*)item).vtInfo[VT_RESULTS_URL])
{
//alloc paragraph style
paragraphStyle = [[NSMutableParagraphStyle alloc] init];
//center the text
[paragraphStyle setAlignment:NSCenterTextAlignment];
//alloc attributes dictionary
stringAttributes = [NSMutableDictionary dictionary];
//set underlined attribute
stringAttributes[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle);
//set alignment (center)
stringAttributes[NSParagraphStyleAttributeName] = paragraphStyle;
//set font
stringAttributes[NSFontAttributeName] = [NSFont fontWithName:@"Menlo-Bold" size:15];
//compute detection ratio
vtDetectionRatio = [NSString stringWithFormat:@"%lu/%lu", (unsigned long)[((File*)item).vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue], (unsigned long)[((File*)item).vtInfo[VT_RESULTS_TOTAL] unsignedIntegerValue]];
//known 'good' files (0 positivies)
if(0 == [((File*)item).vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue])
{
//(re)set title black
itemCell.textField.textColor = [NSColor blackColor];
//set color (black)
stringAttributes[NSForegroundColorAttributeName] = [NSColor blackColor];
//set string (vt ratio), with attributes
[vtButton setAttributedTitle:[[NSAttributedString alloc] initWithString:vtDetectionRatio attributes:stringAttributes]];
//set color (gray)
stringAttributes[NSForegroundColorAttributeName] = [NSColor grayColor];
//set selected text color
[vtButton setAttributedAlternateTitle:[[NSAttributedString alloc] initWithString:vtDetectionRatio attributes:stringAttributes]];
}
//files flagged by VT
// ->set name and detection to red
else
{
//set title red
itemCell.textField.textColor = [NSColor redColor];
//set color (red)
stringAttributes[NSForegroundColorAttributeName] = [NSColor redColor];
//set string (vt ratio), with attributes
[vtButton setAttributedTitle:[[NSAttributedString alloc] initWithString:vtDetectionRatio attributes:stringAttributes]];
//set selected text color
[vtButton setAttributedAlternateTitle:[[NSAttributedString alloc] initWithString:vtDetectionRatio attributes:stringAttributes]];
}
//enable
[vtButton setEnabled:YES];
}
//file is not known
// ->reset title to '?'
else
{
//set title
[vtButton setTitle:@"?"];
}
}
//no VT results (e.g. unknown file)
else
{
//set font
[vtButton setFont:[NSFont fontWithName:@"Menlo-Bold" size:8]];
//set title
[vtButton setTitle:@"▪ ▪ ▪"];
//disable
vtButton.enabled = NO;
}
//show virus total button
vtButton.hidden = NO;
//show virus total label
[[itemCell viewWithTag:TABLE_ROW_VT_BUTTON+1] setHidden:NO];
}//show VT info (pref not disabled)
//hide VT info
else
{
//hide virus total button
vtButton.hidden = YES;
//hide virus total button label
[[itemCell viewWithTag:TABLE_ROW_VT_BUTTON+1] setHidden:YES];
}
*/
//bail
bail:
return itemCell;
}
//add a tracking area to a view within the item view
void addTrackingArea(NSTableCellView* itemView, NSUInteger subviewTag, id owner)
{
//tracking area
NSTrackingArea* trackingArea = nil;
//alloc/init tracking area
trackingArea = [[NSTrackingArea alloc] initWithRect:[[itemView viewWithTag:subviewTag] bounds] options:(NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:owner userInfo:@{@"tag":[NSNumber numberWithUnsignedInteger:subviewTag]}];
//add tracking area to subview
[[itemView viewWithTag:subviewTag] addTrackingArea:trackingArea];
return;
}
//set code signing image
// ->either signed, unsigned, or unknown
NSImage* getCodeSigningIcon(Binary* binary)
{
//signature image
NSImage* codeSignIcon = nil;
//set signature status icon
if(nil != binary.signingInfo)
{
//binary is signed
if(STATUS_SUCCESS == [binary.signingInfo[KEY_SIGNATURE_STATUS] integerValue])
{
//set
codeSignIcon = [NSImage imageNamed:@"signed"];
}
//binary not signed
else if(errSecCSUnsigned == [binary.signingInfo[KEY_SIGNATURE_STATUS] integerValue])
{
//set
codeSignIcon = [NSImage imageNamed:@"unsigned"];
}
//unknown
else
{
//set
codeSignIcon = [NSImage imageNamed:@"unknown"];
}
}
//signing info is nil
// ->just to unknown
else
{
//set
codeSignIcon = [NSImage imageNamed:@"unknown"];
}
return codeSignIcon;
}
//create & customize Task view
NSTableCellView* createTaskView(NSTableView* tableView, id owner, Task* task)
{
//item cell
NSTableCellView* taskCell = nil;
//task's name frame
CGRect nameFrame = {0};
//sanity check
if(nil == task.binary)
{
//bail
goto bail;
}
//create cell
taskCell = [tableView makeViewWithIdentifier:@"TaskCell" owner:owner];
if(nil == taskCell)
{
//bail
goto bail;
}
//brand new cells need tracking areas
// ->determine if new, by checking default (.xib/IB) value
if(YES == [taskCell.textField.stringValue isEqualToString:@"Task Name"])
{
//add tracking area
// ->'vt' button
addTrackingArea(taskCell, TABLE_ROW_VT_BUTTON, owner);
//add tracking area
// ->'info' button
addTrackingArea(taskCell, TABLE_ROW_INFO_BUTTON, owner);
//add tracking area
// ->'show' button
addTrackingArea(taskCell, TABLE_ROW_SHOW_BUTTON, owner);
}
//set icon
taskCell.imageView.image = [task.binary icon];
//set code signing icon
((NSImageView*)[taskCell viewWithTag:TABLE_ROW_SIGNATURE_ICON]).image = getCodeSigningIcon(task.binary);
//default
// ->(re)set main textfield's color to black
taskCell.textField.textColor = [NSColor blackColor];
//set main text
// ->name
[taskCell.textField setStringValue:task.binary.name];
//get name frame
nameFrame = taskCell.textField.frame;
//adjust width to fit text
nameFrame.size.width = [taskCell.textField.stringValue sizeWithAttributes: @{NSFontAttributeName: taskCell.textField.font}].width + 5;
//disable autolayout for name
taskCell.textField.translatesAutoresizingMaskIntoConstraints = YES;
//update name frame
// ->should now be exact size of text
taskCell.textField.frame = nameFrame;
//set pid
// ->immediately follows name
[((NSTextField*)[taskCell viewWithTag:TABLE_ROW_PID_LABEL]) setStringValue:[NSString stringWithFormat:@"(%@)", task.pid]];
//set path
[[taskCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:task.binary.path];
//bail
bail:
return taskCell;
}
//create & customize dylib view
NSTableCellView* createDylibView(NSTableView* tableView, id owner, Binary* dylib)
{
//item cell
NSTableCellView* dylibCell = nil;
//create cell
dylibCell = [tableView makeViewWithIdentifier:@"DylibCell" owner:owner];
if(nil == dylibCell)
{
//bail
goto bail;
}
//brand new cells need tracking areas
// ->determine if new, by checking default (.xib/IB) value
if(YES == [dylibCell.textField.stringValue isEqualToString:@"Dylib Name"])
{
//add tracking area
// ->'vt' button
addTrackingArea(dylibCell, TABLE_ROW_VT_BUTTON, owner);
//add tracking area
// ->'info' button
addTrackingArea(dylibCell, TABLE_ROW_INFO_BUTTON, owner);
//add tracking area
// ->'show' button
addTrackingArea(dylibCell, TABLE_ROW_SHOW_BUTTON, owner);
}
//set code signing icon
((NSImageView*)[dylibCell viewWithTag:TABLE_ROW_SIGNATURE_ICON]).image = getCodeSigningIcon(dylib);
//default
// ->(re)set main textfield's color to black
dylibCell.textField.textColor = [NSColor blackColor];
//set main text
// ->name
[dylibCell.textField setStringValue:dylib.name];
//set path
[[dylibCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:dylib.path];
//bail
bail:
return dylibCell;
}
//create & customize file view
NSTableCellView* createFileView(NSTableView* tableView, id owner, File* file)
{
//item cell
NSTableCellView* fileCell = nil;
//sanity check
if(nil == file)
{
//bail
goto bail;
}
//create cell
fileCell = [tableView makeViewWithIdentifier:@"FileCell" owner:owner];
if(nil == fileCell)
{
//bail
goto bail;
}
//brand new cells need tracking areas
// ->determine if new, by checking default (.xib/IB) value
if(YES == [fileCell.textField.stringValue isEqualToString:@"Dylib Name"])
{
//add tracking area
// ->'info' button
addTrackingArea(fileCell, TABLE_ROW_INFO_BUTTON, owner);
//add tracking area
// ->'show' button
addTrackingArea(fileCell, TABLE_ROW_SHOW_BUTTON, owner);
}
//default
// ->(re)set main textfield's color to black
fileCell.textField.textColor = [NSColor blackColor];
//set main text
// ->name
[fileCell.textField setStringValue:file.name];
//set path
[[fileCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:file.path];
//bail
bail:
return fileCell;
}
//create & customize networking view
NSTableCellView* createNetworkView(NSTableView* tableView, id owner, Connection* connection)
{
//item cell
NSTableCellView* connectionCell = nil;
//connection endpoint
NSMutableString* endpoints = nil;
//connection details
NSMutableString* details = nil;
//alloc string for endpoints
endpoints = [NSMutableString string];
//alloc string for details
details = [NSMutableString string];
//create cell
connectionCell = [tableView makeViewWithIdentifier:@"NetworkCell" owner:owner];
if(nil == connectionCell)
{
//bail
goto bail;
}
//set icon
//TODO: (re)set default icon!?
if(nil != connection.state)
{
//listening
if(YES == [connection.state isEqualToString:SOCKET_LISTENING])
{
//set
connectionCell.imageView.image = [NSImage imageNamed:@"listeningIcon"];
}
//connected
else if(YES == [connection.state isEqualToString:SOCKET_ESTABLISHED])
{
//set
connectionCell.imageView.image = [NSImage imageNamed:@"connectedIcon"];
}
}
//default
// ->(re)set main textfield's color to black
connectionCell.textField.textColor = [NSColor blackColor];
//add local addr/port to endpoint string
[endpoints appendString:[NSString stringWithFormat:@"%@:%d", connection.localIPAddr, [connection.localPort unsignedShortValue]]];
//for remote connections
// ->add remote endpoint
if( (nil != connection.remoteIPAddr) &&
(nil != connection.remotePort) )
{
//add remote endpoint
[endpoints appendString:[NSString stringWithFormat:@" -> %@:%d", connection.remoteIPAddr, [connection.remotePort unsignedShortValue]]];
}
//set main text
// ->connection endpoints
[connectionCell.textField setStringValue:endpoints];
//set details
if(nil != connection.state)
{
//add state
[details appendString:connection.state];
}
//set details
[[connectionCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:details];
//bail
bail:
return connectionCell;
}
+72
View File
@@ -0,0 +1,72 @@
//
// File.h
// KnockKnock
//
// Created by Patrick Wardle on 2/19/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "ItemBase.h"
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
@interface Binary : ItemBase
{
}
/* PROPERTIES */
//name
@property(nonatomic, retain)NSString* name;
//path
@property(nonatomic, retain)NSString* path;
//bundle
@property(nonatomic, retain)NSBundle* bundle;
//TODO: no needed?
//flag for task (main) executable
@property BOOL isTaskBinary;
//hashes (md5, sha1)
@property(nonatomic, retain)NSDictionary* hashes;
//signing info
@property(nonatomic, retain)NSDictionary* signingInfo;
/* VIRUS TOTAL INFO */
//dictionary returned by VT
@property (nonatomic, retain)NSDictionary* vtInfo;
/* METHODS */
//init method
-(id)initWithParams:(NSDictionary*)params;
//get task's name
// ->either from bundle or path's last component
-(NSString*)getName;
//get an icon for a process
-(NSImage*)getIcon;
//get signing info (which takes a while to generate)
// ->this method should be called in the background
-(void)generatedSigningInfo;
//get detailed info (which takes a while to generate)
// ->only shown to user if they click 'info' so this method should be called in the background
-(void)generateDetailedInfo;
//format the signing info dictionary
-(NSString*)formatSigningInfo;
@end
+358
View File
@@ -0,0 +1,358 @@
//
// File.m
// KnockKnock
//
// Created by Patrick Wardle on 2/19/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "Binary.h"
#import "Consts.h"
#import "Utilities.h"
#import "AppDelegate.h"
@implementation Binary
@synthesize path;
@synthesize name;
@synthesize icon;
@synthesize bundle;
@synthesize hashes;
@synthesize signingInfo;
@synthesize isTaskBinary;
@synthesize vtInfo;
//init method
-(id)initWithParams:(NSDictionary*)params
{
//super
// ->saves path, etc
self = [super initWithParams:params];
if(self)
{
//since path is always full path to binary
// ->manaully try to find & load bundle (for .apps)
self.bundle = findAppBundle(self.path);
/* now we have bundle (maybe), try get name and icon */
//get task's name
// ->either from bundle or path's last component
self.name = [self getName];
//get task's icon
// ->either from bundle or just use system icon
self.icon = [self getIcon];
//grab attributes
//self.attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:self.path error:nil];
//do this in bg!
//set signing info
//self.signingInfo = extractSigningInfo(self.path);
//computes hashes
// ->set 'md5' and 'sha1' iVars
//self.hashes = hashFile(self.path);
//call into filter object to check if file is known
// ->apple-signed or whitelisted
//self.isTrusted = [((AppDelegate*)[[NSApplication sharedApplication] delegate]).filterObj isTrustedFile:self];
}
//bail
bail:
return self;
}
//get task's name
// ->either from bundle or path's last component
-(NSString*)getName
{
//name
NSString* taskName = nil;
//try to get name from bundle
// ->key 'CFBundleName'
if(nil != self.bundle)
{
//extract name
taskName = [self.bundle infoDictionary][@"CFBundleName"];
}
//no bundle/ or bundle lookup failed
// ->just use last component of path
if(nil == taskName)
{
//special case
// ->kernel -> 'kernel_task'
if(YES == [self.path isEqualToString:path2Kernel()])
{
//set kernel
taskName = @"kernel_task";
}
//default
// ->name is just last component of path
else
{
//extract name
taskName = [self.path lastPathComponent];
}
}
return taskName;
}
//TODO: fix: "Path kernel_task given to -[NSWorkspace iconForFile:] is not a full path."
//get an icon for a process
// ->for apps, this will be app's icon, otherwise just a standard system one
-(NSImage*)getIcon
{
//icon's file name
NSString* iconFile = nil;
//icon's path
NSString* iconPath = nil;
//icon's path extension
NSString* iconExtension = nil;
//icon
NSImage* taskIcon = nil;
//for app's
// ->extract their icon
if(nil != self.bundle)
{
//get file
iconFile = self.bundle.infoDictionary[@"CFBundleIconFile"];
//get path extension
iconExtension = [iconFile pathExtension];
//if its blank (i.e. not specified)
// ->go with 'icns'
if(YES == [iconExtension isEqualTo:@""])
{
//set type
iconExtension = @"icns";
}
//set full path
iconPath = [self.bundle pathForResource:[iconFile stringByDeletingPathExtension] ofType:iconExtension];
//load it
taskIcon = [[NSImage alloc] initWithContentsOfFile:iconPath];
}
//process is not an app or couldn't get icon
// ->try to get it via shared workspace
if( (nil == self.bundle) ||
(nil == taskIcon) )
{
//extract icon
taskIcon = [[NSWorkspace sharedWorkspace] iconForFile:self.path];
}
return taskIcon;
}
//TODO: green signing for apple!!!
//get signing info (which takes a while to generate)
// ->this method should be called in the background
-(void)generatedSigningInfo
{
//set signing info
self.signingInfo = extractSigningInfo(self.path);
return;
}
//get detailed info (which takes a while to generate)
// ->only shown to user if they click 'info' so this method should be called in the background
-(void)generateDetailedInfo
{
//grab file attributes
self.attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:self.path error:nil];
//computes hashes
// ->set 'md5' and 'sha1' iVars
self.hashes = hashFile(self.path);
//call into filter object to check if file is known
// ->apple-signed or whitelisted
self.isTrusted = [((AppDelegate*)[[NSApplication sharedApplication] delegate]).filterObj isTrustedFile:self];
return;
}
//format the signing info dictionary
-(NSString*)formatSigningInfo
{
//pretty print
NSMutableString* prettyPrint = nil;
//sanity check
if(nil == self.signingInfo)
{
//bail
goto bail;
}
//switch on signing status
switch([self.signingInfo[KEY_SIGNATURE_STATUS] integerValue])
{
//unsigned
case errSecCSUnsigned:
{
//set string
prettyPrint = [NSMutableString stringWithString:@"unsigned"];
//brk
break;
}
//errSecCSSignatureFailed
case errSecCSSignatureFailed:
{
//set string
prettyPrint = [NSMutableString stringWithString:@"invalid signature"];
//brk
break;
}
//happily signed
case STATUS_SUCCESS:
{
//init
prettyPrint = [NSMutableString string];//stringWithString:@"signed by:"];
//add each signing auth
for(NSString* signingAuthority in self.signingInfo[KEY_SIGNING_AUTHORITIES])
{
//append
[prettyPrint appendString:[NSString stringWithFormat:@"%@, ", signingAuthority]];
}
//remove last comma & space
if(YES == [prettyPrint hasSuffix:@", "])
{
//remove
[prettyPrint deleteCharactersInRange:NSMakeRange([prettyPrint length]-2, 2)];
}
//brk
break;
}
//unknown
default:
//set string
prettyPrint = [NSMutableString stringWithFormat:@"unknown (status/error: %ld)", (long)[self.signingInfo[KEY_SIGNATURE_STATUS] integerValue]];
//brk
break;
}
//bail
bail:
return prettyPrint;
}
//convert object to JSON string
-(NSString*)toJSON
{
//json string
NSString *json = nil;
//json data
// ->for intermediate conversions
NSData *jsonData = nil;
//hashes
NSString* fileHashes = nil;
//signing info
NSString* fileSigs = nil;
//VT detection ratio
NSString* vtDetectionRatio = nil;
//init file hash to default string
// ->used when hashes are nil, or serialization fails
fileHashes = @"\"unknown\"";
//init file signature to default string
// ->used when signatures are nil, or serialization fails
fileSigs = @"\"unknown\"";
//convert hashes to JSON
if(nil != self.hashes)
{
//convert hash dictionary
// ->wrap since we are serializing JSON
@try
{
//convert
jsonData = [NSJSONSerialization dataWithJSONObject:self.hashes options:kNilOptions error:NULL];
if(nil != jsonData)
{
//convert data to string
fileHashes = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
//ignore exceptions
// ->file hashes will just be 'unknown'
@catch(NSException *exception)
{
;
}
}
//convert signing dictionary to JSON
if(nil != self.signingInfo)
{
//convert signing dictionary
// ->wrap since we are serializing JSON
@try
{
//convert
jsonData = [NSJSONSerialization dataWithJSONObject:self.signingInfo options:kNilOptions error:NULL];
if(nil != jsonData)
{
//convert data to string
fileSigs = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
//ignore exceptions
// ->file sigs will just be 'unknown'
@catch(NSException *exception)
{
;
}
}
//init VT detection ratio
vtDetectionRatio = [NSString stringWithFormat:@"%lu/%lu", (unsigned long)[self.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue], (unsigned long)[self.vtInfo[VT_RESULTS_TOTAL] unsignedIntegerValue]];
//init json
json = [NSString stringWithFormat:@"\"name\": \"%@\", \"path\": \"%@\", \"hashes\": %@, \"signature(s)\": %@, \"VT detection\": \"%@\"", self.name, self.path, fileHashes, fileSigs, vtDetectionRatio];
return json;
}
@end
+45
View File
@@ -0,0 +1,45 @@
//
// Extension.h
// KnockKnock
//
// Created by Patrick Wardle on 2/19/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "ItemBase.h"
#import <Foundation/Foundation.h>
@interface Connection : ItemBase
{
}
//local ip addr
@property(nonatomic, retain)NSString* localIPAddr;
//local port
@property(nonatomic, retain)NSNumber* localPort;
//remote ip addr
@property(nonatomic, retain)NSString* remoteIPAddr;
//remote port
@property(nonatomic, retain)NSNumber* remotePort;
//socket type
@property(nonatomic, retain)NSString* type;
//socket family
@property(nonatomic, retain)NSString* family;
//socket proto
@property(nonatomic, retain)NSString* proto;
//socket state
@property(nonatomic, retain)NSString* state;
/* METHODS */
@end
+68
View File
@@ -0,0 +1,68 @@
//
// Extension.m
// KnockKnock
//
// Created by Patrick Wardle on 2/19/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "Consts.h"
#import "Connection.h"
#import "AppDelegate.h"
@implementation Connection
//init method
-(id)initWithParams:(NSDictionary*)params
{
//super
//self = [super initWithParams:params];
//TODO: think about this - Connection doesn't share any baseItem stuffz
self = [super init];
if(nil != self)
{
//extract/save local addr
self.localIPAddr = params[KEY_LOCAL_ADDR];
//extract/save local port
self.localPort = params[KEY_LOCAL_PORT];
//extract/save remote addr
self.remoteIPAddr = params[KEY_REMOTE_ADDR];
//extract/save remote port
self.remotePort = params[KEY_REMOTE_PORT];
//extract/save type
self.type = params[KEY_SOCKET_TYPE];
//extract/save family
self.family = params[KEY_SOCKET_FAMILY];
//extract/save proto
self.proto = params[KEY_SOCKET_PROTO];
//extract/save state
self.state = params[KEY_SOCKET_STATE];
}
return self;
}
/*
//convert object to JSON string
-(NSString*)toJSON
{
//json string
NSString *json = nil;
//init json
json = [NSString stringWithFormat:@"\"name\": \"%@\", \"path\": \"%@\", \"identifier\": \"%@\", \"details\": \"%@\", \"browser\": \"%@\"", self.name, self.path, self.identifier, self.details, self.browser];
return json;
}
*/
@end
+55
View File
@@ -0,0 +1,55 @@
//
// File.h
// KnockKnock
//
// Created by Patrick Wardle on 2/19/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "ItemBase.h"
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
@interface File : ItemBase
{
}
/* PROPERTIES */
//name
@property(nonatomic, retain)NSString* name;
//path
@property(nonatomic, retain)NSString* path;
//plist
@property(nonatomic, retain)NSString* plist;
//bundle
@property(nonatomic, retain)NSBundle* bundle;
//hashes (md5, sha1)
@property(nonatomic, retain)NSDictionary* hashes;
//signing info
@property(nonatomic, retain)NSDictionary* signingInfo;
/* METHODS */
//init method
-(id)initWithParams:(NSDictionary*)params;
//get detailed info (which takes a while to generate)
// ->only shown to user if they click 'info' so this method is called in the background
-(void)generateDetailedInfo;
//format the signing info dictionary
-(NSString*)formatSigningInfo;
@end
+211
View File
@@ -0,0 +1,211 @@
//
// File.m
// KnockKnock
//
// Created by Patrick Wardle on 2/19/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "File.h"
#import "Consts.h"
#import "Utilities.h"
#import "AppDelegate.h"
@implementation File
@synthesize path;
@synthesize name;
@synthesize plist;
@synthesize bundle;
@synthesize hashes;
@synthesize signingInfo;
//@synthesize vtInfo;
//init method
-(id)initWithParams:(NSDictionary*)params
{
//flag for directories
BOOL isDirectory = NO;
//super
// ->saves path, etc
self = [super initWithParams:params];
if(self)
{
//always skip not-existent paths
// ->also get set a directory flag at the same time ;)
if(YES != [[NSFileManager defaultManager] fileExistsAtPath:params[KEY_RESULT_PATH] isDirectory:&isDirectory])
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: %@ not found", params[KEY_RESULT_PATH]);
//set self to nil
self = nil;
//bail
goto bail;
}
//if path is directory
// ->treat is as a bundle
if(YES == isDirectory)
{
//load bundle
// ->save this into 'bundle' iVar
if(nil == (bundle = [NSBundle bundleWithPath:params[KEY_RESULT_PATH]]))
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: couldn't create bundle for %@", params[KEY_RESULT_PATH]);
//set self to nil
self = nil;
//bail
goto bail;
}
//extract executable from bundle
// ->save this into 'path' iVar
if(nil == (self.path = self.bundle.executablePath))
{
//err msg
//NSLog(@"OBJECTIVE-SEE ERROR: couldn't find executable in bundle %@", itemPath);
//set self to nil
self = nil;
//bail
goto bail;
}
}
//save (optional) plist
// ->ok if this is nil
self.plist = params[KEY_RESULT_PLIST];
//extract name
self.name = [[self.path lastPathComponent] stringByDeletingPathExtension];
}
//bail
bail:
return self;
}
//get detailed info (which takes a while to generate)
// ->only shown to user if they click 'info' so this method is called in the background
-(void)generateDetailedInfo
{
//grab attributes
//TODO: done elsewhere?
self.attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:self.path error:nil];
//computes hashes
// ->set 'md5' and 'sha1' iVars
self.hashes = hashFile(self.path);
return;
}
//convert object to JSON string
-(NSString*)toJSON
{
//json string
NSString *json = nil;
//json data
// ->for intermediate conversions
NSData *jsonData = nil;
//plist
NSString* filePlist = nil;
//hashes
NSString* fileHashes = nil;
//signing info
NSString* fileSigs = nil;
//init file hash to default string
// ->used when hashes are nil, or serialization fails
fileHashes = @"\"unknown\"";
//init file signature to default string
// ->used when signatures are nil, or serialization fails
fileSigs = @"\"unknown\"";
//convert hashes to JSON
if(nil != self.hashes)
{
//convert hash dictionary
// ->wrap since we are serializing JSON
@try
{
//convert
jsonData = [NSJSONSerialization dataWithJSONObject:self.hashes options:kNilOptions error:NULL];
if(nil != jsonData)
{
//convert data to string
fileHashes = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
//ignore exceptions
// ->file hashes will just be 'unknown'
@catch(NSException *exception)
{
;
}
}
//convert signing dictionary to JSON
if(nil != self.signingInfo)
{
//convert signing dictionary
// ->wrap since we are serializing JSON
@try
{
//convert
jsonData = [NSJSONSerialization dataWithJSONObject:self.signingInfo options:kNilOptions error:NULL];
if(nil != jsonData)
{
//convert data to string
fileSigs = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
//ignore exceptions
// ->file sigs will just be 'unknown'
@catch(NSException *exception)
{
;
}
}
//provide a default string if the file doesn't have a plist
if(nil == self.plist)
{
//set
filePlist = @"n/a";
}
//use plist as is
else
{
//set
filePlist = self.plist;
}
//init VT detection ratio
//vtDetectionRatio = [NSString stringWithFormat:@"%lu/%lu", (unsigned long)[self.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue], (unsigned long)[self.vtInfo[VT_RESULTS_TOTAL] unsignedIntegerValue]];
//init json
json = [NSString stringWithFormat:@"\"name\": \"%@\", \"path\": \"%@\", \"plist\": \"%@\", \"hashes\": %@, \"signature(s)\": %@", self.name, self.path, filePlist, fileHashes, fileSigs];
return json;
}
@end
+46
View File
@@ -0,0 +1,46 @@
//
// ItemBase.h
// BlockBlock
//
// Created by Patrick Wardle on 9/25/14.
// Copyright (c) 2014 Synack. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ItemBase : NSObject
{
}
//name
@property(retain, nonatomic)NSString* name;
//path
@property(retain, nonatomic)NSString* path;
//icon
@property(nonatomic, retain)NSImage* icon;
//file attributes
@property(nonatomic, retain)NSDictionary* attributes;
//flag if known
// ->signed by apple and/or whitelisted
@property BOOL isTrusted;
/* METHODS */
//init method
-(id)initWithParams:(NSDictionary*)params;
//return a path that can be opened in Finder.app
-(NSString*)pathForFinder;
//convert object to JSON string
-(NSString*)toJSON;
@end
+80
View File
@@ -0,0 +1,80 @@
//
// ItemBase.m
// TaskExplorer
#import "Consts.h"
#import "ItemBase.h"
#define kErrFormat @"%@ not implemented in subclass %@"
#define kExceptName @"KK Item"
@implementation ItemBase
@synthesize name;
@synthesize path;
@synthesize isTrusted;
@synthesize attributes;
//init method
-(id)initWithParams:(NSDictionary*)params
{
//super
self = [super init];
if(nil != self)
{
//save plugin
//self.plugin = params[KEY_RESULT_PLUGIN];
//extract/save name
self.name = params[KEY_RESULT_NAME];
//extract/save path
self.path = params[KEY_RESULT_PATH];
//get attributes
// ->based off path
self.attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:self.path error:nil];
}
return self;
}
//return a path that can be opened in Finder.app
-(NSString*)pathForFinder
{
return self.path;
}
//return
/* OPTIONAL METHODS */
/* REQUIRED METHODS */
//stubs for inherited methods
// ->all just throw exceptions as they should be implemented in sub-classes
//scan
-(void)scan:(NSDictionary*)scanOptions
{
@throw [NSException exceptionWithName:kExceptName
reason:[NSString stringWithFormat:kErrFormat, NSStringFromSelector(_cmd), [self class]]
userInfo:nil];
return;
}
//convert object to JSON string
-(NSString*)toJSON
{
@throw [NSException exceptionWithName:kExceptName
reason:[NSString stringWithFormat:kErrFormat, NSStringFromSelector(_cmd), [self class]]
userInfo:nil];
return nil;
}
@end
+13
View File
@@ -0,0 +1,13 @@
//
// CategoryRow.h
// KnockKnock
//
// Created by Patrick Wardle on 4/4/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface KKRow : NSTableRowView
@end
+48
View File
@@ -0,0 +1,48 @@
//
// CategoryRow.m
// KnockKnock
//
// Created by Patrick Wardle on 4/4/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "KKRow.h"
@implementation KKRow
//custom row selection
-(void)drawSelectionInRect:(NSRect)dirtyRect
{
//selection rect
NSRect selectionRect = {0};
//selection path
NSBezierPath *selectionPath = nil;
//highlight selected rows
if(self.selectionHighlightStyle != NSTableViewSelectionHighlightStyleNone)
{
//make selection rect
selectionRect = NSInsetRect(self.bounds, 2.5, 2.5);
//set stroke
[[NSColor colorWithCalibratedWhite:.65 alpha:1.0] setStroke];
//set fill
[[NSColor colorWithCalibratedWhite:.82 alpha:1.0] setFill];
//create selection path
// ->with rounded corners
selectionPath = [NSBezierPath bezierPathWithRoundedRect:selectionRect xRadius:5 yRadius:5];
//fill
[selectionPath fill];
//stroke
[selectionPath stroke];
}
return;
}
@end
+27
View File
@@ -0,0 +1,27 @@
//
// NSMutableArray+QueueAdditions.h
// BlockBlock
//
// Created by Patrick Wardle on 9/26/14.
// Copyright (c) 2014 Synack. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSMutableArray (QueueAdditions)
{
}
//METHODS
//remove first object
-(id)dequeue;
//add to end
-(void)enqueue:(id)obj;
//check if empty
-(BOOL)empty;
@end
+54
View File
@@ -0,0 +1,54 @@
//
// NSMutableArray+QueueAdditions.m
// BlockBlock
//
// Created by Patrick Wardle on 9/26/14.
// Copyright (c) 2014 Synack. All rights reserved.
//
#import "NSMutableArray+QueueAdditions.h"
@implementation NSMutableArray (QueueAdditions)
//add object to tail (end) of queue
-(void)enqueue:(id)anObject
{
//sync
@synchronized(self)
{
//add object
[self addObject: anObject];
}
}
//grab next item in queue
-(id)dequeue
{
//extract object
id queueObject = nil;
//sync
@synchronized(self)
{
//check to make sure there are some items
if(YES != [self empty])
{
//extract first one
queueObject = [self objectAtIndex: 0];
//delete it from queue
[self removeObjectAtIndex: 0];
}
}//sync
return queueObject;
}
// Checks if the queue is empty
-(BOOL)empty
{
return ([self lastObject] == nil);
}
@end
+55
View File
@@ -0,0 +1,55 @@
//
// PrefsWindowController.h
// DHS
//
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface PrefsWindowController : NSWindowController <NSWindowDelegate>
{
}
//buttons
//button for filtering out OS componets
@property (weak) IBOutlet NSButton* showTrustedItemsBtn;
//button for disabling talking to VT
@property (weak) IBOutlet NSButton* disableVTQueriesBtn;
//button for saving output
@property (weak) IBOutlet NSButton* saveOutputBtn;
//button for ok/close
@property (weak) IBOutlet NSButton *okButton;
//filter out OS/known items
@property BOOL showTrustedItems;
//disable talking to VT
@property BOOL disableVTQueries;
//save results (at end of scan)
@property BOOL saveOutput;
//save results now
@property BOOL shouldSaveNow;
/* METHODS */
//save existing prefs
-(void)captureExistingPrefs;
//'OK' button handler
// ->save prefs and close window
-(IBAction)closeWindow:(id)sender;
/* METHODS */
@end
+125
View File
@@ -0,0 +1,125 @@
//
// PrefsWindowController.m
// KnockKnock
//
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
//
#import "AppDelegate.h"
#import "PrefsWindowController.h"
@implementation PrefsWindowController
@synthesize okButton;
@synthesize saveOutput;
@synthesize shouldSaveNow;
@synthesize disableVTQueries;
@synthesize showTrustedItems;
//automatically called when nib is loaded
// ->center window
-(void)awakeFromNib
{
//center
[self.window center];
}
//automatically invoked when window is loaded
// ->set to white
-(void)windowDidLoad
{
//super
[super windowDidLoad];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//make button selected
[self.window makeFirstResponder:self.okButton];
//capture existing prefs
// ->needed to trigger re-saves
[self captureExistingPrefs];
return;
}
//save existing prefs
-(void)captureExistingPrefs
{
//save current state of 'include os/trusted' components
self.showTrustedItems = self.showTrustedItemsBtn.state;
//save current state of 'disable VT'
self.disableVTQueries = self.disableVTQueriesBtn.state;
//save current state of 'save' button
self.saveOutput = self.saveOutputBtn.state;
return;
}
//automatically invoked when window is closing
// ->make ourselves unmodal
-(void)windowWillClose:(NSNotification *)notification
{
//save prefs
[self savePrefs];
//make un-modal
[[NSApplication sharedApplication] stopModal];
return;
}
//save prefs
-(void)savePrefs
{
//first, any prefs changed, a 'save' set
// ->set 'save now' flag
if( ((self.showTrustedItems != self.showTrustedItemsBtn.state) ||
(self.disableVTQueries != self.disableVTQueriesBtn.state) ||
(self.saveOutput != self.saveOutputBtn.state) ) &&
(YES == self.saveOutputBtn.state) )
{
//set
self.shouldSaveNow = YES;
}
//don't save
else
{
//unset
self.shouldSaveNow = NO;
}
//save hiding OS components flag
self.showTrustedItems = self.showTrustedItemsBtn.state;
//save disabling VT flag
self.disableVTQueries = self.disableVTQueriesBtn.state;
//save save output flag
self.saveOutput = self.saveOutputBtn.state;
//call back up into app delegate for filtering/hiding OS components
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) applyPreferences];
return;
}
//'OK' button handler
// ->save prefs and close window
-(IBAction)closeWindow:(id)sender
{
//close
[self.window close];
return;
}
@end
+44
View File
@@ -0,0 +1,44 @@
//
// Queue.h
// BlockBlock
//
// Created by Patrick Wardle on 9/26/14.
// Copyright (c) 2014 Synack. All rights reserved.
//
//from: https://github.com/esromneb/ios-queue-object/blob/master/NSMutableArray%2BQueueAdditions.h
#import <Foundation/Foundation.h>
#import "NSMutableArray+QueueAdditions.h"
@interface Queue : NSObject
{
//the queue
NSMutableArray* eventQueue;
//queue processor thread
NSThread* qProcessorThread;
//condition for queue's status
NSCondition* queueCondition;
}
//event queue
@property(retain, atomic)NSMutableArray* eventQueue;
@property (nonatomic, retain)NSThread* qProcessorThread;
@property (nonatomic, retain)NSCondition* queueCondition;
//METHODS
//add an object to the queue
-(void)enqueue:(id)anObject;
@end
+117
View File
@@ -0,0 +1,117 @@
//
// Queue.m
// BlockBlock
//
// Created by Patrick Wardle on 9/26/14.
// Copyright (c) 2014 Synack. All rights reserved.
//
#import "Queue.h"
#import "Consts.h"
#import "Binary.h"
#import "AppDelegate.h"
@implementation Queue
@synthesize eventQueue;
@synthesize queueCondition;
@synthesize qProcessorThread;
-(id)init
{
//init super
self = [super init];
if(nil != self)
{
//init queue
eventQueue = [NSMutableArray array];
//init empty condition
queueCondition = [[NSCondition alloc] init];
//spin up thread to watch/process queue
self.qProcessorThread = [[NSThread alloc] initWithTarget:self selector:@selector(processQueue:) object:nil];
//start it
[self.qProcessorThread start];
}
return self;
}
//process events from Q
-(void)processQueue:(id)threadParam
{
//Binary obj
Binary* binary = nil;
//nap for a bit
// ->don't want UI thread, etc to suffer
[NSThread sleepForTimeInterval:5.0f];
//for ever
while(YES)
{
//pool
@autoreleasepool {
//lock
[self.queueCondition lock];
//wait while queue is empty
while(YES == [self.eventQueue empty])
{
//wait
[self.queueCondition wait];
}
//get item off queue
binary = [eventQueue dequeue];
//process binary
// ->hash, etc
if(YES == [binary isKindOfClass:[Binary class]])
{
//process
//->for now, just hash, etc
[binary generateDetailedInfo];
}
//unlock
[self.queueCondition unlock];
//pool
}
}//foreverz process queue
return;
}
//add an object to the queue
-(void)enqueue:(id)anObject
{
//lock
[self.queueCondition lock];
//add to queue
[self.eventQueue enqueue:anObject];
//signal
[self.queueCondition signal];
//unlock
[self.queueCondition unlock];
return;
}
//process binary
-(void)processBinary:(Binary*)binary
{
}
@end
+34
View File
@@ -0,0 +1,34 @@
//
// PrefsWindowController.h
// DHS
//
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface RequestRootWindowController : NSWindowController <NSWindowDelegate>
{
}
/* PROPERTIES */
//status msg
@property (weak) IBOutlet NSTextField *statusMsg;
//flag indicating app should exit
@property BOOL shouldExit;
/* METHODS */
//invoked when user clicks 'auth' button
// ->auths user!
-(IBAction)authenticate:(id)sender;
//invoked when user clicks 'cancel' button
// ->exits app
-(IBAction)close:(id)sender;
@end
+226
View File
@@ -0,0 +1,226 @@
//
// PrefsWindowController.m
// KnockKnock
//
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
//
#import "Utilities.h"
#import "AppDelegate.h"
#import "RequestRootWindowController.h"
@implementation RequestRootWindowController
@synthesize statusMsg;
@synthesize shouldExit;
//TODO: add 'why' / info button :)
//automatically called when nib is loaded
// ->center window
-(void)awakeFromNib
{
//center
[self.window center];
return;
}
//automatically invoked when window is loaded
// ->set to white
-(void)windowDidLoad
{
//super
[super windowDidLoad];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//set version sting
//[self.versionLabel setStringValue:[NSString stringWithFormat:@"version: %@", getAppVersion()]];
return;
}
//automatically invoked when window is closing
// ->make ourselves unmodal and possibly exit app
-(void)windowWillClose:(NSNotification *)notification
{
//save prefs
//[self savePrefs];
//make un-modal
[[NSApplication sharedApplication] stopModal];
//on errors, cancels
// ->exit app
if(YES == self.shouldExit)
{
//exit
[NSApp terminate:self];
}
return;
}
//invoked when user clicks 'auth' button
// ->auth user, then set XPC service as root/setuid
-(IBAction)authenticate:(id)sender
{
//status var
BOOL authdOK = NO;
//authorization ref
AuthorizationRef authorizationRef = {0};
//args
const char* installArgs[0x10] = {0};
//status code
OSStatus osStatus = -1;
//path to XPC service
NSString* xpcService = nil;
//get path to XPC service
xpcService = getPath2XPC();
if(nil == xpcService)
{
//bail
goto bail;
}
/* first chown as root */
//1st arg: recursive flag
installArgs[0] = "-R";
//2nd arg: group/owner
installArgs[1] = "root:wheel";
//3rd arg: XPC service
installArgs[2] = [xpcService UTF8String];
//end w/ NULL
installArgs[3] = NULL;
//create authorization ref
osStatus = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
if(errAuthorizationSuccess != osStatus)
{
//err msg
NSLog(@"ERROR: AuthorizationCreate() failed with %d", osStatus);
//set exit flag
self.shouldExit = YES;
//bail
goto bail;
}
//chown XPC service as r00t
osStatus = AuthorizationExecuteWithPrivileges(authorizationRef, "/usr/sbin/chown", 0, (char* const*)installArgs, NULL);
if(errAuthorizationSuccess != osStatus)
{
//err msg
NSLog(@"ERROR: AuthorizationExecuteWithPrivileges() failed with %d", osStatus);
//set result msg
[self.statusMsg setStringValue: [NSString stringWithFormat:@"error: failed with %d", osStatus]];
//set font to red
self.statusMsg.textColor = [NSColor redColor];
//set exit flag
self.shouldExit = YES;
//bail
goto bail;
}
/* then setuid */
//1st arg: recursive flag
installArgs[0] = "-R";
//2nd arg: permissions
// ->4 at front is setuid
//TODO: make 4755
installArgs[1] = "4777";
//3rd arg: XPC service
installArgs[2] = [xpcService UTF8String];
//end w/ NULL
installArgs[3] = NULL;
//chmod XPC service w/ setuid
osStatus = AuthorizationExecuteWithPrivileges(authorizationRef, "/bin/chmod", 0, (char* const*)installArgs, NULL);
//check
if(errAuthorizationSuccess != osStatus)
{
//err msg
NSLog(@"ERROR: AuthorizationExecuteWithPrivileges() failed with %d", osStatus);
//set result msg
[self.statusMsg setStringValue: [NSString stringWithFormat:@"error: failed with %d", osStatus]];
//set font to red
self.statusMsg.textColor = [NSColor redColor];
//set exit flag
self.shouldExit = YES;
//bail
goto bail;
}
//no errors
authdOK = YES;
//no exit
self.shouldExit = NO;
//start enumerating tasks
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) exploreTasks];
//bail
bail:
//free auth ref
if(0 != authorizationRef)
{
//free
AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
}
//on auth/'install' success
// ->close window
if(YES == authdOK)
{
//close window
[self.window close];
}
return;
}
//invoked when user clicks 'cancel' button
// ->set exit flag and close window
-(IBAction)close:(id)sender
{
//set flag to exit
self.shouldExit = YES;
//exit
[self.window close];
}
@end
+31
View File
@@ -0,0 +1,31 @@
//
// PrefsWindowController.h
// DHS
//
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface ResultsWindowController : NSWindowController <NSWindowDelegate>
{
}
/* PROPERTIES */
//details
@property(nonatomic, retain)NSString* details;
//details of results label/string
@property(weak) IBOutlet NSTextField *detailsLabel;
/* METHODS */
//invoked when user clicks 'more info' button
// ->open KK's webpage
- (IBAction)close:(id)sender;
@end
+65
View File
@@ -0,0 +1,65 @@
//
// PrefsWindowController.m
// KnockKnock
//
// Created by Patrick Wardle on 2/6/15.
// Copyright (c) 2015 Objective-See, LLC. All rights reserved.
//
#import "Utilities.h"
#import "AppDelegate.h"
#import "ResultsWindowController.h"
@implementation ResultsWindowController
@synthesize details;
@synthesize detailsLabel;
//automatically called when nib is loaded
// ->center window
-(void)awakeFromNib
{
//center
[self.window center];
}
//automatically invoked when window is loaded
// ->set to white
-(void)windowDidLoad
{
//super
[super windowDidLoad];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//set details
self.detailsLabel.stringValue = self.details;
return;
}
//automatically invoked when user clicks 'OK'
// ->close window
-(IBAction)close:(id)sender
{
//close
[[self window] close];
return;
}
//automatically invoked when window is closing
// ->make ourselves unmodal
-(void)windowWillClose:(NSNotification *)notification
{
//make un-modal
[[NSApplication sharedApplication] stopModal];
return;
}
@end
+112
View File
@@ -0,0 +1,112 @@
//
// Task.h
// TaskExplorer
//
// Created by Patrick Wardle on 5/2/15.
// Copyright (c) 2015 Lucas Derraugh. All rights reserved.
//
#import "Binary.h"
#import <Foundation/Foundation.h>
/*
//32bit
struct dyld_image_info_32 {
int imageLoadAddress;
int imageFilePath;
int imageFileModDate;
};
*/
@interface Task : NSObject
{
//pid
NSNumber* pid;
//uid
uid_t uid;
//main binary
Binary* binary;
//app bundle
// ->only for apps of course...
//NSBundle* bundle;
//process's full path
// ->e.g. /Applications/Calculator.app/Contents/MacOS/Calculator
//NSString* path;
//process's name
// ->e.g Calculator
//NSString* name;
//icon
//NSImage* icon;
//parent id
NSNumber* ppid;
//children (for tree view)
NSMutableArray* children;
}
@property (nonatomic, retain)NSNumber* pid;
//main binary
@property(nonatomic, retain)Binary* binary;
//process args
@property(nonatomic, retain)NSMutableArray* arguments;
//loaded dylibs
@property(nonatomic, retain)NSMutableArray* dylibs;
//open files
@property(nonatomic, retain)NSMutableArray* files;
//connections
@property(nonatomic, retain)NSMutableArray* connections;
@property uid_t uid;
@property (nonatomic, retain)NSNumber* ppid;
//signing info
@property(nonatomic, retain)NSDictionary* signingInfo;
//children
@property (nonatomic, retain)NSMutableArray* children;
/* METHODS */
//init w/ a pid + path
// note: icons are dynamically determined only when process is shown in alert
-(id)initWithPID:(NSNumber*)taskPID andPath:(NSString*)taskPath;
//get command-line args
-(void)getArguments;
-(void)generateBinaryInfo;
//enumerate all dylibs
// ->new ones are added to 'existingDylibs' (global) dictionary
-(void)enumerateDylibs:(NSXPCConnection*)xpcConnection allDylibs:(NSMutableDictionary*)allDylibs;
//enumerate all open files
-(void)enumerateFiles:(NSXPCConnection*)xpcConnection;
//enumerate network sockets/connections
-(void)enumerateNetworking:(NSXPCConnection*)xpcConnection;
//get UID for process (by pid)
//-(void)determineUID;
@end
+536
View File
@@ -0,0 +1,536 @@
//
// Task.m
// TaskExplorer
//
// Created by Patrick Wardle on 5/2/15.
// Copyright (c) 2015 Lucas Derraugh. All rights reserved.
//
#import "Task.h"
#import "Consts.h"
#import "Utilities.h"
#import "File.h"
#import "Connection.h"
#import "remoteTaskService.h"
#import "AppDelegate.h"
#import <mach-o/dyld_images.h>
#import <mach/mach_init.h>
#import <mach/mach_vm.h>
#import <sys/types.h>
#import <mach/mach.h>
#import <sys/ptrace.h>
#import <sys/wait.h>
#import <sys/sysctl.h>
#import <sys/proc_info.h>
#import <libproc.h>
#import <arpa/inet.h>
#import <netinet/tcp_fsm.h>
@implementation Task
@synthesize pid;
@synthesize uid;
//@synthesize icon;
//@synthesize name;
//@synthesize path;
@synthesize ppid;
@synthesize files;
@synthesize binary;
//@synthesize bundle;
@synthesize dylibs;
@synthesize children;
@synthesize arguments;
@synthesize connections;
//init w/ a pid + path
// note: time consuming init's are done in '' method
-(id)initWithPID:(NSNumber*)taskPID andPath:(NSString*)taskPath
{
//existing binaries
NSMutableDictionary* existingBinaries = nil;
//existing binary
// ->can re-use for tasks w/ same binary
Binary* existingBinary = nil;
//init super
self = [super init];
if(nil != self)
{
//grab existings binaries
existingBinaries = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.executables;
//since root UID is zero
// ->init UID to -1
//self.uid = -1;
//save pid
self.pid = taskPID;
//alloc array for children
children = [NSMutableArray array];
//alloc array for dylibs
dylibs = [NSMutableArray array];
//alloc array for open files
files = [NSMutableArray array];
//alloc array for network connections
connections = [NSMutableArray array];
//get parent id
self.ppid = [NSNumber numberWithInteger:getParentID([taskPID intValue])];
//try extract existing binary
// ->will succeed for multiple instances of the same task (process)
existingBinary = existingBinaries[taskPath];
//re-use existing binaries
if(nil != existingBinary)
{
//re-use
self.binary = existingBinary;
}
//generate new binary
else
{
//generate binary obj
// ->time-consuming tasks are preformed in background block
self.binary = [[Binary alloc] initWithParams:@{KEY_RESULT_PATH:taskPath}];
//skip those that error out
if(nil == self.binary)
{
//bail
goto bail;
}
//add to queue
// ->this will processing
[((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.binaryQueue enqueue:self.binary];
//add it to 'global' list
existingBinaries[taskPath] = self.binary;
}
//indicate that binary is a task (main) executable
//self.binary.isTaskBinary = YES;
}//init self
//bail
bail:
return self;
}
//
-(void)generateBinaryInfo
{
//create main binary
//self.binary = [[Binary alloc] initWithParams:@{KEY_RESULT_PATH:self.path}];
return;
}
//get command-line args
-(void)getArguments
{
//'management info base' array
int mib[3] = {0};
//system's size for max args
int systemMaxArgs = 0;
//process's args
char* processArgs = NULL;
//# of args
int numberOfArgs = 0;
//start of (each) arg
char* argStart = NULL;
//size of buffers, etc
size_t size = 0;
//parser pointer
char *parser;
//init mib
// ->want system's size for max args
mib[0] = CTL_KERN;
mib[1] = KERN_ARGMAX;
//first time
// ->alloc array for args
if(nil == self.arguments)
{
//alloc
arguments = [NSMutableArray array];
}
//set size
size = sizeof(systemMaxArgs);
//get system's size for max args
if(-1 == sysctl(mib, 2, &systemMaxArgs, &size, NULL, 0))
{
//bail
goto bail;
}
//alloc space for args
processArgs = malloc(systemMaxArgs);
if(NULL == processArgs)
{
//bail
goto bail;
}
//init mib
// ->want process args
mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS2;
mib[2] = [self.pid intValue];
//set size
size = (size_t)systemMaxArgs;
//get process's args
if(-1 == sysctl(mib, 3, processArgs, &size, NULL, 0))
{
//bail
goto bail;
}
//extract number of args
// ->at start of buffer
memcpy(&numberOfArgs, processArgs, sizeof(numberOfArgs));
//skip procs w/ no args
// ->note: don't care about arg[0]
if(numberOfArgs < 2)
{
//no args
goto bail;
}
//init point to start of args
// ->they start right after # of args
parser = processArgs + sizeof(numberOfArgs);
//skip over exe name
// ->always at front, yes, even before arg[0] (which is also exe name)
while(parser < &processArgs[size])
{
//scan till NULL-terminator
if(0x0 == *parser)
{
//end of exe name
break;
}
//next char
parser++;
}
//sanity check
// ->make sure end-of-buffer wasn't reached
if(parser == &processArgs[size])
{
//bail
goto bail;
}
//skip all trailing NULLs
// ->scan will non-NULL is found
while(parser < &processArgs[size])
{
//scan till NULL-terminator
if(0x0 != *parser)
{
//ok, got to argv[0]
break;
}
//next char
parser++;
}
//sanity check
// ->(again), make sure end-of-buffer wasn't reached
if(parser == &processArgs[size])
{
//bail
goto bail;
}
//keep scanning until all args are found
// ->each is NULL-terminated
while(parser < &processArgs[size])
{
//bail if we've hit arg cnt
// ->note: don't save arg[0], so add 1
if(self.arguments.count + 1 == numberOfArgs)
{
//bail
break;
}
//each arg is NULL-terminated
if(*parser == '\0')
{
//save arg
// ->'argStart' is purposely NULL for argv[0]
if(NULL != argStart)
{
[self.arguments addObject:[NSString stringWithUTF8String:argStart]];
}
//init string pointer to (possibly) next arg
argStart = ++parser;
}
//next char
parser++;
}
//bail
bail:
//free process args
if(NULL != processArgs)
{
//free
free(processArgs);
}
return;
}
//enumerate all dylibs
// ->new ones are added to 'existingDylibs' (global) dictionary
-(void)enumerateDylibs:(NSXPCConnection*)xpcConnection allDylibs:(NSMutableDictionary*)allDylibs
{
//dylib instance (as Binary) obj
__block Binary* dylib = nil;
//new dylibs
// ->ones that should be hashed/processed
__block NSMutableArray* newDylibs = nil;
//alloc array for new dylibs
newDylibs = [NSMutableArray array];
//invoke XPC service (running as r00t)
// ->will enumerate dylibs, then invoke reply block to save into iVar
[[xpcConnection remoteObjectProxy] enumerateDylibs:self.pid withReply:^(NSMutableArray* dylibPaths) {
//add all dylibs
for(NSString* dylibPath in dylibPaths)
{
//skip main image
if(YES == [dylibPath isEqualToString:self.binary.path])
{
//skip
continue;
}
//skip 'cl_kernels'
// ->not an on-disk/'real' dylib
if(YES == [dylibPath isEqualToString:@"cl_kernels"])
{
//skip
continue;
}
//first try grab from 'global' list of all dylibs
// ->will be non-nil if its already been processed
dylib = allDylibs[dylibPath];
//first time seen?
// ->create Binary obj & save into 'global' list
if(nil == dylib)
{
//create Binary obj
dylib = [[Binary alloc] initWithParams:@{KEY_RESULT_PATH:dylibPath}];
//skip any that error out
if(nil == dylib)
{
//skip
continue;
}
//add to queue
// ->this will processing
[((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.binaryQueue enqueue:dylib];
//add to list of new dylibs
// ->will allow for post processing
[newDylibs addObject:dylib];
//sync
// ->add to global list
@synchronized(allDylibs)
{
//add
allDylibs[dylib.path] = dylib;
}
}
//sync
@synchronized(self.dylibs)
{
//add to task's dylibs
[self.dylibs addObject:dylib];
}
}
//reload bottom pane now
// ->this will only reload if new task is the currently selected one, etc
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:DYLIBS_VIEW];
//complete dylib processing
// ->get signing info, hash, etc, & save into global list
for(Binary* newDylib in newDylibs)
{
//generate signing info
[newDylib generatedSigningInfo];
}
//any new dylibs?
// ->reload bottom pane
if(0 != newDylibs.count)
{
//reload
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:DYLIBS_VIEW];
}
}];
return;
}
//enumerate all file descriptors
-(void)enumerateFiles:(NSXPCConnection*)xpcConnection
{
//File object
__block File* file = nil;
//new files
NSMutableArray* newFiles = nil;
//file path
__block NSString* filePath = nil;
//alloc array for new files
newFiles = [NSMutableArray array];
//invoke XPC service (running as r00t)
// ->will enumerate files, then invoke reply block so can save into iVar
[[xpcConnection remoteObjectProxy] enumerateFiles:self.pid withReply:^(NSMutableArray* fileDescriptors) {
//create/add all files
for(NSMutableDictionary* fileDescriptor in fileDescriptors)
{
//extract file path
filePath = fileDescriptor[KEY_FILE_PATH];
//alloc/init File obj
file = [[File alloc] initWithParams:@{KEY_RESULT_PATH:filePath}];
//skip nil files
//TODO: look into what files err out!!
if(nil == file)
{
//next
continue;
}
//add to task's files
[self.files addObject:file];
//save new files
// ->will be processed below
if(nil == [((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.files objectForKey:filePath])
{
//save as new
[newFiles addObject:file];
}
}
//reload bottom pane
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:FILES_VIEW];
//process all new files
// ->calculate hash, etc & save into global list
for(File* newFile in newFiles)
{
//generate detailed info
[newFile generateDetailedInfo];
//TODO: sync!
//save into global list
[((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.files setObject:newFile forKey:filePath];
}
}];
return;
}
//enumerate network sockets/connections
-(void)enumerateNetworking:(NSXPCConnection*)xpcConnection
{
//File object
__block Connection* connection = nil;
//remove any existing enum'd networking sockets/connections
[self.connections removeAllObjects];
NSLog(@"invoking XPC to enumer networking");
//invoke XPC service (running as r00t)
// ->will enumerate network sockets/connections, then invoke reply block so can save into iVar
[[xpcConnection remoteObjectProxy] enumerateNetwork:self.pid withReply:^(NSMutableArray* networkItems) {
//
//NSLog(@"found %d connections", networkItems.count);
//create/add all network sockets/connection
for(NSMutableDictionary* networkItem in networkItems)
{
//alloc/init File obj
connection = [[Connection alloc] initWithParams:networkItem];
//add File obj
if(nil != connection)
{
//add
[self.connections addObject:connection];
}
}
////TODO: on main thead?
//reload bottom pane
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:NETWORKING_VIEW];
}];
return;
}
@end
+65
View File
@@ -0,0 +1,65 @@
//
// TaskEnumerator.h
//
//
// Created by Patrick Wardle on 5/2/15.
//
//
#import "Queue.h"
#import "3rdParty/OrderedDictionary.h"
#import <Foundation/Foundation.h>
@interface TaskEnumerator : NSObject
{
}
/* PROPERTIES */
//flag indicating first scan is complete
//@property BOOL firstScanComplete;
//all tasks objects
@property(nonatomic, retain)OrderedDictionary* tasks;
//all task binaries (main executables)
@property(nonatomic, retain)NSMutableDictionary* executables;
//all (opened) files
@property(nonatomic, retain)NSMutableDictionary* files;
//all dylibs
@property(nonatomic, retain)NSMutableDictionary* dylibs;
//remote XPC interface
//TODO: weak OK?
@property (nonatomic, retain) NSXPCConnection* xpcConnection;
//queue object
// ->contains watch items that should be processed
@property (nonatomic, retain) Queue* binaryQueue;
/* METHODS */
//enumerate all tasks
// ->call back into app delegate to update task (top) table
-(void)enumerateTasks;
//get list of all pids
-(OrderedDictionary*)getAllTasks;
//insert tasks into appropriate parent
// ->ensures order of parent's (by pid), is preserved
-(void)generateAncestries:(OrderedDictionary*)newTasks;
//determine if dylibs should be (re)enumerated
// ->generally yes, unless the first enumeration (of all tasks) is not complete
-(BOOL)shouldEnumDylibs;
@end
+411
View File
@@ -0,0 +1,411 @@
//
// TaskEnumerator.m
//
//
// Created by Patrick Wardle on 5/2/15.
//
//
#import <libproc.h>
#import <sys/proc_info.h>
#import "Task.h"
#import "Consts.h"
#import "AppDelegate.h"
#import "Utilities.h"
#import "TaskEnumerator.h"
#import "serviceInterface.h"
#include <signal.h>
#include <unistd.h>
@implementation TaskEnumerator
@synthesize files;
@synthesize tasks;
@synthesize dylibs;
@synthesize binaryQueue;
@synthesize executables;
@synthesize xpcConnection;
//@synthesize firstScanComplete;
//init
-(id)init
{
//init super
self = [super init];
if(nil != self)
{
//init tasks dictionary
tasks = [[OrderedDictionary alloc] init];
//alloc executables dictionary
executables = [NSMutableDictionary dictionary];
//alloc dylibs dictionary
dylibs = [NSMutableDictionary dictionary];
//alloc XPC connection
xpcConnection = [[NSXPCConnection alloc] initWithServiceName:@"com.objective-see.remoteTaskService"];
//set remote object interface
self.xpcConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(remoteTaskProto)];
//set classes
// ->arrays & strings are what is ok to vend
[self.xpcConnection.remoteObjectInterface
setClasses: [NSSet setWithObjects: [NSMutableArray class], [NSMutableDictionary class], [NSString class], nil]
forSelector: @selector(enumerateDylibs:withReply:)
argumentIndex: 0 // the first parameter
ofReply: YES // in the method itself.
];
//set classes
// ->arrays & strings are what is ok to vend
[self.xpcConnection.remoteObjectInterface
setClasses: [NSSet setWithObjects: [NSMutableArray class], [NSMutableDictionary class], [NSString class], nil]
forSelector: @selector(enumerateFiles:withReply:)
argumentIndex: 0 // the first parameter
ofReply: YES // in the method itself.
];
//set classes
// ->arrays & strings are what is ok to vend
[self.xpcConnection.remoteObjectInterface
setClasses: [NSSet setWithObjects: [NSMutableArray class], [NSMutableDictionary class], [NSString class], [NSNumber class], nil]
forSelector: @selector(enumerateNetwork:withReply:)
argumentIndex: 0 // the first parameter
ofReply: YES // in the method itself.
];
//resume
[self.xpcConnection resume];
//init binary processing queue
binaryQueue = [[Queue alloc] init];
}
return self;
}
//enumerate all tasks
// ->call back into app delegate to update task (top) table
// call every x # of seconds~
//TODO: re-enumerate dylibs for everytime!
// only need to update task.dylibs list (not global one, unless its new!)
-(void)enumerateTasks
{
//(new) task item
Task* newTask = nil;
//new tasks
OrderedDictionary* newTasks = nil;
//get all tasks
// ->pids and binary obj with just path/name
newTasks = [self getAllTasks];
//build ancestries
[self generateAncestries:newTasks];
//add all tasks that are really new to 'tasks' iVar
// ->ensures existing task and their info are reused
for(NSNumber* key in newTasks.allKeys)
{
//get task
newTask = newTasks[key];
//remove any non-new (i.e. existing) tasks
if(nil != self.tasks[newTask.pid])
{
//not new
// ->remove
[newTasks removeObjectForKey:key];
//next
continue;
}
//enumerate task's dylibs
//[newTask enumerateDylibs:self.xpcConnection allDylibs:self.dylibs];
//add new task
// TODO: ordering!?
[self.tasks setObject:newTask forKey:newTask.pid];
}
//reload table
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadTaskTable];
//now generate signing info
// ->for (new) tasks & their dylibs
for(NSNumber* key in newTasks)
{
//get task
newTask = newTasks[key];
//generate signing info
[newTask.binary generatedSigningInfo];
//reload task (row) in table
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadRow:newTask item:newTask.binary pane:PANE_TOP];
//reload bottom pane
// ->this will only reload if new task is the currently selected one, etc
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:newTask itemView:CURRENT_VIEW];
}//signing info for all tasks and dylibs
return;
}
/*
//determine if dylibs should be (re)enumerated
// ->generally yes, unless the first enumeration (of all tasks) is not complete
-(BOOL)shouldEnumDylibs
{
//flag
BOOL shouldEnum = NO;
//task key
NSNumber* taskKey = nil;
//Task
Task* task = nil;
for(NSInteger i = self.tasks.count-1; i>=0; i--)
{
taskKey = [self.tasks keyAtIndex:i];
task = self.tasks[taskKey];
//skip dead procs
if(YES != isAlive([task.pid unsignedIntValue]))
{
continue;
}
//alive
// ->does it have dylibs?
if(0 != task.dylibs.count)
{
//a end task has dylibs
// ->indicates all done?
shouldEnum = YES;
//bail
break;
}
else
{
shouldEnum = NO;
break;
}
}
return shouldEnum;
}
*/
/*
//TODO: only do this once!
// ->otherwise done JIT (on click)
//TODO: sync!!
//iterate over all tasks
// ->invoke task's emun method to get all files/network (via XPC)
-(void)enumerateFiles
{
//Task
Task* task = nil;
//iterate over all tasks
// ->invoke method to enumerate files
for(NSNumber* key in self.tasks)
{
//get task
task = self.tasks[key];
//enumerate files
[task enumerateFiles:self.xpcConnection];
}
}
*/
//get list of all pids
-(OrderedDictionary*)getAllTasks
{
//tasks
// ->pid/name
OrderedDictionary* allTasks = nil;
//task
Task* task = nil;
//alloc/init list
allTasks = [[OrderedDictionary alloc] init];
//# of procs
int numberOfProcesses = 0;
//array of pids
pid_t* pids = NULL;
//buffer for process path
char pathBuffer[PROC_PIDPATHINFO_MAXSIZE] = {0};
//status
int status = -1;
//process ID
NSNumber* processID = nil;
//process name
NSString* processName = nil;
//get # of procs
numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
//alloc buffer for pids
pids = calloc(numberOfProcesses, sizeof(pid_t));
//get list of pids
status = proc_listpids(PROC_ALL_PIDS, 0, pids, numberOfProcesses * sizeof(pid_t));
if(status < 0)
{
//err
NSLog(@"OBJECTIVE-SEE ERROR: proc_listpids() failed with %d", status);
//bail
goto bail;
}
//iterate over all pids
// ->get name for each
for(int i = 0; i < numberOfProcesses; ++i)
{
//skip blank pids
if(0 == pids[i])
{
//skip
continue;
}
//reset buffer
bzero(pathBuffer, PROC_PIDPATHINFO_MAXSIZE);
//init process ID
processID = [NSNumber numberWithInt:pids[i]];
//get path
status = proc_pidpath(pids[i], pathBuffer, sizeof(pathBuffer));
//sanity check
// ->this generally just fails if process has exited....
if( (status < 0) ||
(0 == strlen(pathBuffer)) )
{
//skip
continue;
}
//init process name
processName = [NSString stringWithUTF8String:pathBuffer];
//init task
// ->pass in pid and name
task = [[Task alloc] initWithPID:processID andPath:processName];
//add task to list
// ->order by pid for now
[allTasks setObject:task forKey:processID];
}
//always add kernel's task
// ->hardcoded pid (0) and path to kernel
task = [[Task alloc] initWithPID:@0 andPath:path2Kernel()];
//add kernel task
[allTasks setObject:task forKey:@0];
//reverse array
// ->want order to go from 0 -> ...
[allTasks reverse];
//bail
bail:
//free buffer
if(NULL != pids)
{
//free
free(pids);
}
//dbg msg
//NSLog(@"OBJECTIVE-SEE INFO: done scanning running processes");
return allTasks;
}
//insert tasks into appropriate parent
// ->ensures order of parent's (by pid), is preserved
//TODO: what about parentless procs!? (e.g. malware?)
-(void)generateAncestries:(OrderedDictionary*)newTasks
{
//task
Task* task = nil;
//parent
Task* parent = nil;
//comparator
NSComparator comparator = nil;
//index
// ->where task should be inserted into parent's child array
NSUInteger childIndex = 0;
//init comparator
comparator = ^(id obj1, id obj2) { return NSOrderedSame; };
//interate over all task
// ->insert task into parent's *ordered* child array
for(NSNumber* key in newTasks.allKeys)
{
//get task
task = newTasks[key];
//get parent
parent = newTasks[task.ppid];
//ignore tasks that are their own parent
// ->i.e. kernel_task
if(YES == [task.pid isEqualToNumber:task.ppid])
{
//skip
continue;
}
//get index where child should be inserted
childIndex = [parent.children indexOfObject:task.pid
inSortedRange:(NSRange){0, [parent.children count]}
options:NSBinarySearchingInsertionIndex usingComparator:comparator];
//insert child
[parent.children insertObject:task.pid atIndex:childIndex];
}
return;
}
@end
+34
View File
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>icon</string>
<key>CFBundleIdentifier</key>
<string>com.objective-see.$(PRODUCT_NAME:rfc1034identifier)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.2.3</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.2.3</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015 Objective-See, LLC. All rights reserved.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
+7
View File
@@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'KnockKnock' target in the 'KnockKnock' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif
+916
View File
@@ -0,0 +1,916 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1D21BC4F172AF43D009D1CFD /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D21BC4E172AF43D009D1CFD /* Cocoa.framework */; };
CD001B371AB903040089014A /* kkText.png in Resources */ = {isa = PBXBuildFile; fileRef = CD001B341AB903040089014A /* kkText.png */; };
CD001B381AB903040089014A /* logo.png in Resources */ = {isa = PBXBuildFile; fileRef = CD001B351AB903040089014A /* logo.png */; };
CD001B391AB903040089014A /* logoApple.png in Resources */ = {isa = PBXBuildFile; fileRef = CD001B361AB903040089014A /* logoApple.png */; };
CD02194F1AD34D8B005148A2 /* AboutWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD02194D1AD34D8B005148A2 /* AboutWindow.xib */; };
CD0219501AD34D8B005148A2 /* PrefsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD02194E1AD34D8B005148A2 /* PrefsWindow.xib */; };
CD0219531AD34D9A005148A2 /* AboutWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD0219521AD34D9A005148A2 /* AboutWindowController.m */; };
CD0219551AD34E4C005148A2 /* kkIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CD0219541AD34E4C005148A2 /* kkIcon.png */; };
CD0219581AD37748005148A2 /* signed2.png in Resources */ = {isa = PBXBuildFile; fileRef = CD0219561AD37748005148A2 /* signed2.png */; };
CD0219591AD37748005148A2 /* unsigned2.png in Resources */ = {isa = PBXBuildFile; fileRef = CD0219571AD37748005148A2 /* unsigned2.png */; };
CD02195C1AD38823005148A2 /* kkRowCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CD02195B1AD38823005148A2 /* kkRowCell.m */; };
CD02195E1AD39A74005148A2 /* ResultsWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD02195D1AD39A74005148A2 /* ResultsWindow.xib */; };
CD0219611AD39A83005148A2 /* ResultsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD0219601AD39A83005148A2 /* ResultsWindowController.m */; };
CD3F4CE81AF5CF68002A2647 /* TaskEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = CD3F4CE61AF5CF68002A2647 /* TaskEnumerator.m */; };
CD3F4CEB1AF6D948002A2647 /* OrderedDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = CD3F4CEA1AF6D948002A2647 /* OrderedDictionary.m */; };
CD3F4CFA1AF71B58002A2647 /* Binary.m in Sources */ = {isa = PBXBuildFile; fileRef = CD3F4CF31AF71B58002A2647 /* Binary.m */; };
CD3F4CFB1AF71B58002A2647 /* Connection.m in Sources */ = {isa = PBXBuildFile; fileRef = CD3F4CF51AF71B58002A2647 /* Connection.m */; };
CD3F4CFC1AF71B58002A2647 /* File.m in Sources */ = {isa = PBXBuildFile; fileRef = CD3F4CF71AF71B58002A2647 /* File.m */; };
CD3F4CFD1AF71B58002A2647 /* ItemBase.m in Sources */ = {isa = PBXBuildFile; fileRef = CD3F4CF91AF71B58002A2647 /* ItemBase.m */; };
CD3F4CFF1AF72BC4002A2647 /* TaskInfoWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD3F4CFE1AF72BC4002A2647 /* TaskInfoWindow.xib */; };
CD3F4D141AF85088002A2647 /* FlatView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD3F4D131AF85088002A2647 /* FlatView.xib */; };
CD3F4D161AF89066002A2647 /* TreeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD3F4D151AF89066002A2647 /* TreeView.xib */; };
CD3F4D1C1AFADD36002A2647 /* TreeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD3F4D1B1AFADD36002A2647 /* TreeViewController.m */; };
CD4D53CA1B20296E00008030 /* unknown.png in Resources */ = {isa = PBXBuildFile; fileRef = CD4D53C91B20296E00008030 /* unknown.png */; };
CD4D53D01B23ED3900008030 /* connectedIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CD4D53CF1B23ED3900008030 /* connectedIcon.png */; };
CD4D53D21B23ED4300008030 /* listeningIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CD4D53D11B23ED4300008030 /* listeningIcon.png */; };
CD4D541F1B2CE6C400008030 /* Queue.m in Sources */ = {isa = PBXBuildFile; fileRef = CD4D541E1B2CE6C400008030 /* Queue.m */; };
CD4D54221B2CE6F200008030 /* NSMutableArray+QueueAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CD4D54211B2CE6F200008030 /* NSMutableArray+QueueAdditions.m */; };
CD4D54241B2D082300008030 /* DylibInfoWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CD4D54231B2D082300008030 /* DylibInfoWindow.xib */; };
CD6095731A87067D00E091CD /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD6095721A87067D00E091CD /* Security.framework */; };
CD6E54FF1B1162B5007953AB /* ItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = CD6E54FE1B1162B5007953AB /* ItemView.m */; };
CD7B9F4D1ACB959200DF3C71 /* logoAppleOver.png in Resources */ = {isa = PBXBuildFile; fileRef = CD7B9F4C1ACB959200DF3C71 /* logoAppleOver.png */; };
CD7B9F501ACB9A8400DF3C71 /* Exception.m in Sources */ = {isa = PBXBuildFile; fileRef = CD7B9F4F1ACB9A8400DF3C71 /* Exception.m */; };
CD7B9FA41ACBCFAD00DF3C71 /* spotlightIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CD7B9FA31ACBCFAD00DF3C71 /* spotlightIcon.png */; };
CD7B9FA71ACCAE5E00DF3C71 /* startScanOver.png in Resources */ = {isa = PBXBuildFile; fileRef = CD7B9FA51ACCAE5E00DF3C71 /* startScanOver.png */; };
CD7B9FA81ACCAE5E00DF3C71 /* stopScanOver.png in Resources */ = {isa = PBXBuildFile; fileRef = CD7B9FA61ACCAE5E00DF3C71 /* stopScanOver.png */; };
CD7B9FAB1AD08FA100DF3C71 /* KKRow.m in Sources */ = {isa = PBXBuildFile; fileRef = CD7B9FAA1AD08FA100DF3C71 /* KKRow.m */; };
CD83887F1AACCEDF000EB098 /* VirusTotal.m in Sources */ = {isa = PBXBuildFile; fileRef = CD83887E1AACCEDF000EB098 /* VirusTotal.m */; };
CDA5F6B41B16D805003CE340 /* remoteTaskService.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA5F6B31B16D805003CE340 /* remoteTaskService.m */; };
CDA5F6B61B16D805003CE340 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA5F6B51B16D805003CE340 /* main.m */; };
CDA5F6BA1B16D805003CE340 /* remoteTaskService.xpc in Embed XPC Services */ = {isa = PBXBuildFile; fileRef = CDA5F6AD1B16D805003CE340 /* remoteTaskService.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
CDA5F6C11B16E1D6003CE340 /* RequestRootWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CDA5F6C01B16E1D6003CE340 /* RequestRootWindow.xib */; };
CDA5F6C41B16E20E003CE340 /* RequestRootWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA5F6C31B16E20E003CE340 /* RequestRootWindowController.m */; };
CDA5F6C61B16E8D4003CE340 /* lockIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA5F6C51B16E8D4003CE340 /* lockIcon.png */; };
CDA81D4F1A95B492009790E2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA81D451A95B492009790E2 /* AppDelegate.m */; };
CDA81D531A95B492009790E2 /* Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA81D4E1A95B492009790E2 /* Utilities.m */; };
CDA81D5B1A95B4B4009790E2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D541A95B4B4009790E2 /* InfoPlist.strings */; };
CDA81D5C1A95B4B4009790E2 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D561A95B4B4009790E2 /* MainMenu.xib */; };
CDA81D5E1A95B4B4009790E2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA81D5A1A95B4B4009790E2 /* main.m */; };
CDA81D691A95B4E9009790E2 /* bug.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D5F1A95B4E9009790E2 /* bug.png */; };
CDA81D6A1A95B4E9009790E2 /* mainIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D601A95B4E9009790E2 /* mainIcon.png */; };
CDA81D6B1A95B4E9009790E2 /* show.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D611A95B4E9009790E2 /* show.png */; };
CDA81D6C1A95B4E9009790E2 /* showBG.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D621A95B4E9009790E2 /* showBG.png */; };
CDA81D6D1A95B4E9009790E2 /* scanIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D631A95B4E9009790E2 /* scanIcon.png */; };
CDA81D6E1A95B4E9009790E2 /* startScan.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D641A95B4E9009790E2 /* startScan.png */; };
CDA81D6F1A95B4E9009790E2 /* startScanBG.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D651A95B4E9009790E2 /* startScanBG.png */; };
CDA81D701A95B4E9009790E2 /* stopScan.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D661A95B4E9009790E2 /* stopScan.png */; };
CDA81D711A95B4E9009790E2 /* stopScanBG.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D671A95B4E9009790E2 /* stopScanBG.png */; };
CDA81D721A95B4E9009790E2 /* virus.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D681A95B4E9009790E2 /* virus.png */; };
CDA81D741A95B4FB009790E2 /* icon.iconset in Resources */ = {isa = PBXBuildFile; fileRef = CDA81D731A95B4FB009790E2 /* icon.iconset */; };
CDA81D7B1A95D29B009790E2 /* TaskTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA81D7A1A95D29B009790E2 /* TaskTableController.m */; };
CDA81DC91A9960A3009790E2 /* info.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81DC51A9960A3009790E2 /* info.png */; };
CDA81DCA1A9960A3009790E2 /* infoBG.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81DC61A9960A3009790E2 /* infoBG.png */; };
CDA81DCB1A9960A3009790E2 /* virusTotal.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81DC71A9960A3009790E2 /* virusTotal.png */; };
CDA81DCC1A9960A3009790E2 /* virusTotalBG.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81DC81A9960A3009790E2 /* virusTotalBG.png */; };
CDA81DD31A9970A0009790E2 /* signed.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81DD11A9970A0009790E2 /* signed.png */; };
CDA81DD41A9970A0009790E2 /* unsigned.png in Resources */ = {isa = PBXBuildFile; fileRef = CDA81DD21A9970A0009790E2 /* unsigned.png */; };
CDA81DEA1A997BF1009790E2 /* InfoWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA81DE81A997BF1009790E2 /* InfoWindowController.m */; };
CDA81DEE1A99B5F8009790E2 /* Filter.m in Sources */ = {isa = PBXBuildFile; fileRef = CDA81DED1A99B5F8009790E2 /* Filter.m */; };
CDA81E661AA020FD009790E2 /* FileInfoWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CDA81E641AA020FD009790E2 /* FileInfoWindow.xib */; };
CDAB98A11AEAFAFA00C75B4B /* authorizationIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAB98A01AEAFAFA00C75B4B /* authorizationIcon.png */; };
CDAB98A31AEB413C00C75B4B /* dylibIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDAB98A21AEB413C00C75B4B /* dylibIcon.png */; };
CDD248341AF5947300232422 /* TAAdaptiveSpaceItem.m in Sources */ = {isa = PBXBuildFile; fileRef = CDD248311AF5947300232422 /* TAAdaptiveSpaceItem.m */; };
CDD248351AF5947300232422 /* TAAdaptiveSpaceItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = CDD248331AF5947300232422 /* TAAdaptiveSpaceItemView.m */; };
CDD2483B1AF5CC4D00232422 /* Task.m in Sources */ = {isa = PBXBuildFile; fileRef = CDD2483A1AF5CC4D00232422 /* Task.m */; };
CDF08CBF1AC3DE25009B3423 /* logoAppleBG.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CBE1AC3DE25009B3423 /* logoAppleBG.png */; };
CDF08CC11AC3E8B0009B3423 /* showOver.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CC01AC3E8B0009B3423 /* showOver.png */; };
CDF08CC31AC3E98D009B3423 /* infoOver.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CC21AC3E98D009B3423 /* infoOver.png */; };
CDF08CC61AC46E75009B3423 /* VTButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CDF08CC51AC46E75009B3423 /* VTButton.m */; };
CDF08CCA1AC4C678009B3423 /* PrefsWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CDF08CC81AC4C678009B3423 /* PrefsWindowController.m */; };
CDF08CCF1AC4C6E8009B3423 /* settingsOver.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CCC1AC4C6E8009B3423 /* settingsOver.png */; };
CDF08CD01AC4C6E8009B3423 /* settingsBG.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CCD1AC4C6E8009B3423 /* settingsBG.png */; };
CDF08CD11AC4C6E8009B3423 /* settings.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CCE1AC4C6E8009B3423 /* settings.png */; };
CDF08CDF1AC886F2009B3423 /* VTInfoWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = CDF08CDD1AC886F2009B3423 /* VTInfoWindowController.m */; };
CDF08CE21AC88E0F009B3423 /* VTInfoWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CE11AC88E0F009B3423 /* VTInfoWindow.xib */; };
CDF08CE61AC89FE1009B3423 /* HyperlinkTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = CDF08CE51AC89FE1009B3423 /* HyperlinkTextField.m */; };
CDF08CE81AC8A35C009B3423 /* vtLogo.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CE71AC8A35C009B3423 /* vtLogo.png */; };
CDF08CEA1AC8D97B009B3423 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CDF08CE91AC8D97B009B3423 /* Quartz.framework */; };
CDF08CEF1ACA677B009B3423 /* launchIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CED1ACA677B009B3423 /* launchIcon.png */; };
CDF08CF01ACA677B009B3423 /* kernelIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CEE1ACA677B009B3423 /* kernelIcon.png */; };
CDF08CF31ACA6864009B3423 /* browserIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CF11ACA6864009B3423 /* browserIcon.png */; };
CDF08CF41ACA6864009B3423 /* loginIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = CDF08CF21ACA6864009B3423 /* loginIcon.png */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
CDA5F6B71B16D805003CE340 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 1D21BC43172AF43D009D1CFD /* Project object */;
proxyType = 1;
remoteGlobalIDString = CDA5F6AC1B16D805003CE340;
remoteInfo = remoteTaskService;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
CDA5F6B91B16D805003CE340 /* Embed XPC Services */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices";
dstSubfolderSpec = 16;
files = (
CDA5F6BA1B16D805003CE340 /* remoteTaskService.xpc in Embed XPC Services */,
);
name = "Embed XPC Services";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1D21BC4B172AF43D009D1CFD /* TaskExplorer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TaskExplorer.app; sourceTree = BUILT_PRODUCTS_DIR; };
1D21BC4E172AF43D009D1CFD /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
1D21BC51172AF43D009D1CFD /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
1D21BC52172AF43D009D1CFD /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
1D21BC53172AF43D009D1CFD /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
CD001B341AB903040089014A /* kkText.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = kkText.png; path = images/kkText.png; sourceTree = SOURCE_ROOT; };
CD001B351AB903040089014A /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = logo.png; path = images/logo.png; sourceTree = SOURCE_ROOT; };
CD001B361AB903040089014A /* logoApple.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = logoApple.png; path = images/logoApple.png; sourceTree = SOURCE_ROOT; };
CD02194D1AD34D8B005148A2 /* AboutWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = AboutWindow.xib; path = UI/AboutWindow.xib; sourceTree = "<group>"; };
CD02194E1AD34D8B005148A2 /* PrefsWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = PrefsWindow.xib; path = UI/PrefsWindow.xib; sourceTree = "<group>"; };
CD0219511AD34D9A005148A2 /* AboutWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutWindowController.h; sourceTree = "<group>"; };
CD0219521AD34D9A005148A2 /* AboutWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutWindowController.m; sourceTree = "<group>"; };
CD0219541AD34E4C005148A2 /* kkIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = kkIcon.png; path = images/kkIcon.png; sourceTree = SOURCE_ROOT; };
CD0219561AD37748005148A2 /* signed2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = signed2.png; path = images/signed2.png; sourceTree = SOURCE_ROOT; };
CD0219571AD37748005148A2 /* unsigned2.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = unsigned2.png; path = images/unsigned2.png; sourceTree = SOURCE_ROOT; };
CD02195A1AD38823005148A2 /* kkRowCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kkRowCell.h; sourceTree = "<group>"; };
CD02195B1AD38823005148A2 /* kkRowCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = kkRowCell.m; sourceTree = "<group>"; };
CD02195D1AD39A74005148A2 /* ResultsWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = ResultsWindow.xib; path = UI/ResultsWindow.xib; sourceTree = "<group>"; };
CD02195F1AD39A83005148A2 /* ResultsWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultsWindowController.h; sourceTree = "<group>"; };
CD0219601AD39A83005148A2 /* ResultsWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResultsWindowController.m; sourceTree = "<group>"; };
CD3F4CE61AF5CF68002A2647 /* TaskEnumerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TaskEnumerator.m; sourceTree = SOURCE_ROOT; };
CD3F4CE71AF5CF68002A2647 /* TaskEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaskEnumerator.h; sourceTree = SOURCE_ROOT; };
CD3F4CE91AF6D948002A2647 /* OrderedDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OrderedDictionary.h; path = 3rdParty/OrderedDictionary.h; sourceTree = "<group>"; };
CD3F4CEA1AF6D948002A2647 /* OrderedDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OrderedDictionary.m; path = 3rdParty/OrderedDictionary.m; sourceTree = "<group>"; };
CD3F4CF21AF71B58002A2647 /* Binary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Binary.h; path = Items/Binary.h; sourceTree = "<group>"; };
CD3F4CF31AF71B58002A2647 /* Binary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Binary.m; path = Items/Binary.m; sourceTree = "<group>"; };
CD3F4CF41AF71B58002A2647 /* Connection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Connection.h; path = Items/Connection.h; sourceTree = "<group>"; };
CD3F4CF51AF71B58002A2647 /* Connection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Connection.m; path = Items/Connection.m; sourceTree = "<group>"; };
CD3F4CF61AF71B58002A2647 /* File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = File.h; path = Items/File.h; sourceTree = "<group>"; };
CD3F4CF71AF71B58002A2647 /* File.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = File.m; path = Items/File.m; sourceTree = "<group>"; };
CD3F4CF81AF71B58002A2647 /* ItemBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ItemBase.h; path = Items/ItemBase.h; sourceTree = "<group>"; };
CD3F4CF91AF71B58002A2647 /* ItemBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ItemBase.m; path = Items/ItemBase.m; sourceTree = "<group>"; };
CD3F4CFE1AF72BC4002A2647 /* TaskInfoWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TaskInfoWindow.xib; path = UI/TaskInfoWindow.xib; sourceTree = "<group>"; };
CD3F4D131AF85088002A2647 /* FlatView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = FlatView.xib; path = UI/FlatView.xib; sourceTree = "<group>"; };
CD3F4D151AF89066002A2647 /* TreeView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = TreeView.xib; path = UI/TreeView.xib; sourceTree = "<group>"; };
CD3F4D1A1AFADD36002A2647 /* TreeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TreeViewController.h; sourceTree = "<group>"; };
CD3F4D1B1AFADD36002A2647 /* TreeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TreeViewController.m; sourceTree = "<group>"; };
CD4D53C91B20296E00008030 /* unknown.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = unknown.png; path = images/unknown.png; sourceTree = SOURCE_ROOT; };
CD4D53CF1B23ED3900008030 /* connectedIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = connectedIcon.png; path = images/connectedIcon.png; sourceTree = SOURCE_ROOT; };
CD4D53D11B23ED4300008030 /* listeningIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = listeningIcon.png; path = images/listeningIcon.png; sourceTree = SOURCE_ROOT; };
CD4D541D1B2CE6C400008030 /* Queue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Queue.h; sourceTree = "<group>"; };
CD4D541E1B2CE6C400008030 /* Queue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Queue.m; sourceTree = "<group>"; };
CD4D54201B2CE6F200008030 /* NSMutableArray+QueueAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+QueueAdditions.h"; sourceTree = "<group>"; };
CD4D54211B2CE6F200008030 /* NSMutableArray+QueueAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+QueueAdditions.m"; sourceTree = "<group>"; };
CD4D54231B2D082300008030 /* DylibInfoWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = DylibInfoWindow.xib; path = UI/DylibInfoWindow.xib; sourceTree = "<group>"; };
CD6095721A87067D00E091CD /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
CD6E54FD1B1162B5007953AB /* ItemView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ItemView.h; sourceTree = "<group>"; };
CD6E54FE1B1162B5007953AB /* ItemView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ItemView.m; sourceTree = "<group>"; };
CD7B9F4C1ACB959200DF3C71 /* logoAppleOver.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = logoAppleOver.png; path = images/logoAppleOver.png; sourceTree = SOURCE_ROOT; };
CD7B9F4E1ACB9A8400DF3C71 /* Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Exception.h; sourceTree = SOURCE_ROOT; };
CD7B9F4F1ACB9A8400DF3C71 /* Exception.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Exception.m; sourceTree = SOURCE_ROOT; };
CD7B9FA31ACBCFAD00DF3C71 /* spotlightIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = spotlightIcon.png; path = images/spotlightIcon.png; sourceTree = SOURCE_ROOT; };
CD7B9FA51ACCAE5E00DF3C71 /* startScanOver.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = startScanOver.png; path = images/startScanOver.png; sourceTree = SOURCE_ROOT; };
CD7B9FA61ACCAE5E00DF3C71 /* stopScanOver.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = stopScanOver.png; path = images/stopScanOver.png; sourceTree = SOURCE_ROOT; };
CD7B9FA91AD08FA100DF3C71 /* KKRow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KKRow.h; sourceTree = "<group>"; };
CD7B9FAA1AD08FA100DF3C71 /* KKRow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KKRow.m; sourceTree = "<group>"; };
CD83887D1AACCEDF000EB098 /* VirusTotal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirusTotal.h; sourceTree = "<group>"; };
CD83887E1AACCEDF000EB098 /* VirusTotal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VirusTotal.m; sourceTree = "<group>"; };
CDA5F6AD1B16D805003CE340 /* remoteTaskService.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = remoteTaskService.xpc; sourceTree = BUILT_PRODUCTS_DIR; };
CDA5F6B01B16D805003CE340 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CDA5F6B21B16D805003CE340 /* remoteTaskService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = remoteTaskService.h; sourceTree = "<group>"; };
CDA5F6B31B16D805003CE340 /* remoteTaskService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = remoteTaskService.m; sourceTree = "<group>"; };
CDA5F6B51B16D805003CE340 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
CDA5F6BF1B16DBC9003CE340 /* serviceInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = serviceInterface.h; sourceTree = "<group>"; };
CDA5F6C01B16E1D6003CE340 /* RequestRootWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = RequestRootWindow.xib; path = UI/RequestRootWindow.xib; sourceTree = "<group>"; };
CDA5F6C21B16E20E003CE340 /* RequestRootWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RequestRootWindowController.h; sourceTree = "<group>"; };
CDA5F6C31B16E20E003CE340 /* RequestRootWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RequestRootWindowController.m; sourceTree = "<group>"; };
CDA5F6C51B16E8D4003CE340 /* lockIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = lockIcon.png; path = images/lockIcon.png; sourceTree = SOURCE_ROOT; };
CDA81D441A95B492009790E2 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
CDA81D451A95B492009790E2 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
CDA81D481A95B492009790E2 /* Consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Consts.h; sourceTree = SOURCE_ROOT; };
CDA81D4D1A95B492009790E2 /* Utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Utilities.h; sourceTree = SOURCE_ROOT; };
CDA81D4E1A95B492009790E2 /* Utilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Utilities.m; sourceTree = SOURCE_ROOT; };
CDA81D551A95B4B4009790E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; };
CDA81D571A95B4B4009790E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; };
CDA81D581A95B4B4009790E2 /* TaskExplorer-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "TaskExplorer-Info.plist"; sourceTree = SOURCE_ROOT; };
CDA81D591A95B4B4009790E2 /* TaskExplorer-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TaskExplorer-Prefix.pch"; sourceTree = SOURCE_ROOT; };
CDA81D5A1A95B4B4009790E2 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; };
CDA81D5F1A95B4E9009790E2 /* bug.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = bug.png; path = images/bug.png; sourceTree = SOURCE_ROOT; };
CDA81D601A95B4E9009790E2 /* mainIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = mainIcon.png; path = images/mainIcon.png; sourceTree = SOURCE_ROOT; };
CDA81D611A95B4E9009790E2 /* show.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = show.png; path = images/show.png; sourceTree = SOURCE_ROOT; };
CDA81D621A95B4E9009790E2 /* showBG.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = showBG.png; path = images/showBG.png; sourceTree = SOURCE_ROOT; };
CDA81D631A95B4E9009790E2 /* scanIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = scanIcon.png; path = images/scanIcon.png; sourceTree = SOURCE_ROOT; };
CDA81D641A95B4E9009790E2 /* startScan.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = startScan.png; path = images/startScan.png; sourceTree = SOURCE_ROOT; };
CDA81D651A95B4E9009790E2 /* startScanBG.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = startScanBG.png; path = images/startScanBG.png; sourceTree = SOURCE_ROOT; };
CDA81D661A95B4E9009790E2 /* stopScan.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = stopScan.png; path = images/stopScan.png; sourceTree = SOURCE_ROOT; };
CDA81D671A95B4E9009790E2 /* stopScanBG.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = stopScanBG.png; path = images/stopScanBG.png; sourceTree = SOURCE_ROOT; };
CDA81D681A95B4E9009790E2 /* virus.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = virus.png; path = images/virus.png; sourceTree = SOURCE_ROOT; };
CDA81D731A95B4FB009790E2 /* icon.iconset */ = {isa = PBXFileReference; lastKnownFileType = folder.iconset; name = icon.iconset; path = images/icon.iconset; sourceTree = SOURCE_ROOT; };
CDA81D791A95D29B009790E2 /* TaskTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaskTableController.h; sourceTree = "<group>"; };
CDA81D7A1A95D29B009790E2 /* TaskTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TaskTableController.m; sourceTree = "<group>"; };
CDA81DC51A9960A3009790E2 /* info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = info.png; path = images/info.png; sourceTree = SOURCE_ROOT; };
CDA81DC61A9960A3009790E2 /* infoBG.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = infoBG.png; path = images/infoBG.png; sourceTree = SOURCE_ROOT; };
CDA81DC71A9960A3009790E2 /* virusTotal.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = virusTotal.png; path = images/virusTotal.png; sourceTree = SOURCE_ROOT; };
CDA81DC81A9960A3009790E2 /* virusTotalBG.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = virusTotalBG.png; path = images/virusTotalBG.png; sourceTree = SOURCE_ROOT; };
CDA81DD11A9970A0009790E2 /* signed.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = signed.png; path = images/signed.png; sourceTree = SOURCE_ROOT; };
CDA81DD21A9970A0009790E2 /* unsigned.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = unsigned.png; path = images/unsigned.png; sourceTree = SOURCE_ROOT; };
CDA81DE71A997BF1009790E2 /* InfoWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoWindowController.h; sourceTree = "<group>"; };
CDA81DE81A997BF1009790E2 /* InfoWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InfoWindowController.m; sourceTree = "<group>"; };
CDA81DEC1A99B5F8009790E2 /* Filter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Filter.h; sourceTree = "<group>"; };
CDA81DED1A99B5F8009790E2 /* Filter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Filter.m; sourceTree = "<group>"; };
CDA81E641AA020FD009790E2 /* FileInfoWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = FileInfoWindow.xib; path = UI/FileInfoWindow.xib; sourceTree = "<group>"; };
CDAB98A01AEAFAFA00C75B4B /* authorizationIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = authorizationIcon.png; path = images/authorizationIcon.png; sourceTree = SOURCE_ROOT; };
CDAB98A21AEB413C00C75B4B /* dylibIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = dylibIcon.png; path = images/dylibIcon.png; sourceTree = SOURCE_ROOT; };
CDD248301AF5947300232422 /* TAAdaptiveSpaceItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TAAdaptiveSpaceItem.h; path = 3rdParty/TAAdaptiveSpaceItem.h; sourceTree = "<group>"; };
CDD248311AF5947300232422 /* TAAdaptiveSpaceItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TAAdaptiveSpaceItem.m; path = 3rdParty/TAAdaptiveSpaceItem.m; sourceTree = "<group>"; };
CDD248321AF5947300232422 /* TAAdaptiveSpaceItemView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TAAdaptiveSpaceItemView.h; path = 3rdParty/TAAdaptiveSpaceItemView.h; sourceTree = "<group>"; };
CDD248331AF5947300232422 /* TAAdaptiveSpaceItemView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TAAdaptiveSpaceItemView.m; path = 3rdParty/TAAdaptiveSpaceItemView.m; sourceTree = "<group>"; };
CDD248391AF5CC4D00232422 /* Task.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Task.h; sourceTree = SOURCE_ROOT; };
CDD2483A1AF5CC4D00232422 /* Task.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Task.m; sourceTree = SOURCE_ROOT; };
CDF08CBE1AC3DE25009B3423 /* logoAppleBG.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = logoAppleBG.png; path = images/logoAppleBG.png; sourceTree = SOURCE_ROOT; };
CDF08CC01AC3E8B0009B3423 /* showOver.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = showOver.png; path = images/showOver.png; sourceTree = SOURCE_ROOT; };
CDF08CC21AC3E98D009B3423 /* infoOver.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = infoOver.png; path = images/infoOver.png; sourceTree = SOURCE_ROOT; };
CDF08CC41AC46E75009B3423 /* VTButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VTButton.h; sourceTree = SOURCE_ROOT; };
CDF08CC51AC46E75009B3423 /* VTButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VTButton.m; sourceTree = SOURCE_ROOT; };
CDF08CC71AC4C678009B3423 /* PrefsWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefsWindowController.h; sourceTree = SOURCE_ROOT; };
CDF08CC81AC4C678009B3423 /* PrefsWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrefsWindowController.m; sourceTree = SOURCE_ROOT; };
CDF08CCC1AC4C6E8009B3423 /* settingsOver.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = settingsOver.png; path = images/settingsOver.png; sourceTree = SOURCE_ROOT; };
CDF08CCD1AC4C6E8009B3423 /* settingsBG.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = settingsBG.png; path = images/settingsBG.png; sourceTree = SOURCE_ROOT; };
CDF08CCE1AC4C6E8009B3423 /* settings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = settings.png; path = images/settings.png; sourceTree = SOURCE_ROOT; };
CDF08CDC1AC886F2009B3423 /* VTInfoWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VTInfoWindowController.h; sourceTree = "<group>"; };
CDF08CDD1AC886F2009B3423 /* VTInfoWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VTInfoWindowController.m; sourceTree = "<group>"; };
CDF08CE11AC88E0F009B3423 /* VTInfoWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = VTInfoWindow.xib; path = UI/VTInfoWindow.xib; sourceTree = "<group>"; };
CDF08CE41AC89FE1009B3423 /* HyperlinkTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HyperlinkTextField.h; path = 3rdParty/HyperlinkTextField.h; sourceTree = "<group>"; };
CDF08CE51AC89FE1009B3423 /* HyperlinkTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HyperlinkTextField.m; path = 3rdParty/HyperlinkTextField.m; sourceTree = "<group>"; };
CDF08CE71AC8A35C009B3423 /* vtLogo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = vtLogo.png; path = images/vtLogo.png; sourceTree = SOURCE_ROOT; };
CDF08CE91AC8D97B009B3423 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = System/Library/Frameworks/Quartz.framework; sourceTree = SDKROOT; };
CDF08CED1ACA677B009B3423 /* launchIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = launchIcon.png; path = images/launchIcon.png; sourceTree = SOURCE_ROOT; };
CDF08CEE1ACA677B009B3423 /* kernelIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = kernelIcon.png; path = images/kernelIcon.png; sourceTree = SOURCE_ROOT; };
CDF08CF11ACA6864009B3423 /* browserIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = browserIcon.png; path = images/browserIcon.png; sourceTree = SOURCE_ROOT; };
CDF08CF21ACA6864009B3423 /* loginIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = loginIcon.png; path = images/loginIcon.png; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
1D21BC48172AF43D009D1CFD /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CDF08CEA1AC8D97B009B3423 /* Quartz.framework in Frameworks */,
CD6095731A87067D00E091CD /* Security.framework in Frameworks */,
1D21BC4F172AF43D009D1CFD /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CDA5F6AA1B16D805003CE340 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1D21BC42172AF43D009D1CFD = {
isa = PBXGroup;
children = (
CD4D54201B2CE6F200008030 /* NSMutableArray+QueueAdditions.h */,
CD4D54211B2CE6F200008030 /* NSMutableArray+QueueAdditions.m */,
CD4D541D1B2CE6C400008030 /* Queue.h */,
CD4D541E1B2CE6C400008030 /* Queue.m */,
CDA5F6BE1B16DBAA003CE340 /* Interface */,
CD02195A1AD38823005148A2 /* kkRowCell.h */,
CD02195B1AD38823005148A2 /* kkRowCell.m */,
CD7B9FA91AD08FA100DF3C71 /* KKRow.h */,
CD7B9FAA1AD08FA100DF3C71 /* KKRow.m */,
CDF08CE31AC89FD4009B3423 /* 3rdParty */,
CD83887D1AACCEDF000EB098 /* VirusTotal.h */,
CD83887E1AACCEDF000EB098 /* VirusTotal.m */,
CDA81E621AA020E8009790E2 /* UI */,
CDA81DEC1A99B5F8009790E2 /* Filter.h */,
CDA81DED1A99B5F8009790E2 /* Filter.m */,
CDA81D7C1A96EFFF009790E2 /* Items */,
CDA81D781A95B939009790E2 /* UIControllers */,
1D21BC54172AF43D009D1CFD /* TaskExplorer */,
CDA5F6AE1B16D805003CE340 /* remoteTaskService */,
1D21BC4D172AF43D009D1CFD /* Frameworks */,
1D21BC4C172AF43D009D1CFD /* Products */,
);
sourceTree = "<group>";
};
1D21BC4C172AF43D009D1CFD /* Products */ = {
isa = PBXGroup;
children = (
1D21BC4B172AF43D009D1CFD /* TaskExplorer.app */,
CDA5F6AD1B16D805003CE340 /* remoteTaskService.xpc */,
);
name = Products;
sourceTree = "<group>";
};
1D21BC4D172AF43D009D1CFD /* Frameworks */ = {
isa = PBXGroup;
children = (
CDF08CE91AC8D97B009B3423 /* Quartz.framework */,
CD6095721A87067D00E091CD /* Security.framework */,
1D21BC4E172AF43D009D1CFD /* Cocoa.framework */,
1D21BC50172AF43D009D1CFD /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
1D21BC50172AF43D009D1CFD /* Other Frameworks */ = {
isa = PBXGroup;
children = (
1D21BC51172AF43D009D1CFD /* AppKit.framework */,
1D21BC52172AF43D009D1CFD /* CoreData.framework */,
1D21BC53172AF43D009D1CFD /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
1D21BC54172AF43D009D1CFD /* TaskExplorer */ = {
isa = PBXGroup;
children = (
CD3F4CE61AF5CF68002A2647 /* TaskEnumerator.m */,
CD3F4CE71AF5CF68002A2647 /* TaskEnumerator.h */,
CDD248391AF5CC4D00232422 /* Task.h */,
CDD2483A1AF5CC4D00232422 /* Task.m */,
CD7B9F4E1ACB9A8400DF3C71 /* Exception.h */,
CD7B9F4F1ACB9A8400DF3C71 /* Exception.m */,
CDF08CC71AC4C678009B3423 /* PrefsWindowController.h */,
CDF08CC81AC4C678009B3423 /* PrefsWindowController.m */,
CDA81D731A95B4FB009790E2 /* icon.iconset */,
CDA81D561A95B4B4009790E2 /* MainMenu.xib */,
CDF08CC41AC46E75009B3423 /* VTButton.h */,
CDF08CC51AC46E75009B3423 /* VTButton.m */,
CDA81D441A95B492009790E2 /* AppDelegate.h */,
CDA81D451A95B492009790E2 /* AppDelegate.m */,
CDA81D481A95B492009790E2 /* Consts.h */,
CDA81D4D1A95B492009790E2 /* Utilities.h */,
CDA81D4E1A95B492009790E2 /* Utilities.m */,
CD6095501A8329FA00E091CD /* images */,
1D21BC55172AF43D009D1CFD /* Supporting Files */,
);
name = TaskExplorer;
path = "Lesson 53";
sourceTree = "<group>";
};
1D21BC55172AF43D009D1CFD /* Supporting Files */ = {
isa = PBXGroup;
children = (
CDA81D541A95B4B4009790E2 /* InfoPlist.strings */,
CDA81D581A95B4B4009790E2 /* TaskExplorer-Info.plist */,
CDA81D591A95B4B4009790E2 /* TaskExplorer-Prefix.pch */,
CDA81D5A1A95B4B4009790E2 /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
CD6095501A8329FA00E091CD /* images */ = {
isa = PBXGroup;
children = (
CD4D53D11B23ED4300008030 /* listeningIcon.png */,
CD4D53CF1B23ED3900008030 /* connectedIcon.png */,
CD4D53C91B20296E00008030 /* unknown.png */,
CDA5F6C51B16E8D4003CE340 /* lockIcon.png */,
CDAB98A21AEB413C00C75B4B /* dylibIcon.png */,
CDAB98A01AEAFAFA00C75B4B /* authorizationIcon.png */,
CD0219561AD37748005148A2 /* signed2.png */,
CD0219571AD37748005148A2 /* unsigned2.png */,
CD0219541AD34E4C005148A2 /* kkIcon.png */,
CD7B9FA51ACCAE5E00DF3C71 /* startScanOver.png */,
CD7B9FA61ACCAE5E00DF3C71 /* stopScanOver.png */,
CD7B9FA31ACBCFAD00DF3C71 /* spotlightIcon.png */,
CD7B9F4C1ACB959200DF3C71 /* logoAppleOver.png */,
CDF08CF11ACA6864009B3423 /* browserIcon.png */,
CDF08CF21ACA6864009B3423 /* loginIcon.png */,
CDF08CED1ACA677B009B3423 /* launchIcon.png */,
CDF08CEE1ACA677B009B3423 /* kernelIcon.png */,
CDF08CE71AC8A35C009B3423 /* vtLogo.png */,
CDF08CCC1AC4C6E8009B3423 /* settingsOver.png */,
CDF08CCD1AC4C6E8009B3423 /* settingsBG.png */,
CDF08CCE1AC4C6E8009B3423 /* settings.png */,
CDF08CC21AC3E98D009B3423 /* infoOver.png */,
CDF08CC01AC3E8B0009B3423 /* showOver.png */,
CDF08CBE1AC3DE25009B3423 /* logoAppleBG.png */,
CD001B341AB903040089014A /* kkText.png */,
CD001B351AB903040089014A /* logo.png */,
CD001B361AB903040089014A /* logoApple.png */,
CDA81DD11A9970A0009790E2 /* signed.png */,
CDA81DD21A9970A0009790E2 /* unsigned.png */,
CDA81DC51A9960A3009790E2 /* info.png */,
CDA81DC61A9960A3009790E2 /* infoBG.png */,
CDA81DC71A9960A3009790E2 /* virusTotal.png */,
CDA81DC81A9960A3009790E2 /* virusTotalBG.png */,
CDA81D5F1A95B4E9009790E2 /* bug.png */,
CDA81D601A95B4E9009790E2 /* mainIcon.png */,
CDA81D611A95B4E9009790E2 /* show.png */,
CDA81D621A95B4E9009790E2 /* showBG.png */,
CDA81D631A95B4E9009790E2 /* scanIcon.png */,
CDA81D641A95B4E9009790E2 /* startScan.png */,
CDA81D651A95B4E9009790E2 /* startScanBG.png */,
CDA81D661A95B4E9009790E2 /* stopScan.png */,
CDA81D671A95B4E9009790E2 /* stopScanBG.png */,
CDA81D681A95B4E9009790E2 /* virus.png */,
);
name = images;
sourceTree = "<group>";
};
CDA5F6AE1B16D805003CE340 /* remoteTaskService */ = {
isa = PBXGroup;
children = (
CDA5F6B21B16D805003CE340 /* remoteTaskService.h */,
CDA5F6B31B16D805003CE340 /* remoteTaskService.m */,
CDA5F6B51B16D805003CE340 /* main.m */,
CDA5F6AF1B16D805003CE340 /* Supporting Files */,
);
path = remoteTaskService;
sourceTree = "<group>";
};
CDA5F6AF1B16D805003CE340 /* Supporting Files */ = {
isa = PBXGroup;
children = (
CDA5F6B01B16D805003CE340 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
CDA5F6BE1B16DBAA003CE340 /* Interface */ = {
isa = PBXGroup;
children = (
CDA5F6BF1B16DBC9003CE340 /* serviceInterface.h */,
);
name = Interface;
sourceTree = "<group>";
};
CDA81D781A95B939009790E2 /* UIControllers */ = {
isa = PBXGroup;
children = (
CDA5F6C21B16E20E003CE340 /* RequestRootWindowController.h */,
CDA5F6C31B16E20E003CE340 /* RequestRootWindowController.m */,
CD3F4D1A1AFADD36002A2647 /* TreeViewController.h */,
CD3F4D1B1AFADD36002A2647 /* TreeViewController.m */,
CD6E54FD1B1162B5007953AB /* ItemView.h */,
CD6E54FE1B1162B5007953AB /* ItemView.m */,
CD02195F1AD39A83005148A2 /* ResultsWindowController.h */,
CD0219601AD39A83005148A2 /* ResultsWindowController.m */,
CD0219511AD34D9A005148A2 /* AboutWindowController.h */,
CD0219521AD34D9A005148A2 /* AboutWindowController.m */,
CDF08CDC1AC886F2009B3423 /* VTInfoWindowController.h */,
CDF08CDD1AC886F2009B3423 /* VTInfoWindowController.m */,
CDA81DE71A997BF1009790E2 /* InfoWindowController.h */,
CDA81DE81A997BF1009790E2 /* InfoWindowController.m */,
CDA81D791A95D29B009790E2 /* TaskTableController.h */,
CDA81D7A1A95D29B009790E2 /* TaskTableController.m */,
);
name = UIControllers;
sourceTree = "<group>";
};
CDA81D7C1A96EFFF009790E2 /* Items */ = {
isa = PBXGroup;
children = (
CD3F4CF21AF71B58002A2647 /* Binary.h */,
CD3F4CF31AF71B58002A2647 /* Binary.m */,
CD3F4CF41AF71B58002A2647 /* Connection.h */,
CD3F4CF51AF71B58002A2647 /* Connection.m */,
CD3F4CF61AF71B58002A2647 /* File.h */,
CD3F4CF71AF71B58002A2647 /* File.m */,
CD3F4CF81AF71B58002A2647 /* ItemBase.h */,
CD3F4CF91AF71B58002A2647 /* ItemBase.m */,
);
name = Items;
sourceTree = "<group>";
};
CDA81E621AA020E8009790E2 /* UI */ = {
isa = PBXGroup;
children = (
CD4D54231B2D082300008030 /* DylibInfoWindow.xib */,
CDA5F6C01B16E1D6003CE340 /* RequestRootWindow.xib */,
CD3F4D151AF89066002A2647 /* TreeView.xib */,
CD3F4D131AF85088002A2647 /* FlatView.xib */,
CD3F4CFE1AF72BC4002A2647 /* TaskInfoWindow.xib */,
CD02195D1AD39A74005148A2 /* ResultsWindow.xib */,
CD02194D1AD34D8B005148A2 /* AboutWindow.xib */,
CD02194E1AD34D8B005148A2 /* PrefsWindow.xib */,
CDF08CE11AC88E0F009B3423 /* VTInfoWindow.xib */,
CDA81E641AA020FD009790E2 /* FileInfoWindow.xib */,
);
name = UI;
sourceTree = "<group>";
};
CDF08CE31AC89FD4009B3423 /* 3rdParty */ = {
isa = PBXGroup;
children = (
CD3F4CE91AF6D948002A2647 /* OrderedDictionary.h */,
CD3F4CEA1AF6D948002A2647 /* OrderedDictionary.m */,
CDD248301AF5947300232422 /* TAAdaptiveSpaceItem.h */,
CDD248311AF5947300232422 /* TAAdaptiveSpaceItem.m */,
CDD248321AF5947300232422 /* TAAdaptiveSpaceItemView.h */,
CDD248331AF5947300232422 /* TAAdaptiveSpaceItemView.m */,
CDF08CE41AC89FE1009B3423 /* HyperlinkTextField.h */,
CDF08CE51AC89FE1009B3423 /* HyperlinkTextField.m */,
);
name = 3rdParty;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
1D21BC4A172AF43D009D1CFD /* TaskExplorer */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1D21BC68172AF43D009D1CFD /* Build configuration list for PBXNativeTarget "TaskExplorer" */;
buildPhases = (
1D21BC47172AF43D009D1CFD /* Sources */,
1D21BC48172AF43D009D1CFD /* Frameworks */,
1D21BC49172AF43D009D1CFD /* Resources */,
CDA5F6B91B16D805003CE340 /* Embed XPC Services */,
);
buildRules = (
);
dependencies = (
CDA5F6B81B16D805003CE340 /* PBXTargetDependency */,
);
name = TaskExplorer;
productName = "Lesson 53";
productReference = 1D21BC4B172AF43D009D1CFD /* TaskExplorer.app */;
productType = "com.apple.product-type.application";
};
CDA5F6AC1B16D805003CE340 /* remoteTaskService */ = {
isa = PBXNativeTarget;
buildConfigurationList = CDA5F6BD1B16D805003CE340 /* Build configuration list for PBXNativeTarget "remoteTaskService" */;
buildPhases = (
CDA5F6A91B16D805003CE340 /* Sources */,
CDA5F6AA1B16D805003CE340 /* Frameworks */,
CDA5F6AB1B16D805003CE340 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = remoteTaskService;
productName = remoteTaskService;
productReference = CDA5F6AD1B16D805003CE340 /* remoteTaskService.xpc */;
productType = "com.apple.product-type.xpc-service";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
1D21BC43172AF43D009D1CFD /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0620;
ORGANIZATIONNAME = "Lucas Derraugh";
TargetAttributes = {
CDA5F6AC1B16D805003CE340 = {
CreatedOnToolsVersion = 6.3.2;
};
};
};
buildConfigurationList = 1D21BC46172AF43D009D1CFD /* Build configuration list for PBXProject "TaskExplorer" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 1D21BC42172AF43D009D1CFD;
productRefGroup = 1D21BC4C172AF43D009D1CFD /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
1D21BC4A172AF43D009D1CFD /* TaskExplorer */,
CDA5F6AC1B16D805003CE340 /* remoteTaskService */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
1D21BC49172AF43D009D1CFD /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CD4D53D01B23ED3900008030 /* connectedIcon.png in Resources */,
CDF08CE81AC8A35C009B3423 /* vtLogo.png in Resources */,
CDA81D691A95B4E9009790E2 /* bug.png in Resources */,
CD02195E1AD39A74005148A2 /* ResultsWindow.xib in Resources */,
CD3F4D141AF85088002A2647 /* FlatView.xib in Resources */,
CDA81D5B1A95B4B4009790E2 /* InfoPlist.strings in Resources */,
CD4D53CA1B20296E00008030 /* unknown.png in Resources */,
CDA81D6B1A95B4E9009790E2 /* show.png in Resources */,
CDF08CF31ACA6864009B3423 /* browserIcon.png in Resources */,
CDAB98A11AEAFAFA00C75B4B /* authorizationIcon.png in Resources */,
CD001B391AB903040089014A /* logoApple.png in Resources */,
CDF08CEF1ACA677B009B3423 /* launchIcon.png in Resources */,
CD7B9FA41ACBCFAD00DF3C71 /* spotlightIcon.png in Resources */,
CD7B9FA81ACCAE5E00DF3C71 /* stopScanOver.png in Resources */,
CDA81D701A95B4E9009790E2 /* stopScan.png in Resources */,
CDF08CF01ACA677B009B3423 /* kernelIcon.png in Resources */,
CDF08CD01AC4C6E8009B3423 /* settingsBG.png in Resources */,
CD0219551AD34E4C005148A2 /* kkIcon.png in Resources */,
CD0219591AD37748005148A2 /* unsigned2.png in Resources */,
CDA81D5C1A95B4B4009790E2 /* MainMenu.xib in Resources */,
CD7B9F4D1ACB959200DF3C71 /* logoAppleOver.png in Resources */,
CD0219581AD37748005148A2 /* signed2.png in Resources */,
CDA81DCB1A9960A3009790E2 /* virusTotal.png in Resources */,
CDA5F6C61B16E8D4003CE340 /* lockIcon.png in Resources */,
CDA81DD41A9970A0009790E2 /* unsigned.png in Resources */,
CD7B9FA71ACCAE5E00DF3C71 /* startScanOver.png in Resources */,
CD001B371AB903040089014A /* kkText.png in Resources */,
CDF08CC11AC3E8B0009B3423 /* showOver.png in Resources */,
CD4D54241B2D082300008030 /* DylibInfoWindow.xib in Resources */,
CDA81DCC1A9960A3009790E2 /* virusTotalBG.png in Resources */,
CD001B381AB903040089014A /* logo.png in Resources */,
CDA81D6D1A95B4E9009790E2 /* scanIcon.png in Resources */,
CDF08CCF1AC4C6E8009B3423 /* settingsOver.png in Resources */,
CDAB98A31AEB413C00C75B4B /* dylibIcon.png in Resources */,
CDF08CC31AC3E98D009B3423 /* infoOver.png in Resources */,
CDF08CF41ACA6864009B3423 /* loginIcon.png in Resources */,
CD3F4D161AF89066002A2647 /* TreeView.xib in Resources */,
CD0219501AD34D8B005148A2 /* PrefsWindow.xib in Resources */,
CDA81D6C1A95B4E9009790E2 /* showBG.png in Resources */,
CD3F4CFF1AF72BC4002A2647 /* TaskInfoWindow.xib in Resources */,
CDA81D6A1A95B4E9009790E2 /* mainIcon.png in Resources */,
CDA81D711A95B4E9009790E2 /* stopScanBG.png in Resources */,
CDF08CBF1AC3DE25009B3423 /* logoAppleBG.png in Resources */,
CDF08CE21AC88E0F009B3423 /* VTInfoWindow.xib in Resources */,
CD4D53D21B23ED4300008030 /* listeningIcon.png in Resources */,
CDA81D6F1A95B4E9009790E2 /* startScanBG.png in Resources */,
CDA5F6C11B16E1D6003CE340 /* RequestRootWindow.xib in Resources */,
CDA81D721A95B4E9009790E2 /* virus.png in Resources */,
CDA81DC91A9960A3009790E2 /* info.png in Resources */,
CDA81D741A95B4FB009790E2 /* icon.iconset in Resources */,
CDA81D6E1A95B4E9009790E2 /* startScan.png in Resources */,
CD02194F1AD34D8B005148A2 /* AboutWindow.xib in Resources */,
CDA81DCA1A9960A3009790E2 /* infoBG.png in Resources */,
CDF08CD11AC4C6E8009B3423 /* settings.png in Resources */,
CDA81DD31A9970A0009790E2 /* signed.png in Resources */,
CDA81E661AA020FD009790E2 /* FileInfoWindow.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CDA5F6AB1B16D805003CE340 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
1D21BC47172AF43D009D1CFD /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CD3F4CE81AF5CF68002A2647 /* TaskEnumerator.m in Sources */,
CD4D54221B2CE6F200008030 /* NSMutableArray+QueueAdditions.m in Sources */,
CDA5F6C41B16E20E003CE340 /* RequestRootWindowController.m in Sources */,
CDD2483B1AF5CC4D00232422 /* Task.m in Sources */,
CD83887F1AACCEDF000EB098 /* VirusTotal.m in Sources */,
CDF08CDF1AC886F2009B3423 /* VTInfoWindowController.m in Sources */,
CD3F4CEB1AF6D948002A2647 /* OrderedDictionary.m in Sources */,
CD0219611AD39A83005148A2 /* ResultsWindowController.m in Sources */,
CD4D541F1B2CE6C400008030 /* Queue.m in Sources */,
CD6E54FF1B1162B5007953AB /* ItemView.m in Sources */,
CDA81DEE1A99B5F8009790E2 /* Filter.m in Sources */,
CDA81D7B1A95D29B009790E2 /* TaskTableController.m in Sources */,
CDF08CCA1AC4C678009B3423 /* PrefsWindowController.m in Sources */,
CDA81DEA1A997BF1009790E2 /* InfoWindowController.m in Sources */,
CD3F4D1C1AFADD36002A2647 /* TreeViewController.m in Sources */,
CD02195C1AD38823005148A2 /* kkRowCell.m in Sources */,
CDF08CE61AC89FE1009B3423 /* HyperlinkTextField.m in Sources */,
CDA81D4F1A95B492009790E2 /* AppDelegate.m in Sources */,
CD3F4CFA1AF71B58002A2647 /* Binary.m in Sources */,
CD3F4CFC1AF71B58002A2647 /* File.m in Sources */,
CDA81D5E1A95B4B4009790E2 /* main.m in Sources */,
CD7B9F501ACB9A8400DF3C71 /* Exception.m in Sources */,
CDD248341AF5947300232422 /* TAAdaptiveSpaceItem.m in Sources */,
CD0219531AD34D9A005148A2 /* AboutWindowController.m in Sources */,
CDF08CC61AC46E75009B3423 /* VTButton.m in Sources */,
CD3F4CFB1AF71B58002A2647 /* Connection.m in Sources */,
CDD248351AF5947300232422 /* TAAdaptiveSpaceItemView.m in Sources */,
CDA81D531A95B492009790E2 /* Utilities.m in Sources */,
CD7B9FAB1AD08FA100DF3C71 /* KKRow.m in Sources */,
CD3F4CFD1AF71B58002A2647 /* ItemBase.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CDA5F6A91B16D805003CE340 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CDA5F6B61B16D805003CE340 /* main.m in Sources */,
CDA5F6B41B16D805003CE340 /* remoteTaskService.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
CDA5F6B81B16D805003CE340 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = CDA5F6AC1B16D805003CE340 /* remoteTaskService */;
targetProxy = CDA5F6B71B16D805003CE340 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
CDA81D541A95B4B4009790E2 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
CDA81D551A95B4B4009790E2 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
CDA81D561A95B4B4009790E2 /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
CDA81D571A95B4B4009790E2 /* en */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1D21BC66172AF43D009D1CFD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
1D21BC67172AF43D009D1CFD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Release;
};
1D21BC69172AF43D009D1CFD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "TaskExplorer-Prefix.pch";
INFOPLIST_FILE = "TaskExplorer-Info.plist";
PRODUCT_NAME = TaskExplorer;
WRAPPER_EXTENSION = app;
};
name = Debug;
};
1D21BC6A172AF43D009D1CFD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "TaskExplorer-Prefix.pch";
INFOPLIST_FILE = "TaskExplorer-Info.plist";
PRODUCT_NAME = TaskExplorer;
WRAPPER_EXTENSION = app;
};
name = Release;
};
CDA5F6BB1B16D805003CE340 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
COMBINE_HIDPI_IMAGES = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
INFOPLIST_FILE = remoteTaskService/Info.plist;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
CDA5F6BC1B16D805003CE340 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
INFOPLIST_FILE = remoteTaskService/Info.plist;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1D21BC46172AF43D009D1CFD /* Build configuration list for PBXProject "TaskExplorer" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1D21BC66172AF43D009D1CFD /* Debug */,
1D21BC67172AF43D009D1CFD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1D21BC68172AF43D009D1CFD /* Build configuration list for PBXNativeTarget "TaskExplorer" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1D21BC69172AF43D009D1CFD /* Debug */,
1D21BC6A172AF43D009D1CFD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CDA5F6BD1B16D805003CE340 /* Build configuration list for PBXNativeTarget "remoteTaskService" */ = {
isa = XCConfigurationList;
buildConfigurations = (
CDA5F6BB1B16D805003CE340 /* Debug */,
CDA5F6BC1B16D805003CE340 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 1D21BC43172AF43D009D1CFD /* Project object */;
}
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:../TaskEnumerator.h">
</FileRef>
<FileRef
location = "group:../TaskEnumerator.m">
</FileRef>
<FileRef
location = "self:TaskExplorer.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>1ECDBF86-1DFC-4002-A5BE-41FC31ACB68B</string>
<key>IDESourceControlProjectName</key>
<string>project</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>A9FFC1B124E25027A0E10FB456DBA9E2803FAE9D</key>
<string>https://bitbucket.org/objective-see/knockknock.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>KnockKnock.xcodeproj/project.xcworkspace</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>A9FFC1B124E25027A0E10FB456DBA9E2803FAE9D</key>
<string>../..</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>https://bitbucket.org/objective-see/knockknock.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>A9FFC1B124E25027A0E10FB456DBA9E2803FAE9D</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>A9FFC1B124E25027A0E10FB456DBA9E2803FAE9D</string>
<key>IDESourceControlWCCName</key>
<string>KnockKnock</string>
</dict>
</array>
</dict>
</plist>
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>FE4103FE-6F26-4639-8C9F-D8D32C76D6A9</string>
<key>IDESourceControlProjectName</key>
<string>TaskExplorer</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>A9FFC1B124E25027A0E10FB456DBA9E2803FAE9D</key>
<string>https://bitbucket.org/objective-see/knockknock.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>TaskExplorer.xcodeproj</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>A9FFC1B124E25027A0E10FB456DBA9E2803FAE9D</key>
<string>../..</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>https://bitbucket.org/objective-see/knockknock.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>A9FFC1B124E25027A0E10FB456DBA9E2803FAE9D</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>A9FFC1B124E25027A0E10FB456DBA9E2803FAE9D</string>
<key>IDESourceControlWCCName</key>
<string>TaskExplorer</string>
</dict>
</array>
</dict>
</plist>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
<true/>
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
<false/>
</dict>
</plist>
@@ -0,0 +1,241 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
scope = "0"
stopOnStyle = "0">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Task.m"
timestampString = "455934659.769831"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "509"
endingLineNumber = "509"
landmarkName = "-enumerateNetworking:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Task.m"
timestampString = "455934659.769831"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "319"
endingLineNumber = "319"
landmarkName = "-enumerateDylibs:allDylibs:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Task.m"
timestampString = "455934659.769831"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "402"
endingLineNumber = "402"
landmarkName = "-enumerateDylibs:allDylibs:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "455870793.890474"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "406"
endingLineNumber = "406"
landmarkName = "-reloadBottomPane:itemView:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "455871607.2373"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "413"
endingLineNumber = "413"
landmarkName = "-reloadBottomPane:itemView:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "455913381.256009"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "1354"
endingLineNumber = "1354"
landmarkName = "-selectBottomPaneContent:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "455927034.93809"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "1375"
endingLineNumber = "1375"
landmarkName = "-selectBottomPaneContent:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "455927034.93809"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "1378"
endingLineNumber = "1378"
landmarkName = "-selectBottomPaneContent:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "kkRowCell.m"
timestampString = "455918972.792996"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "15"
endingLineNumber = "15"
landmarkName = "-drawRect:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Task.m"
timestampString = "455933492.971073"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "95"
endingLineNumber = "95"
landmarkName = "-initWithPID:andPath:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Queue.m"
timestampString = "455934198.853999"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "94"
endingLineNumber = "94"
landmarkName = "-enqueue:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "TaskTableController.m"
timestampString = "455935914.851075"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "985"
endingLineNumber = "985"
landmarkName = "-showInfo:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "InfoWindowController.m"
timestampString = "455936252.706327"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "40"
endingLineNumber = "40"
landmarkName = "-initWithItem:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "InfoWindowController.m"
timestampString = "455936279.739463"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "95"
endingLineNumber = "95"
landmarkName = "-configure"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1D21BC4A172AF43D009D1CFD"
BuildableName = "TaskExplorer.app"
BlueprintName = "TaskExplorer"
ReferencedContainer = "container:TaskExplorer.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1D21BC4A172AF43D009D1CFD"
BuildableName = "TaskExplorer.app"
BlueprintName = "TaskExplorer"
ReferencedContainer = "container:TaskExplorer.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1D21BC4A172AF43D009D1CFD"
BuildableName = "TaskExplorer.app"
BlueprintName = "TaskExplorer"
ReferencedContainer = "container:TaskExplorer.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0630"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CDA5F6AC1B16D805003CE340"
BuildableName = "remoteTaskService.xpc"
BlueprintName = "remoteTaskService"
ReferencedContainer = "container:TaskExplorer.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1D21BC4A172AF43D009D1CFD"
BuildableName = "TaskExplorer.app"
BlueprintName = "TaskExplorer"
ReferencedContainer = "container:TaskExplorer.xcodeproj">
</BuildableReference>
</MacroExpansion>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1D21BC4A172AF43D009D1CFD"
BuildableName = "TaskExplorer.app"
BlueprintName = "TaskExplorer"
ReferencedContainer = "container:TaskExplorer.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CDA5F6AC1B16D805003CE340"
BuildableName = "remoteTaskService.xpc"
BlueprintName = "remoteTaskService"
ReferencedContainer = "container:TaskExplorer.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>TaskExplorer.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>remoteTaskService.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>1D21BC4A172AF43D009D1CFD</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>CDA5F6AC1B16D805003CE340</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
+81
View File
@@ -0,0 +1,81 @@
//
// ItemTableController.h
// KnockKnock
//
// Created by Patrick Wardle on 2/18/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "Task.h"
#import "InfoWindowController.h"
#import "VTInfoWindowController.h"
#import "3rdParty/OrderedDictionary.h"
#import <Foundation/Foundation.h>
@interface TaskTableController : NSViewController <NSTableViewDataSource, NSTableViewDelegate>
{
}
//tasks
// ->updated by task enumerator
//@property(nonatomic, retain)OrderedDictionary* tasks;
@property(nonatomic, retain)NSMutableArray* tableItems;
//category table view
@property(weak) IBOutlet NSTableView *itemView;
//info window
@property(retain, nonatomic)InfoWindowController* infoWindowController;
//preferences window controller
@property (nonatomic, retain)VTInfoWindowController* vtWindowController;
//currently selected row
// ->can help determine if newly selected row is really new
@property NSUInteger selectedRow;
//flag to differentiate between top/bottom view
@property BOOL isBottomPane;
/* METHODS */
//reload table
-(void)reloadTable;
//custom reload
// ->ensures selected row remains selected
-(void)refresh;
//grab a task at a row
-(Task*)taskForRow:(id)sender;
//button handler
// ->show item in finder
- (IBAction)showInFinder:(id)sender;
//button handler
// ->show info window
- (IBAction)showInfo:(id)sender;
//button handler
// ->show virus total info window
-(void)showVTInfo:(NSView*)button;
//scroll back up to top of table
-(void)scrollToTop;
//helper function
// ->get items array (either all or just unknown)
-(NSArray*)getTableItems;
//determine if instance is rendering top pane
// ->for now, just looks at 'tableItems' iVar
-(BOOL)isTopPane;
@end
File diff suppressed because it is too large Load Diff
+46
View File
@@ -0,0 +1,46 @@
/*-
* Copyright 2009, Mac OS X Internals. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY Mac OS X Internals ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Mac OS X Internals OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of Mac OS X Internals.
*/
#import <Cocoa/Cocoa.h>
#import "3rdParty/OrderedDictionary.h"
@interface TreeViewController : NSViewController
{
}
@property (weak) IBOutlet NSOutlineView *itemView;
//tasks
// ->updated by task enumerator
//@property(nonatomic, retain)OrderedDictionary* tasks;
@end
+305
View File
@@ -0,0 +1,305 @@
/*-
* Copyright 2009, Mac OS X Internals. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY Mac OS X Internals ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Mac OS X Internals OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of Mac OS X Internals.
*/
#import "Task.h"
#import "AppDelegate.h"
#import "TreeViewController.h"
#import "ItemView.h"
#import "KKRow.h"
@implementation TreeViewController
@synthesize itemView;
-(void)awakeFromNib
{
//auto-expand everything
//
[itemView expandItem:nil expandChildren:YES];
//TODO: do this in IB?
[itemView setTarget:self];
//[outlineView setDoubleAction:@selector(onDoubleAction:)];
}
//reload + row selection intact
-(void)refresh
{
//TODO: add logic to ensure selected row stays selected
[self.itemView reloadData];
return;
}
/*
-(void)showProcessInfo
{
NSArray *processes = [arrayController selectedObjects];
if ([processes count] > 0) {
ProcessInfo *pInfo = [processes objectAtIndex:0];
if (pInfo.processState != -1 ) {
TaskInfoController *taskInfoController = [TaskInfoController taskInfoController:pInfo];
[taskInfoController showInfo];
}
}
}
*/
/*
-(void)onDoubleAction:(NSEvent*)theEvent;
{
[self showProcessInfo];
}
-(NSArray*)sortDescriptors
{
return [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];
}
-(IBAction)menuItemAction:(id)sender
{
NSInteger clickedRow = [sender tag];
}
-(TasksInfoManager*)tasksInfoManager
{
return [TasksInfoManager instance];
}
-(NSString*)selectedAppName
{
NSString *result;
NSArray *processes = [arrayController selectedObjects];
if ([processes count] > 0) {
ProcessInfo *pInfo = [processes objectAtIndex:0];
result = pInfo.name;
}
return result;
}
*/
/*
-(void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(NSCell *)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
//Task* *task = [item representedObject];
Task* task = (Task*)item;
//item cell
NSTableCellView *itemCell = nil;
itemCell = (NSTableCellView*)cell;
//set main text
// ->name
[itemCell.textField setStringValue:task.path];
//[imageAndTextCell setImage:pInfo.icon_small];
/*
if ([[Settings instance] highlightProcesses] == YES) {
if (pInfo.processState == 0) { // process
[(NSTextFieldCell*)cell setTextColor:[NSColor blackColor]];
}
else if (pInfo.processState == 1) { // new process
[(NSTextFieldCell*)cell setTextColor:[NSColor greenColor]];
}
else if (pInfo.processState == -1) { // ended process
[(NSTextFieldCell*)cell setTextColor:[NSColor redColor]];
}
}
return;
}
*/
-(NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
//tasks
OrderedDictionary* tasks = nil;
//grab tasks
tasks = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.tasks;
//NSLog(@"task: %@", ((Task*)item).path);
//count
NSUInteger children = 0;
//when item is nil
// ->count is all children
if(nil == item)
{
//all
children = ((Task*)[tasks objectForKey:@0]).children.count;
}
//otherwise
// ->give number of item's kids
else
{
//NSLog(@"task: %@", ((Task*)item).path);
//
children = [((Task*)item).children count];
//NSLog(@"..has %lu kids", (unsigned long)children);
}
return children;
}
-(BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
//only no for leafs
// ->items w/o kids
if( (nil != item) &&
(0 == [[item children] count]) )
{
return NO;
}
else
{
return YES;
}
//return !item ? YES : [[item children] count] != 0;
}
//return child
-(id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
//tasks
OrderedDictionary* tasks = nil;
//task
Task* task = nil;
//grab tasks
tasks = ((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator.tasks;
//get task object
// ->by index to get key, then by key
//task = self.tasks[[self.tasks keyAtIndex:index]];
task = [tasks objectForKey:@0];
//NSLog(@"root item: %@", self.tasks[[self.tasks objectForKey:@1]]);
//root item
// ->child at index
if(nil == item)
{
return task;//[self.tasks objectForKey:@1];
}
//other items
// ->return *their* child!
else
{
return [tasks objectForKey:[(Task*)item children][index]];
}
}
//table delegate method
// ->return cell for row
-(NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
return createItemView(outlineView, self, (Task*)item);
}
//automatically invoked
// ->create custom (sub-classed) NSTableRowView
-(NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item
{
//row view
KKRow* rowView = nil;
//row ID
static NSString* const kRowIdentifier = @"RowView";
//try grab existing row view
rowView = [outlineView makeViewWithIdentifier:kRowIdentifier owner:self];
//make new if needed
if(nil == rowView)
{
//create new
// ->size doesn't matter
rowView = [[KKRow alloc] initWithFrame:NSZeroRect];
//set row ID
rowView.identifier = kRowIdentifier;
}
return rowView;
}
/*
//person object
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
//NSLog(@"column name: %@", [tableColumn identifier]);
// if ([[tableColumn identifier] isEqualToString:@"name"])
return [item path];
// return @"Nobody's Here!";
}
*/
/*
- (NSString *)outlineView:(NSOutlineView *)outlineView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tc item:(id)item mouseLocation:(NSPoint)mouseLocation
{
ProcessInfo *pInfo = [item representedObject];
NSNumber *id_table;
NSString *id_column;
id *cell_data;
NSString *descr = pInfo.description;
return (descr);
}
*/
@end
+62
View File
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="AboutWindowController">
<connections>
<outlet property="versionLabel" destination="OSm-xS-Dmd" id="luW-4O-fYe"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES" unifiedTitleAndToolbar="YES"/>
<rect key="contentRect" x="196" y="240" width="422" height="123"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="422" height="123"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
<rect key="frame" x="10" y="12" width="110" height="106"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkIcon" id="xKf-GK-m0k"/>
</imageView>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Eaf-yA-bbe">
<rect key="frame" x="141" y="63" width="180" height="50"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkText" id="Ws8-bD-j2R"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OSm-xS-Dmd">
<rect key="frame" x="141" y="51" width="182" height="19"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="version:" id="bBK-v0-ypq">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
<rect key="frame" x="280" y="11" width="128" height="32"/>
<buttonCell key="cell" type="push" title="more info" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="moreInfo:" target="-2" id="YYW-1b-uJY"/>
</connections>
</button>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="318" y="246.5"/>
</window>
</objects>
<resources>
<image name="kkIcon" width="512" height="512"/>
<image name="kkText" width="426.48001098632812" height="85.919998168945312"/>
</resources>
</document>
+158
View File
@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="InfoWindowController">
<connections>
<outlet property="arguments" destination="1eL-b7-I94" id="6GM-Ne-rgf"/>
<outlet property="date" destination="Wbv-SK-w53" id="Li5-qD-Hxq"/>
<outlet property="hashes" destination="GQc-va-MLN" id="ta6-6g-dzh"/>
<outlet property="icon" destination="l8H-S3-g8O" id="P7o-8z-MjY"/>
<outlet property="name" destination="NA2-2e-4hN" id="0Lg-xP-m03"/>
<outlet property="path" destination="dY9-WD-WAf" id="7Lg-cs-t0f"/>
<outlet property="sign" destination="5Rx-Vm-7gm" id="3g2-Ay-zQ4"/>
<outlet property="size" destination="hLU-fi-qXH" id="wZf-h4-BKf"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Task File Information" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
<rect key="contentRect" x="196" y="240" width="646" height="220"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="-1" width="646" height="220"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NA2-2e-4hN">
<rect key="frame" x="73" y="186" width="553" height="29"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" title="Item Name" id="pYD-IR-Vtv">
<font key="font" size="20" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dY9-WD-WAf">
<rect key="frame" x="75" y="151" width="553" height="34"/>
<textFieldCell key="cell" selectable="YES" sendsActionOnEndEditing="YES" title="Item Path" id="MfU-Jb-agl">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GMp-1g-TFI">
<rect key="frame" x="8" y="84" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="hash:" id="fYa-Av-reX">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GQc-va-MLN">
<rect key="frame" x="75" y="84" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item hash" id="yYo-KQ-DMm">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hLU-fi-qXH">
<rect key="frame" x="75" y="64" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item size" id="XJ7-Go-bkG">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wbv-SK-w53">
<rect key="frame" x="75" y="43" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item creation/modified" id="hR8-Wz-esN">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5Rx-Vm-7gm">
<rect key="frame" x="75" y="6" width="554" height="34"/>
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="signing status" id="00d-h4-SPW">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DFa-vc-wFY">
<rect key="frame" x="8" y="64" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="size:" id="iBS-9J-ok9">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tM6-Nq-1Rh">
<rect key="frame" x="8" y="43" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="time:" id="U3V-A7-jO8">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hel-J4-4Qt">
<rect key="frame" x="8" y="23" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="sign:" id="ezp-TW-Xky">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<box verticalHuggingPriority="750" fixedFrame="YES" title="Box" boxType="separator" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Oh7-Ag-bHc">
<rect key="frame" x="22" y="141" width="604" height="5"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="l8H-S3-g8O">
<rect key="frame" x="13" y="162" width="48" height="48"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="bug" id="w3z-uu-XKS"/>
</imageView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uJq-Bw-lDQ">
<rect key="frame" x="552" y="9" width="82" height="32"/>
<buttonCell key="cell" type="push" title="close" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="RwO-yA-Xwk">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="closeWindow:" target="-2" id="SSo-9s-xQz"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="i1i-Er-lQW">
<rect key="frame" x="8" y="110" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="args:" id="fZY-li-gtz">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1eL-b7-I94">
<rect key="frame" x="74" y="110" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item args" id="qTP-D2-QN6">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="430" y="250"/>
</window>
</objects>
<resources>
<image name="bug" width="256" height="256"/>
</resources>
</document>
+158
View File
@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="InfoWindowController">
<connections>
<outlet property="date" destination="Wbv-SK-w53" id="Li5-qD-Hxq"/>
<outlet property="hashes" destination="GQc-va-MLN" id="ta6-6g-dzh"/>
<outlet property="icon" destination="l8H-S3-g8O" id="P7o-8z-MjY"/>
<outlet property="name" destination="NA2-2e-4hN" id="0Lg-xP-m03"/>
<outlet property="path" destination="dY9-WD-WAf" id="7Lg-cs-t0f"/>
<outlet property="plist" destination="vm8-PU-Bu0" id="9mC-ha-tfK"/>
<outlet property="sign" destination="5Rx-Vm-7gm" id="3g2-Ay-zQ4"/>
<outlet property="size" destination="hLU-fi-qXH" id="wZf-h4-BKf"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="File Information" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
<rect key="contentRect" x="196" y="240" width="646" height="260"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="646" height="260"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NA2-2e-4hN">
<rect key="frame" x="73" y="226" width="553" height="29"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" title="Item Name" id="pYD-IR-Vtv">
<font key="font" size="20" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dY9-WD-WAf">
<rect key="frame" x="75" y="191" width="553" height="34"/>
<textFieldCell key="cell" selectable="YES" sendsActionOnEndEditing="YES" title="Item Path" id="MfU-Jb-agl">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GMp-1g-TFI">
<rect key="frame" x="8" y="149" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="hash:" id="fYa-Av-reX">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GQc-va-MLN">
<rect key="frame" x="75" y="149" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item hash" id="yYo-KQ-DMm">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hLU-fi-qXH">
<rect key="frame" x="75" y="129" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item size" id="XJ7-Go-bkG">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wbv-SK-w53">
<rect key="frame" x="75" y="108" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item creation/modified" id="hR8-Wz-esN">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5Rx-Vm-7gm">
<rect key="frame" x="75" y="51" width="554" height="34"/>
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="signing status" id="00d-h4-SPW">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vm8-PU-Bu0">
<rect key="frame" x="76" y="88" width="554" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="plist" id="23w-N2-C5Z">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DFa-vc-wFY">
<rect key="frame" x="8" y="129" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="size:" id="iBS-9J-ok9">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tM6-Nq-1Rh">
<rect key="frame" x="8" y="108" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="time:" id="U3V-A7-jO8">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hel-J4-4Qt">
<rect key="frame" x="8" y="68" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="sign:" id="ezp-TW-Xky">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fAH-dm-SJe">
<rect key="frame" x="8" y="88" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="list:" id="oqF-UL-ydq">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<box verticalHuggingPriority="750" fixedFrame="YES" title="Box" boxType="separator" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Oh7-Ag-bHc">
<rect key="frame" x="22" y="181" width="604" height="5"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="l8H-S3-g8O">
<rect key="frame" x="13" y="202" width="48" height="48"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="bug" id="w3z-uu-XKS"/>
</imageView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uJq-Bw-lDQ">
<rect key="frame" x="552" y="12" width="82" height="32"/>
<buttonCell key="cell" type="push" title="close" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="RwO-yA-Xwk">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="closeWindow:" target="-2" id="SSo-9s-xQz"/>
</connections>
</button>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="430" y="270"/>
</window>
</objects>
<resources>
<image name="bug" width="256" height="256"/>
</resources>
</document>
+461
View File
@@ -0,0 +1,461 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<development version="5000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="TaskTableController">
<connections>
<outlet property="itemView" destination="fb0-7X-Sm6" id="sWQ-Jv-UTG"/>
<outlet property="view" destination="T1P-b9-TzF" id="pja-1o-aue"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<view id="T1P-b9-TzF">
<rect key="frame" x="0.0" y="0.0" width="1306" height="294"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView ambiguous="YES" misplaced="YES" autohidesScrollers="YES" horizontalLineScroll="42" horizontalPageScroll="10" verticalLineScroll="42" verticalPageScroll="10" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" verticalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="QDh-31-mfl">
<rect key="frame" x="-3" y="20" width="1300" height="274"/>
<clipView key="contentView" ambiguous="YES" misplaced="YES" drawsBackground="NO" id="t1U-m3-CeJ">
<rect key="frame" x="1" y="1" width="1204" height="437"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="40" rowSizeStyle="automatic" viewBased="YES" id="fb0-7X-Sm6">
<rect key="frame" x="0.0" y="0.0" width="1298" height="0.0"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="MainCell" editable="NO" width="1295" minWidth="40" maxWidth="2000" id="sUM-Cl-ag5">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="XYM-bm-ie0">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="TaskCell" id="sdY-t5-tbW" customClass="kkRowCell">
<rect key="frame" x="1" y="1" width="1295" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cG6-PF-La2">
<rect key="frame" x="5" y="9" width="26" height="23"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="9B3-Dt-CCW"/>
<constraint firstAttribute="width" constant="20" id="XhL-Yo-1xA"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="0cD-OF-kgr"/>
</imageView>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="M2y-fe-Zb7">
<rect key="frame" x="33" y="23" width="11" height="11"/>
<constraints>
<constraint firstAttribute="width" constant="11" id="RPq-FT-sWw"/>
<constraint firstAttribute="height" constant="11" id="erK-aR-d7L"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="unknown" id="2ru-B9-6b1"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ryD-lC-8IR">
<rect key="frame" x="46" y="20" width="225" height="19"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Task Name" id="fEY-SM-ufc">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show in finder" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="107" translatesAutoresizingMaskIntoConstraints="NO" id="Y4J-KD-8iy">
<rect key="frame" x="1263" y="17" width="15" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="Nro-9M-6Xg"/>
<constraint firstAttribute="width" constant="15" id="rEk-W0-lvD"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="show" imagePosition="only" alignment="center" alternateImage="showBG" state="on" imageScaling="proportionallyDown" inset="2" id="Xle-cK-MOQ">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showInFinder:" target="-2" id="7nB-GA-ZiB"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="108" translatesAutoresizingMaskIntoConstraints="NO" id="gpF-bM-EQR">
<rect key="frame" x="1259" y="4" width="25" height="12"/>
<constraints>
<constraint firstAttribute="width" constant="25" id="F3C-cT-yKu"/>
<constraint firstAttribute="height" constant="12" id="k1Q-YJ-vSj"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="show" id="B5F-50-OCm">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="miW-QO-gna">
<rect key="frame" x="31" y="2" width="1093" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="item path" id="7xA-XP-LK6">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show virustotal info" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="103" translatesAutoresizingMaskIntoConstraints="NO" id="Dtg-ac-EVZ" customClass="VTButton">
<rect key="frame" x="1155" y="17" width="49" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="29" id="0ZR-hE-oUJ"/>
<constraint firstAttribute="width" constant="49" id="i1N-eU-GWT"/>
</constraints>
<buttonCell key="cell" type="bevel" title="▪ ▪ ▪" bezelStyle="regularSquare" imagePosition="overlaps" alignment="center" enabled="NO" refusesFirstResponder="YES" state="on" imageScaling="proportionallyDown" inset="2" id="WMp-cU-Uct">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" size="8" name="Menlo-Bold"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="104" translatesAutoresizingMaskIntoConstraints="NO" id="aPz-9H-xyy">
<rect key="frame" x="1148" y="4" width="65" height="12"/>
<constraints>
<constraint firstAttribute="width" constant="61" id="Mn9-1j-NeM"/>
<constraint firstAttribute="height" constant="12" id="pgg-Gc-7aV"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="virustotal" id="WbN-3u-Ihr">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show file info" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="105" translatesAutoresizingMaskIntoConstraints="NO" id="eBe-7K-OiH">
<rect key="frame" x="1226" y="17" width="15" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="3YM-AG-8um"/>
<constraint firstAttribute="width" constant="15" id="iZ2-6y-WKB"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="info" imagePosition="only" alignment="center" alternateImage="infoBG" state="on" imageScaling="proportionallyDown" inset="2" id="TCH-R3-DzT">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showInfo:" target="-2" id="1Jl-sO-iDL"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="106" translatesAutoresizingMaskIntoConstraints="NO" id="MqO-G8-w9L">
<rect key="frame" x="1220" y="4" width="25" height="12"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="xID-bs-CI7"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="info" id="ljw-jb-ljM">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="102" translatesAutoresizingMaskIntoConstraints="NO" id="Nky-Qb-S7Z">
<rect key="frame" x="295" y="20" width="79" height="18"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="ecq-WO-Xtq"/>
<constraint firstAttribute="width" constant="75" id="qxm-8e-ma2"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="pid" id="BVj-TR-eR2">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" white="0.49295236009999999" alpha="0.84999999999999998" colorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="Nky-Qb-S7Z" firstAttribute="leading" secondItem="ryD-lC-8IR" secondAttribute="trailing" constant="8" id="7Og-f1-rQH"/>
<constraint firstItem="cG6-PF-La2" firstAttribute="leading" secondItem="sdY-t5-tbW" secondAttribute="leading" constant="5" id="7ms-dD-as0"/>
<constraint firstItem="eBe-7K-OiH" firstAttribute="leading" secondItem="Dtg-ac-EVZ" secondAttribute="trailing" constant="18" id="Dd1-7F-oi4"/>
<constraint firstItem="miW-QO-gna" firstAttribute="leading" secondItem="cG6-PF-La2" secondAttribute="trailing" constant="8" id="J3y-8b-F3q"/>
<constraint firstItem="MqO-G8-w9L" firstAttribute="leading" secondItem="aPz-9H-xyy" secondAttribute="trailing" constant="9" id="Rfl-hR-rxD"/>
<constraint firstItem="Y4J-KD-8iy" firstAttribute="leading" secondItem="eBe-7K-OiH" secondAttribute="trailing" constant="20" id="TAx-KS-R7a"/>
<constraint firstAttribute="trailing" secondItem="Y4J-KD-8iy" secondAttribute="trailing" constant="10" id="iMf-M4-bv0"/>
<constraint firstAttribute="trailing" secondItem="gpF-bM-EQR" secondAttribute="trailing" constant="4" id="myW-Ol-OIp"/>
<constraint firstItem="Dtg-ac-EVZ" firstAttribute="leading" secondItem="miW-QO-gna" secondAttribute="trailing" constant="8" id="rxd-Fp-O3o"/>
<constraint firstItem="gpF-bM-EQR" firstAttribute="leading" secondItem="MqO-G8-w9L" secondAttribute="trailing" constant="10" id="tLu-Y9-F4d"/>
</constraints>
<connections>
<outlet property="imageView" destination="cG6-PF-La2" id="v1M-Zn-U5X"/>
<outlet property="textField" destination="ryD-lC-8IR" id="ias-DX-8EL"/>
</connections>
</tableCellView>
<tableCellView identifier="DylibCell" id="AMp-Sl-IUz" customClass="kkRowCell">
<rect key="frame" x="1" y="1" width="1295" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="bgG-DR-RMT">
<rect key="frame" x="13" y="23" width="11" height="11"/>
<constraints>
<constraint firstAttribute="width" constant="11" id="SRW-ea-jvI"/>
<constraint firstAttribute="height" constant="11" id="boT-hW-24p"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="unknown" id="tuX-G4-1az"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kE0-h4-XoU">
<rect key="frame" x="26" y="20" width="1000" height="19"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Dylib Name" id="BA3-2m-roK">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show in finder" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="107" translatesAutoresizingMaskIntoConstraints="NO" id="bau-Td-7ST">
<rect key="frame" x="1263" y="17" width="15" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="DPj-gb-dIB"/>
<constraint firstAttribute="width" constant="15" id="oNg-zE-nJv"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="show" imagePosition="only" alignment="center" alternateImage="showBG" state="on" imageScaling="proportionallyDown" inset="2" id="PQ1-ho-YTb">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showInFinder:" target="-2" id="iqe-Av-pL0"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="108" translatesAutoresizingMaskIntoConstraints="NO" id="DCt-ke-ecy">
<rect key="frame" x="1259" y="4" width="25" height="12"/>
<constraints>
<constraint firstAttribute="width" constant="25" id="SHJ-Pm-wjU"/>
<constraint firstAttribute="height" constant="12" id="dsu-l8-dLe"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="show" id="SbY-jh-Hwi">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="s79-UC-kl8">
<rect key="frame" x="11" y="2" width="1093" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="item path" id="efL-9x-1ue">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show virustotal info" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="103" translatesAutoresizingMaskIntoConstraints="NO" id="FC1-IO-3xs" customClass="VTButton">
<rect key="frame" x="1155" y="17" width="49" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="29" id="M7k-0n-E2g"/>
<constraint firstAttribute="width" constant="49" id="e6T-3k-tEd"/>
</constraints>
<buttonCell key="cell" type="bevel" title="▪ ▪ ▪" bezelStyle="regularSquare" imagePosition="overlaps" alignment="center" enabled="NO" refusesFirstResponder="YES" state="on" imageScaling="proportionallyDown" inset="2" id="nJM-0x-661">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" size="8" name="Menlo-Bold"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="104" translatesAutoresizingMaskIntoConstraints="NO" id="mKM-Ea-CdX">
<rect key="frame" x="1148" y="4" width="65" height="12"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="L1s-UF-cDG"/>
<constraint firstAttribute="width" constant="61" id="Yai-jE-Ag4"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="virustotal" id="6Bu-O1-DgW">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show file info" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="105" translatesAutoresizingMaskIntoConstraints="NO" id="Nvb-5R-deG">
<rect key="frame" x="1226" y="17" width="15" height="15"/>
<constraints>
<constraint firstAttribute="width" constant="15" id="CAs-CP-Cfn"/>
<constraint firstAttribute="height" constant="15" id="Nyk-SH-8p6"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="info" imagePosition="only" alignment="center" alternateImage="infoBG" state="on" imageScaling="proportionallyDown" inset="2" id="7oW-jB-dbZ">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showInfo:" target="-2" id="6cF-vs-qfi"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="106" translatesAutoresizingMaskIntoConstraints="NO" id="d6d-We-r4h">
<rect key="frame" x="1220" y="4" width="25" height="12"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="x00-pi-4zx"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="info" id="mzh-KR-osn">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="Nvb-5R-deG" firstAttribute="leading" secondItem="FC1-IO-3xs" secondAttribute="trailing" constant="18" id="B3b-K8-iKu"/>
<constraint firstItem="d6d-We-r4h" firstAttribute="leading" secondItem="mKM-Ea-CdX" secondAttribute="trailing" constant="9" id="Geb-Pj-PW9"/>
<constraint firstItem="FC1-IO-3xs" firstAttribute="leading" secondItem="s79-UC-kl8" secondAttribute="trailing" constant="8" id="Rb2-Pf-nT9"/>
<constraint firstAttribute="trailing" secondItem="bau-Td-7ST" secondAttribute="trailing" constant="10" id="YV7-dd-VnF"/>
<constraint firstItem="s79-UC-kl8" firstAttribute="leading" secondItem="AMp-Sl-IUz" secondAttribute="leading" constant="13" id="jUo-Cu-hm3"/>
<constraint firstItem="DCt-ke-ecy" firstAttribute="leading" secondItem="d6d-We-r4h" secondAttribute="trailing" constant="10" id="mQm-zs-mcQ"/>
<constraint firstItem="bau-Td-7ST" firstAttribute="leading" secondItem="Nvb-5R-deG" secondAttribute="trailing" constant="20" id="p6O-3z-4Kx"/>
<constraint firstAttribute="trailing" secondItem="DCt-ke-ecy" secondAttribute="trailing" constant="4" id="paK-cH-SPa"/>
</constraints>
<connections>
<outlet property="textField" destination="kE0-h4-XoU" id="ngK-iU-Wtk"/>
</connections>
</tableCellView>
<tableCellView identifier="FileCell" id="zC6-7V-PKY" customClass="kkRowCell">
<rect key="frame" x="1" y="1" width="1295" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LkX-uS-hKH">
<rect key="frame" x="11" y="20" width="1000" height="19"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="File Name" id="fg8-Ix-mHR">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show in finder" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="107" translatesAutoresizingMaskIntoConstraints="NO" id="yDq-tI-YQJ">
<rect key="frame" x="1263" y="17" width="15" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="weN-ut-xDd"/>
<constraint firstAttribute="width" constant="15" id="zwd-5o-XMf"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="show" imagePosition="only" alignment="center" alternateImage="showBG" state="on" imageScaling="proportionallyDown" inset="2" id="i29-A9-Sv1">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showInFinder:" target="-2" id="wBh-1s-Jgt"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="108" translatesAutoresizingMaskIntoConstraints="NO" id="27e-wh-BEp">
<rect key="frame" x="1259" y="4" width="25" height="12"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="M8u-tp-mKC"/>
<constraint firstAttribute="width" constant="25" id="nMd-Wy-wvB"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="show" id="VHL-k9-JxN">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="gwn-Wz-bDY">
<rect key="frame" x="11" y="2" width="1093" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="item path" id="1WZ-C2-VvW">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show file info" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="105" translatesAutoresizingMaskIntoConstraints="NO" id="8Vk-bl-kjr">
<rect key="frame" x="1226" y="17" width="15" height="15"/>
<constraints>
<constraint firstAttribute="width" constant="15" id="FLn-RP-zYu"/>
<constraint firstAttribute="height" constant="15" id="dM6-uC-lks"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="info" imagePosition="only" alignment="center" alternateImage="infoBG" state="on" imageScaling="proportionallyDown" inset="2" id="UDk-8x-xVs">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showInfo:" target="-2" id="eaC-mP-eoj"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="106" translatesAutoresizingMaskIntoConstraints="NO" id="tIY-Ij-plN">
<rect key="frame" x="1220" y="4" width="25" height="12"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="VXj-Yu-ucw"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="info" id="Jha-96-Egc">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="27e-wh-BEp" secondAttribute="trailing" constant="4" id="Ft1-LY-Scf"/>
<constraint firstItem="gwn-Wz-bDY" firstAttribute="leading" secondItem="zC6-7V-PKY" secondAttribute="leading" constant="13" id="GEK-N3-wIC"/>
<constraint firstItem="yDq-tI-YQJ" firstAttribute="leading" secondItem="8Vk-bl-kjr" secondAttribute="trailing" constant="20" id="aV6-Hu-Y5b"/>
<constraint firstAttribute="trailing" secondItem="yDq-tI-YQJ" secondAttribute="trailing" constant="10" id="fqn-su-UYW"/>
<constraint firstItem="27e-wh-BEp" firstAttribute="leading" secondItem="tIY-Ij-plN" secondAttribute="trailing" constant="10" id="w6k-vz-Q6U"/>
</constraints>
<connections>
<outlet property="textField" destination="LkX-uS-hKH" id="XKi-AB-R3o"/>
</connections>
</tableCellView>
<tableCellView identifier="NetworkCell" id="vkh-K9-CiP" customClass="kkRowCell">
<rect key="frame" x="1" y="1" width="1295" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="n84-aN-dS4">
<rect key="frame" x="5" y="9" width="26" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="20" id="S0W-eP-sJY"/>
<constraint firstAttribute="height" constant="20" id="beQ-3n-m5v"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="5ar-gc-DMu"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="clK-51-yQN">
<rect key="frame" x="31" y="2" width="1093" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="item path" id="DlS-aR-tJt">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="t4A-WM-KWO">
<rect key="frame" x="31" y="20" width="1000" height="19"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Network Info" id="Boe-bK-y2E">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="n84-aN-dS4" firstAttribute="leading" secondItem="vkh-K9-CiP" secondAttribute="leading" constant="5" id="iJH-Aa-QGY"/>
<constraint firstItem="clK-51-yQN" firstAttribute="leading" secondItem="n84-aN-dS4" secondAttribute="trailing" constant="8" id="zd5-Ae-yYB"/>
</constraints>
<connections>
<outlet property="imageView" destination="n84-aN-dS4" id="dGH-6T-93g"/>
<outlet property="textField" destination="t4A-WM-KWO" id="gOS-IJ-Hvb"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
<connections>
<outlet property="dataSource" destination="-2" id="SEP-G5-Rr5"/>
<outlet property="delegate" destination="-2" id="iWU-v0-A4g"/>
</connections>
</tableView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" controlSize="mini" horizontal="YES" id="gmJ-1g-Tah">
<rect key="frame" x="1" y="298" width="480" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" doubleValue="1" controlSize="mini" horizontal="NO" id="cwi-rA-cqP">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
<constraints>
<constraint firstItem="QDh-31-mfl" firstAttribute="leading" secondItem="T1P-b9-TzF" secondAttribute="leading" id="XxZ-TH-o2t"/>
<constraint firstAttribute="trailing" secondItem="QDh-31-mfl" secondAttribute="trailing" id="Z3y-5B-K5h"/>
</constraints>
<point key="canvasLocation" x="638" y="-658"/>
</view>
</objects>
<resources>
<image name="NSActionTemplate" width="14" height="14"/>
<image name="info" width="256" height="256"/>
<image name="infoBG" width="256" height="256"/>
<image name="show" width="256" height="256"/>
<image name="showBG" width="256" height="256"/>
<image name="unknown" width="256" height="256"/>
</resources>
</document>
+76
View File
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="PrefsWindowController">
<connections>
<outlet property="disableVTQueries" destination="d54-mZ-jqy" id="gCe-BP-bct"/>
<outlet property="disableVTQueriesBtn" destination="d54-mZ-jqy" id="Xx6-E1-yv0"/>
<outlet property="okButton" destination="HZZ-Es-mpy" id="GKU-Jc-ENB"/>
<outlet property="saveOutput" destination="6la-v6-zBD" id="iif-cF-w6y"/>
<outlet property="saveOutputBtn" destination="6la-v6-zBD" id="m3d-J9-MZg"/>
<outlet property="showTrustedItems" destination="4xV-kQ-iaT" id="3wm-5q-ib3"/>
<outlet property="showTrustedItemsBtn" destination="4xV-kQ-iaT" id="aEg-d4-Orl"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES" unifiedTitleAndToolbar="YES"/>
<rect key="contentRect" x="196" y="240" width="422" height="123"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="422" height="123"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
<rect key="frame" x="25" y="37" width="48" height="48"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="settings" id="xKf-GK-m0k"/>
</imageView>
<button focusRingType="none" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4xV-kQ-iaT">
<rect key="frame" x="101" y="85" width="189" height="18"/>
<buttonCell key="cell" type="check" title="include os/known items" bezelStyle="regularSquare" imagePosition="left" focusRingType="none" inset="2" id="WN8-cQ-8xh">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
</button>
<button focusRingType="none" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d54-mZ-jqy">
<rect key="frame" x="101" y="52" width="303" height="19"/>
<buttonCell key="cell" type="check" title="disable virustotal integration" bezelStyle="regularSquare" imagePosition="left" focusRingType="none" inset="2" id="gXW-vY-Aj1">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
</button>
<button focusRingType="none" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6la-v6-zBD">
<rect key="frame" x="101" y="19" width="160" height="18"/>
<buttonCell key="cell" type="check" title="save results" bezelStyle="regularSquare" imagePosition="left" focusRingType="none" inset="2" id="8A7-6z-flS">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
<rect key="frame" x="326" y="10" width="82" height="32"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="closeWindow:" target="-2" id="eFa-k0-zTM"/>
</connections>
</button>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="318" y="246.5"/>
</window>
</objects>
<resources>
<image name="settings" width="256" height="256"/>
</resources>
</document>
+72
View File
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="RequestRootWindowController">
<connections>
<outlet property="statusMsg" destination="OSm-xS-Dmd" id="mh0-TD-SLI"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES" unifiedTitleAndToolbar="YES"/>
<rect key="contentRect" x="196" y="240" width="422" height="148"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="-2" width="422" height="148"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Eaf-yA-bbe">
<rect key="frame" x="141" y="88" width="180" height="50"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkText" id="Ws8-bD-j2R"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OSm-xS-Dmd">
<rect key="frame" x="141" y="49" width="271" height="41"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="please authenticate TaskExplorer" id="bBK-v0-ypq">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="sNs-lK-0YZ">
<rect key="frame" x="190" y="13" width="128" height="32"/>
<buttonCell key="cell" type="push" title="authenticate" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="9IW-5U-ukA">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="authenticate:" target="-2" id="not-EQ-mpp"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
<rect key="frame" x="328" y="13" width="80" height="32"/>
<buttonCell key="cell" type="push" title="cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="close:" target="-2" id="Ege-pO-ZGg"/>
</connections>
</button>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
<rect key="frame" x="11" y="22" width="110" height="106"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="lockIcon" id="xKf-GK-m0k"/>
</imageView>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="318" y="259"/>
</window>
</objects>
<resources>
<image name="kkText" width="426.48001098632812" height="85.919998168945312"/>
<image name="lockIcon" width="256" height="256"/>
</resources>
</document>
+65
View File
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7702"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="ResultsWindowController">
<connections>
<outlet property="detailsLabel" destination="OSm-xS-Dmd" id="fAP-nb-hfk"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES" unifiedTitleAndToolbar="YES"/>
<rect key="contentRect" x="196" y="240" width="422" height="138"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="-1" width="422" height="138"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lEv-Wj-6S5">
<rect key="frame" x="10" y="4" width="121" height="133"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkIcon" id="xKf-GK-m0k"/>
</imageView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="OSm-xS-Dmd">
<rect key="frame" x="138" y="45" width="261" height="60"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="results..." id="bBK-v0-ypq">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="h9d-xm-5lM">
<rect key="frame" x="138" y="106" width="182" height="19"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="scan complete" id="viG-9e-1Nj">
<font key="font" size="13" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HZZ-Es-mpy">
<rect key="frame" x="309" y="13" width="94" height="32"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J9x-sM-h9S">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="close:" target="-2" id="uMS-EM-Wl2"/>
</connections>
</button>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="318" y="253"/>
</window>
</objects>
<resources>
<image name="kkIcon" width="512" height="512"/>
</resources>
</document>
+158
View File
@@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="InfoWindowController">
<connections>
<outlet property="arguments" destination="1eL-b7-I94" id="6GM-Ne-rgf"/>
<outlet property="date" destination="Wbv-SK-w53" id="Li5-qD-Hxq"/>
<outlet property="hashes" destination="GQc-va-MLN" id="ta6-6g-dzh"/>
<outlet property="icon" destination="l8H-S3-g8O" id="P7o-8z-MjY"/>
<outlet property="name" destination="NA2-2e-4hN" id="0Lg-xP-m03"/>
<outlet property="path" destination="dY9-WD-WAf" id="7Lg-cs-t0f"/>
<outlet property="sign" destination="5Rx-Vm-7gm" id="3g2-Ay-zQ4"/>
<outlet property="size" destination="hLU-fi-qXH" id="wZf-h4-BKf"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Task File Information" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
<rect key="contentRect" x="196" y="240" width="646" height="220"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="-1" width="646" height="220"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NA2-2e-4hN">
<rect key="frame" x="73" y="186" width="553" height="29"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" title="Item Name" id="pYD-IR-Vtv">
<font key="font" size="20" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dY9-WD-WAf">
<rect key="frame" x="75" y="151" width="553" height="34"/>
<textFieldCell key="cell" selectable="YES" sendsActionOnEndEditing="YES" title="Item Path" id="MfU-Jb-agl">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GMp-1g-TFI">
<rect key="frame" x="8" y="84" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="hash:" id="fYa-Av-reX">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GQc-va-MLN">
<rect key="frame" x="75" y="84" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item hash" id="yYo-KQ-DMm">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hLU-fi-qXH">
<rect key="frame" x="75" y="64" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item size" id="XJ7-Go-bkG">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wbv-SK-w53">
<rect key="frame" x="75" y="43" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item creation/modified" id="hR8-Wz-esN">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5Rx-Vm-7gm">
<rect key="frame" x="75" y="6" width="554" height="34"/>
<textFieldCell key="cell" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="signing status" id="00d-h4-SPW">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DFa-vc-wFY">
<rect key="frame" x="8" y="64" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="size:" id="iBS-9J-ok9">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tM6-Nq-1Rh">
<rect key="frame" x="8" y="43" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="time:" id="U3V-A7-jO8">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hel-J4-4Qt">
<rect key="frame" x="8" y="23" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="sign:" id="ezp-TW-Xky">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<box verticalHuggingPriority="750" fixedFrame="YES" title="Box" boxType="separator" titlePosition="noTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Oh7-Ag-bHc">
<rect key="frame" x="22" y="141" width="604" height="5"/>
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<font key="titleFont" metaFont="system"/>
</box>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="l8H-S3-g8O">
<rect key="frame" x="13" y="162" width="48" height="48"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="bug" id="w3z-uu-XKS"/>
</imageView>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uJq-Bw-lDQ">
<rect key="frame" x="552" y="9" width="82" height="32"/>
<buttonCell key="cell" type="push" title="close" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="RwO-yA-Xwk">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="closeWindow:" target="-2" id="SSo-9s-xQz"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="i1i-Er-lQW">
<rect key="frame" x="8" y="110" width="59" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="args:" id="fZY-li-gtz">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1eL-b7-I94">
<rect key="frame" x="74" y="110" width="555" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="left" title="item args" id="qTP-D2-QN6">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="430" y="250"/>
</window>
</objects>
<resources>
<image name="bug" width="256" height="256"/>
</resources>
</document>
+213
View File
@@ -0,0 +1,213 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<development version="5000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="TreeViewController">
<connections>
<outlet property="itemView" destination="Wr1-No-lg2" id="74i-TW-N6D"/>
<outlet property="view" destination="T1P-b9-TzF" id="pja-1o-aue"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<view id="T1P-b9-TzF">
<rect key="frame" x="0.0" y="0.0" width="1306" height="294"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView fixedFrame="YES" borderType="line" autohidesScrollers="YES" horizontalLineScroll="42" horizontalPageScroll="10" verticalLineScroll="42" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mTr-W0-MgJ">
<rect key="frame" x="0.0" y="0.0" width="1306" height="294"/>
<clipView key="contentView" misplaced="YES" id="Sbm-Z7-NmT">
<rect key="frame" x="1" y="17" width="238" height="117"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="40" rowSizeStyle="automatic" viewBased="YES" indentationPerLevel="16" outlineTableColumn="cLW-QZ-CYz" id="Wr1-No-lg2">
<rect key="frame" x="0.0" y="0.0" width="1298" height="0.0"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="MainCell" editable="NO" width="1301" minWidth="40" maxWidth="2000" id="cLW-QZ-CYz">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" alignment="left" title="Text Cell" id="r1l-iI-5S2">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="ImageCell" id="7xB-nb-n5O" customClass="kkRowCell">
<rect key="frame" x="1" y="1" width="1295" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DMw-xR-BeB">
<rect key="frame" x="5" y="9" width="26" height="23"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="N3v-eG-0fM"/>
<constraint firstAttribute="width" constant="20" id="ZmE-rN-Aa2"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="I2b-0v-y6D"/>
</imageView>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" misplaced="YES" tag="100" translatesAutoresizingMaskIntoConstraints="NO" id="839-dJ-gQp">
<rect key="frame" x="33" y="23" width="11" height="11"/>
<constraints>
<constraint firstAttribute="height" constant="11" id="1Kh-hp-YgV"/>
<constraint firstAttribute="width" constant="11" id="WKY-rc-A7v"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="unknown" id="cl5-Gt-HMs"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oWx-jq-02H">
<rect key="frame" x="46" y="20" width="225" height="18"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Item Name" id="Z6I-g2-cup">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show in finder" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="107" translatesAutoresizingMaskIntoConstraints="NO" id="6f3-ri-fbE">
<rect key="frame" x="1263" y="17" width="15" height="15"/>
<constraints>
<constraint firstAttribute="width" constant="15" id="Mza-vw-e2F"/>
<constraint firstAttribute="height" constant="15" id="qqU-cb-eBX"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="show" imagePosition="only" alignment="center" alternateImage="showBG" state="on" imageScaling="proportionallyDown" inset="2" id="cy3-S9-iUc">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="108" translatesAutoresizingMaskIntoConstraints="NO" id="Wjv-b4-LpE">
<rect key="frame" x="1259" y="4" width="25" height="12"/>
<constraints>
<constraint firstAttribute="width" constant="25" id="IdA-gX-1SJ"/>
<constraint firstAttribute="height" constant="12" id="mEP-zn-5P5"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="show" id="Ypq-tG-G2w">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="101" translatesAutoresizingMaskIntoConstraints="NO" id="vl6-B3-YnP">
<rect key="frame" x="31" y="2" width="1093" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="item path" id="IxF-8j-bl0">
<font key="font" size="11" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show virustotal info" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="103" translatesAutoresizingMaskIntoConstraints="NO" id="4A1-v1-fqF" customClass="VTButton">
<rect key="frame" x="1155" y="17" width="49" height="20"/>
<constraints>
<constraint firstAttribute="height" constant="29" id="81l-Vw-eYi"/>
<constraint firstAttribute="width" constant="49" id="Tsp-mH-sb0"/>
</constraints>
<buttonCell key="cell" type="bevel" title="▪ ▪ ▪" bezelStyle="regularSquare" imagePosition="overlaps" alignment="center" enabled="NO" refusesFirstResponder="YES" state="on" imageScaling="proportionallyDown" inset="2" id="7Ff-Cs-4HN">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" size="8" name="Menlo-Bold"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="104" translatesAutoresizingMaskIntoConstraints="NO" id="NKv-qJ-K0K">
<rect key="frame" x="1148" y="4" width="65" height="12"/>
<constraints>
<constraint firstAttribute="width" constant="61" id="BhB-I3-B9j"/>
<constraint firstAttribute="height" constant="12" id="Lvp-ST-Nn4"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="virustotal" id="6oc-VM-LLN">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button toolTip="show file info" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="105" translatesAutoresizingMaskIntoConstraints="NO" id="DJD-ri-L1B">
<rect key="frame" x="1226" y="17" width="15" height="15"/>
<constraints>
<constraint firstAttribute="height" constant="15" id="OjK-9U-ZN2"/>
<constraint firstAttribute="width" constant="15" id="VnG-o4-pT8"/>
</constraints>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="info" imagePosition="only" alignment="center" alternateImage="infoBG" state="on" imageScaling="proportionallyDown" inset="2" id="Pt4-bk-dHy">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="106" translatesAutoresizingMaskIntoConstraints="NO" id="66d-28-HRc">
<rect key="frame" x="1220" y="4" width="25" height="12"/>
<constraints>
<constraint firstAttribute="height" constant="12" id="U1Q-a7-1C4"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="info" id="D2L-sc-I1J">
<font key="font" size="9" name="Menlo-Regular"/>
<color key="textColor" white="0.5" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" tag="102" translatesAutoresizingMaskIntoConstraints="NO" id="bxk-nY-Ojx">
<rect key="frame" x="295" y="20" width="79" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="75" id="QKJ-lc-9uH"/>
<constraint firstAttribute="height" constant="18" id="lqD-mH-tWl"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="pid" id="yDx-Lo-cYE">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" white="0.49295236009999999" alpha="0.84999999999999998" colorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="6f3-ri-fbE" firstAttribute="leading" secondItem="DJD-ri-L1B" secondAttribute="trailing" constant="20" id="62I-6i-bdJ"/>
<constraint firstItem="66d-28-HRc" firstAttribute="leading" secondItem="NKv-qJ-K0K" secondAttribute="trailing" constant="9" id="D01-9Y-AMk"/>
<constraint firstItem="DMw-xR-BeB" firstAttribute="leading" secondItem="7xB-nb-n5O" secondAttribute="leading" constant="5" id="EEt-PD-0zF"/>
<constraint firstItem="bxk-nY-Ojx" firstAttribute="leading" secondItem="oWx-jq-02H" secondAttribute="trailing" constant="8" id="IP5-Ta-1Bu"/>
<constraint firstItem="4A1-v1-fqF" firstAttribute="leading" secondItem="vl6-B3-YnP" secondAttribute="trailing" constant="8" id="VbZ-DW-ip1"/>
<constraint firstItem="vl6-B3-YnP" firstAttribute="leading" secondItem="DMw-xR-BeB" secondAttribute="trailing" constant="8" id="gVM-E6-C5n"/>
<constraint firstAttribute="trailing" secondItem="Wjv-b4-LpE" secondAttribute="trailing" constant="4" id="nBr-zQ-aVu"/>
<constraint firstAttribute="trailing" secondItem="6f3-ri-fbE" secondAttribute="trailing" constant="10" id="nNS-um-ew2"/>
<constraint firstItem="Wjv-b4-LpE" firstAttribute="leading" secondItem="66d-28-HRc" secondAttribute="trailing" constant="10" id="qg8-JA-AGc"/>
<constraint firstItem="DJD-ri-L1B" firstAttribute="leading" secondItem="4A1-v1-fqF" secondAttribute="trailing" constant="18" id="qrS-aQ-C2c"/>
</constraints>
<connections>
<outlet property="imageView" destination="DMw-xR-BeB" id="m01-aR-tqa"/>
<outlet property="textField" destination="oWx-jq-02H" id="hC6-7m-qaL"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
<connections>
<outlet property="dataSource" destination="-2" id="AI8-10-Pvd"/>
<outlet property="delegate" destination="-2" id="Edd-Bv-VRx"/>
</connections>
</outlineView>
</subviews>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="7QY-ke-KIc">
<rect key="frame" x="1" y="109.73348331451416" width="220" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="ifK-Bg-0Ke">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
<point key="canvasLocation" x="638" y="-658"/>
</view>
</objects>
<resources>
<image name="NSActionTemplate" width="14" height="14"/>
<image name="info" width="256" height="256"/>
<image name="infoBG" width="256" height="256"/>
<image name="show" width="256" height="256"/>
<image name="showBG" width="256" height="256"/>
<image name="unknown" width="256" height="256"/>
</resources>
</document>
+142
View File
@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6751" systemVersion="14C1514" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6751"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="VTInfoWindowController">
<connections>
<outlet property="analysisURL" destination="Wbv-SK-w53" id="vRG-LY-sA2"/>
<outlet property="analysisURLLabel" destination="tM6-Nq-1Rh" id="tVS-Z8-QoN"/>
<outlet property="closeButton" destination="uJq-Bw-lDQ" id="RWs-cM-R4U"/>
<outlet property="detectionRatio" destination="hLU-fi-qXH" id="HMI-2q-F37"/>
<outlet property="detectionRatioLabel" destination="DFa-vc-wFY" id="KeB-h4-vI3"/>
<outlet property="fileName" destination="hcM-hb-3Lz" id="uSy-od-y3n"/>
<outlet property="fileNameLabel" destination="Plg-lF-OEE" id="KeM-nK-KQA"/>
<outlet property="overlayView" destination="S16-Le-yTU" id="8Ye-PE-A3D"/>
<outlet property="progressIndicator" destination="egv-M2-RqY" id="zgU-Hu-k7Z"/>
<outlet property="statusMsg" destination="Hew-Ee-HGX" id="BFR-Pr-u6h"/>
<outlet property="submitButton" destination="Sxd-Ob-1Af" id="jB1-QN-Af2"/>
<outlet property="unknownFile" destination="eEi-hA-pdx" id="tY3-qL-05e"/>
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="VirusTotal Information" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="F0z-JX-Cv5">
<windowStyleMask key="styleMask" titled="YES" closable="YES" texturedBackground="YES"/>
<rect key="contentRect" x="196" y="240" width="534" height="144"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="0.0" width="534" height="144"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uJq-Bw-lDQ">
<rect key="frame" x="430" y="13" width="90" height="32"/>
<buttonCell key="cell" type="push" title="close" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="RwO-yA-Xwk">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="closeButtonHandler:" target="-2" id="h73-fH-gDU"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hLU-fi-qXH">
<rect key="frame" x="189" y="81" width="650" height="19"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" alignment="left" title="ratio" id="XJ7-Go-bkG">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wbv-SK-w53" customClass="HyperlinkTextField">
<rect key="frame" x="189" y="53" width="650" height="19"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" alignment="left" title="report url" id="hR8-Wz-esN">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DFa-vc-wFY">
<rect key="frame" x="99" y="81" width="83" height="19"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="detection:" id="iBS-9J-ok9">
<font key="font" size="13" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tM6-Nq-1Rh">
<rect key="frame" x="57" y="53" width="125" height="19"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="more info:" id="U3V-A7-jO8">
<font key="font" size="13" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hcM-hb-3Lz" customClass="HyperlinkTextField">
<rect key="frame" x="189" y="106" width="650" height="19"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" alignment="left" title="file name" id="3TS-NZ-XYE">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Plg-lF-OEE">
<rect key="frame" x="99" y="107" width="83" height="19"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="file name:" id="HO9-t1-yCi">
<font key="font" size="13" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vO5-mf-hOM">
<rect key="frame" x="20" y="56" width="68" height="68"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="vtLogo" id="qFc-P8-Wm8"/>
</imageView>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eEi-hA-pdx">
<rect key="frame" x="18" y="81" width="498" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="unknown file" id="2nj-QY-6ot">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Sxd-Ob-1Af">
<rect key="frame" x="340" y="13" width="90" height="32"/>
<buttonCell key="cell" type="push" title="submit?" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="JAW-nH-eRf">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" size="13" name="Menlo-Regular"/>
</buttonCell>
<connections>
<action selector="vtButtonHandler:" target="-2" id="YtT-aa-xM1"/>
</connections>
</button>
<customView hidden="YES" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="S16-Le-yTU">
<rect key="frame" x="0.0" y="-12" width="534" height="156"/>
<subviews>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Hew-Ee-HGX">
<rect key="frame" x="18" y="52" width="498" height="20"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" title="status msg" id="lxM-ES-i7K">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<progressIndicator hidden="YES" wantsLayer="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" maxValue="100" bezeled="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="egv-M2-RqY">
<rect key="frame" x="251" y="74" width="32" height="32"/>
</progressIndicator>
</subviews>
</customView>
</subviews>
</view>
<connections>
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
</connections>
<point key="canvasLocation" x="374" y="212"/>
</window>
</objects>
<resources>
<image name="vtLogo" width="300" height="300"/>
</resources>
</document>
+79
View File
@@ -0,0 +1,79 @@
//
// Utilities.h
// DHS
//
// Created by Patrick Wardle on 2/7/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#ifndef DHS_Utilities_h
#define DHS_Utilities_h
//get the signing info of a file
NSDictionary* extractSigningInfo(NSString* path);
/* METHODS */
//check if OS is supported
BOOL isSupportedOS();
//get OS's major or minor version
SInt32 getVersion(OSType selector);
//if string is too long to fit into a the text field
// ->truncate and insert ellipises before /file
NSString* stringByTruncatingString(NSTextField* textField, NSString* string, float width);
//get an icon for a process
// ->for apps, this will be app's icon, otherwise just a standard system one
NSImage* getIconForBinary(NSString* binary, NSBundle* bundle);
//given a path to binary
// parse it back up to find app's bundle
NSBundle* findAppBundle(NSString* binaryPath);
//given a directory and a filter predicate
// ->return all matches
NSArray* directoryContents(NSString* directory, NSString* predicate);
//hash (sha1/md5) a file
NSDictionary* hashFile(NSString* filePath);
//get app's version
// ->extracted from Info.plist
NSString* getAppVersion();
//determine if a file is signed by Apple proper
BOOL isApple(NSString* path);
//convert a textview to a clickable hyperlink
void makeTextViewHyperlink(NSTextField* textField, NSURL* url);
//determine if a file is signed by Apple proper
BOOL isApple(NSString* path);
//set the color of an attributed string
NSMutableAttributedString* setStringColor(NSAttributedString* string, NSColor* color);
//exec a process and grab it's output
NSData* execTask(NSString* binaryPath, NSArray* arguments);
//wait until a window is non nil
// ->then make it modal
void makeModal(NSWindowController* windowController);
//given a pid, get its parent (ppid)
pid_t getParentID(int pid);
//get path to XPC service
NSString* getPath2XPC();
//get path to kernel
NSString* path2Kernel();
//determine if process is (still) alive
BOOL isAlive(pid_t targetPID);
#endif
+831
View File
@@ -0,0 +1,831 @@
//
// Utilities.m
// DHS
//
// Created by Patrick Wardle on 2/7/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "Consts.h"
#import "Utilities.h"
#import <signal.h>
#import <unistd.h>
#import <libproc.h>
#import <sys/sysctl.h>
#import <Security/Security.h>
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
//check if OS is supported
BOOL isSupportedOS()
{
//return
BOOL isSupported = NO;
//major version
SInt32 versionMajor = 0;
//minor version
SInt32 versionMinor = 0;
//get major version
versionMajor = getVersion(gestaltSystemVersionMajor);
//get minor version
versionMinor = getVersion(gestaltSystemVersionMinor);
//sanity check
if( (-1 == versionMajor) ||
(-1 == versionMinor) )
{
//err
goto bail;
}
//check that OS is supported
// ->10.8+ ?
if( (versionMajor == OS_MAJOR_VERSION_X) &&
(versionMinor >= OS_MINOR_VERSION_LION) )
{
//set flag
isSupported = YES;
}
//bail
bail:
return isSupported;
}
//get OS's major or minor version
SInt32 getVersion(OSType selector)
{
//version
// ->major or minor
SInt32 version = -1;
//get version info
if(noErr != Gestalt(selector, &version))
{
//reset version
version = -1;
//err
goto bail;
}
//bail
bail:
return version;
}
//get the signing info of a file
NSDictionary* extractSigningInfo(NSString* path)
{
//info dictionary
NSMutableDictionary* signingStatus = nil;
//code
SecStaticCodeRef staticCode = NULL;
//status
OSStatus status = !STATUS_SUCCESS;
//signing information
CFDictionaryRef signingInformation = NULL;
//cert chain
NSArray* certificateChain = nil;
//index
NSUInteger index = 0;
//cert
SecCertificateRef certificate = NULL;
//common name on chert
CFStringRef commonName = NULL;
//init signing status
signingStatus = [NSMutableDictionary dictionary];
//create static code
status = SecStaticCodeCreateWithPath((__bridge CFURLRef)([NSURL fileURLWithPath:path]), kSecCSDefaultFlags, &staticCode);
//save signature status
signingStatus[KEY_SIGNATURE_STATUS] = [NSNumber numberWithInt:status];
//sanity check
if(STATUS_SUCCESS != status)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: SecStaticCodeCreateWithPath() failed on %@ with %d", path, status);
//bail
goto bail;
}
//check signature
status = SecStaticCodeCheckValidityWithErrors(staticCode, kSecCSDoNotValidateResources, NULL, NULL);
//(re)save signature status
signingStatus[KEY_SIGNATURE_STATUS] = [NSNumber numberWithInt:status];
//if file is signed
// ->grab signing authorities
if(STATUS_SUCCESS == status)
{
//grab signing authorities
status = SecCodeCopySigningInformation(staticCode, kSecCSSigningInformation, &signingInformation);
//sanity check
if(STATUS_SUCCESS != status)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: SecCodeCopySigningInformation() failed on %@ with %d", path, status);
//bail
goto bail;
}
}
//init array for certificate names
signingStatus[KEY_SIGNING_AUTHORITIES] = [NSMutableArray array];
//get cert chain
certificateChain = [(__bridge NSDictionary*)signingInformation objectForKey:(__bridge NSString*)kSecCodeInfoCertificates];
//handle case there is no cert chain
// ->adhoc? (/Library/Frameworks/OpenVPN.framework/Versions/Current/bin/openvpn-service)
if(0 == certificateChain.count)
{
//set
[signingStatus[KEY_SIGNING_AUTHORITIES] addObject:@"signed, but no signing authorities (adhoc?)"];
}
//got cert chain
// ->add each to list
else
{
//get name of all certs
for(index = 0; index < certificateChain.count; index++)
{
//extract cert
certificate = (__bridge SecCertificateRef)([certificateChain objectAtIndex:index]);
//get common name
status = SecCertificateCopyCommonName(certificate, &commonName);
//skip ones that error out
if( (STATUS_SUCCESS != status) ||
(NULL == commonName))
{
//skip
continue;
}
//save
[signingStatus[KEY_SIGNING_AUTHORITIES] addObject:(__bridge NSString*)commonName];
//release name
CFRelease(commonName);
}
}
//bail
bail:
//free signing info
if(NULL != signingInformation)
{
//free
CFRelease(signingInformation);
}
//free static code
if(NULL != staticCode)
{
//free
CFRelease(staticCode);
}
return signingStatus;
}
//determine if a file is signed by Apple proper
BOOL isApple(NSString* path)
{
//flag
BOOL isApple = NO;
//code
SecStaticCodeRef staticCode = NULL;
//signing reqs
SecRequirementRef requirementRef = NULL;
//status
OSStatus status = -1;
//create static code
status = SecStaticCodeCreateWithPath((__bridge CFURLRef)([NSURL fileURLWithPath:path]), kSecCSDefaultFlags, &staticCode);
if(STATUS_SUCCESS != status)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: SecStaticCodeCreateWithPath() failed on %@ with %d", path, status);
//bail
goto bail;
}
//create req string w/ 'anchor apple'
// (3rd party: 'anchor apple generic')
status = SecRequirementCreateWithString(CFSTR("anchor apple"), kSecCSDefaultFlags, &requirementRef);
if( (STATUS_SUCCESS != status) ||
(requirementRef == NULL) )
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: SecRequirementCreateWithString() failed on %@ with %d", path, status);
//bail
goto bail;
}
//check if file is signed by apple
// ->i.e. it conforms to req string
status = SecStaticCodeCheckValidity(staticCode, kSecCSDefaultFlags, requirementRef);
if(STATUS_SUCCESS != status)
{
//bail
// ->just means app isn't signed by apple
goto bail;
}
//ok, happy (SecStaticCodeCheckValidity() didn't fail)
// ->file is signed by Apple
isApple = YES;
//bail
bail:
//free req reference
if(NULL != requirementRef)
{
//free
CFRelease(requirementRef);
}
//free static code
if(NULL != staticCode)
{
//free
CFRelease(staticCode);
}
return isApple;
}
//get an icon for a process
// ->for apps, this will be app's icon, otherwise just a standard system one
NSImage* getIconForBinary(NSString* binary, NSBundle* bundle)
{
//icon's file name
NSString* iconFile = nil;
//icon's path
NSString* iconPath = nil;
//icon's path extension
NSString* iconExtension = nil;
//system's document icon
NSData* documentIcon = nil;
//icon
NSImage* icon = nil;
//since path is always full path to binary
// ->manaully try to find & load bundle (for .apps)
if(nil == bundle)
{
//load bundle
bundle = findAppBundle(binary);
}
//for app's
// ->extract their icon
if(nil != bundle)
{
//get file
iconFile = bundle.infoDictionary[@"CFBundleIconFile"];
//get path extension
iconExtension = [iconFile pathExtension];
//if its blank (i.e. not specified)
// ->go with 'icns'
if(YES == [iconExtension isEqualTo:@""])
{
//set type
iconExtension = @"icns";
}
//set full path
iconPath = [bundle pathForResource:[iconFile stringByDeletingPathExtension] ofType:iconExtension];
//load it
icon = [[NSImage alloc] initWithContentsOfFile:iconPath];
}
//process is not an app or couldn't get icon
// ->try to get it via shared workspace
if( (nil == bundle) ||
(nil == icon) )
{
//extract icon
icon = [[NSWorkspace sharedWorkspace] iconForFile:binary];
//load system document icon
documentIcon = [[[NSWorkspace sharedWorkspace] iconForFileType:
NSFileTypeForHFSTypeCode(kGenericDocumentIcon)] TIFFRepresentation];
//if 'iconForFile' method doesn't find and icon, it returns the system 'document' icon
// ->the system 'applicaiton' icon seems more applicable, so use that here...
if(YES == [[icon TIFFRepresentation] isEqual:documentIcon])
{
//set icon to system 'applicaiton' icon
icon = [[NSWorkspace sharedWorkspace]
iconForFileType: NSFileTypeForHFSTypeCode(kGenericApplicationIcon)];
}
//'iconForFileType' returns small icons
// ->so set size to 64
[icon setSize:NSMakeSize(64, 64)];
}
return icon;
}
//if string is too long to fit into a the text field
// ->truncate and insert ellipises before /file
NSString* stringByTruncatingString(NSTextField* textField, NSString* string, float width)
{
//trucated string (with ellipis)
NSMutableString *truncatedString = nil;
//offset of last '/'
NSRange lastSlash = {};
//make copy of string
truncatedString = [string mutableCopy];
//sanity check
// ->make sure string needs truncating
if([string sizeWithAttributes: @{NSFontAttributeName: textField.font}].width < width)
{
//bail
goto bail;
}
//find instance of last '/
lastSlash = [string rangeOfString:@"/" options:NSBackwardsSearch];
//sanity check
// ->make sure found a '/'
if(NSNotFound == lastSlash.location)
{
//bail
goto bail;
}
//account for added ellipsis
width -= [ELLIPIS sizeWithAttributes: @{NSFontAttributeName: textField.font}].width;
//delete characters until string will fit into specified size
while([truncatedString sizeWithAttributes: @{NSFontAttributeName: textField.font}].width > width)
{
//sanity check
// ->make sure we don't run off the front
if(0 == lastSlash.location)
{
//bail
goto bail;
}
//skip back
lastSlash.location--;
//delete char
[truncatedString deleteCharactersInRange:lastSlash];
}
//set length of range
lastSlash.length = ELLIPIS.length;
//back up location
lastSlash.location -= ELLIPIS.length;
//add in ellipis
[truncatedString replaceCharactersInRange:lastSlash withString:ELLIPIS];
//bail
bail:
return truncatedString;
}
//given a directory and a filter predicate
// ->return all matches
NSArray* directoryContents(NSString* directory, NSString* predicate)
{
//(unfiltered) directory contents
NSArray* directoryContents = nil;
//matches
NSArray* matches = nil;
//get (unfiltered) directory contents
directoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directory error:nil];
//filter out matches
if(nil != predicate)
{
//filter
matches = [directoryContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:predicate]];
}
//no need to filter
else
{
//no filter
matches = directoryContents;
}
return matches;
}
//given a path to binary
// parse it back up to find app's bundle
NSBundle* findAppBundle(NSString* binaryPath)
{
//app's bundle
NSBundle* appBundle = nil;
//app's path
NSString* appPath = nil;
//first just try full path
appPath = binaryPath;
//try to find the app's bundle/info dictionary
do
{
//try to load app's bundle
appBundle = [NSBundle bundleWithPath:appPath];
//check for match
// ->binary path's match
if( (nil != appBundle) &&
(YES == [appBundle.executablePath isEqualToString:binaryPath]))
{
//all done
break;
}
//always unset bundle var since it's being returned
// ->and at this point, its not a match
appBundle = nil;
//remove last part
// ->will try this next
appPath = [appPath stringByDeletingLastPathComponent];
//scan until we get to root
// ->of course, loop will be exited if app info dictionary is found/loaded
} while( (nil != appPath) &&
(YES != [appPath isEqualToString:@"/"]) &&
(YES != [appPath isEqualToString:@""]) );
return appBundle;
}
//hash a file
// ->md5 and sha1
NSDictionary* hashFile(NSString* filePath)
{
//file hashes
NSDictionary* hashes = nil;
//file's contents
NSData* fileContents = nil;
//hash digest (md5)
uint8_t digestMD5[CC_MD5_DIGEST_LENGTH] = {0};
//md5 hash as string
NSMutableString* md5 = nil;
//hash digest (sha1)
uint8_t digestSHA1[CC_SHA1_DIGEST_LENGTH] = {0};
//sha1 hash as string
NSMutableString* sha1 = nil;
//index var
NSUInteger index = 0;
//init md5 hash string
md5 = [NSMutableString string];
//init sha1 hash string
sha1 = [NSMutableString string];
//load file
if(nil == (fileContents = [NSData dataWithContentsOfFile:filePath]))
{
//err msg
//TODO: re-enable
//NSLog(@"OBJECTIVE-SEE ERROR: couldn't load %@ to hash", filePath);
//bail
goto bail;
}
//md5 it
CC_MD5(fileContents.bytes, (unsigned int)fileContents.length, digestMD5);
//convert to NSString
// ->iterate over each bytes in computed digest and format
for(index=0; index < CC_MD5_DIGEST_LENGTH; index++)
{
//format/append
[md5 appendFormat:@"%02lX", (unsigned long)digestMD5[index]];
}
//sha1 it
CC_SHA1(fileContents.bytes, (unsigned int)fileContents.length, digestSHA1);
//convert to NSString
// ->iterate over each bytes in computed digest and format
for(index=0; index < CC_SHA1_DIGEST_LENGTH; index++)
{
//format/append
[sha1 appendFormat:@"%02lX", (unsigned long)digestSHA1[index]];
}
//init hash dictionary
hashes = @{KEY_HASH_MD5: md5, KEY_HASH_SHA1: sha1};
//bail
bail:
return hashes;
}
//get app's version
// ->extracted from Info.plist
NSString* getAppVersion()
{
//read and return 'CFBundleVersion' from bundle
return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
}
//convert a textview to a clickable hyperlink
void makeTextViewHyperlink(NSTextField* textField, NSURL* url)
{
//hyperlink
NSMutableAttributedString *hyperlinkString = nil;
//range
NSRange range = {0};
//init hyper link
hyperlinkString = [[NSMutableAttributedString alloc] initWithString:textField.stringValue];
//init range
range = NSMakeRange(0, [hyperlinkString length]);
//start editing
[hyperlinkString beginEditing];
//add url
[hyperlinkString addAttribute:NSLinkAttributeName value:url range:range];
//make it blue
[hyperlinkString addAttribute:NSForegroundColorAttributeName value:[NSColor blueColor] range:NSMakeRange(0, [hyperlinkString length])];
//underline
[hyperlinkString addAttribute:
NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:NSSingleUnderlineStyle] range:NSMakeRange(0, [hyperlinkString length])];
//done editing
[hyperlinkString endEditing];
//set text
[textField setAttributedStringValue:hyperlinkString];
return;
}
//set the color of an attributed string
NSMutableAttributedString* setStringColor(NSAttributedString* string, NSColor* color)
{
//colored string
NSMutableAttributedString *coloredString = nil;
//alloc/init colored string from existing one
coloredString = [[NSMutableAttributedString alloc] initWithAttributedString:string];
//set color
[coloredString addAttribute:NSForegroundColorAttributeName value:color range:NSMakeRange(0, [coloredString length])];
return coloredString;
}
//exec a process and grab it's output
NSData* execTask(NSString* binaryPath, NSArray* arguments)
{
//task
NSTask *task = nil;
//output pipe
NSPipe *outPipe = nil;
//read handle
NSFileHandle* readHandle = nil;
//output
NSMutableData *output = nil;
//init task
task = [NSTask new];
//init output pipe
outPipe = [NSPipe pipe];
//init read handle
readHandle = [outPipe fileHandleForReading];
//init output buffer
output = [NSMutableData data];
//set task's path
[task setLaunchPath:binaryPath];
//set task's args
[task setArguments:arguments];
//set task's output
[task setStandardOutput:outPipe];
//launch the task
[task launch];
//read in output
while(YES == [task isRunning])
{
//accumulate output
[output appendData:[readHandle readDataToEndOfFile]];
}
//grab any left over data
[output appendData:[readHandle readDataToEndOfFile]];
//return output as string
return output;
}
//wait until a window is non nil
// ->then make it modal
void makeModal(NSWindowController* windowController)
{
//wait up to 1 second window to be non-nil
// ->then make modal
for(int i=0; i<20; i++)
{
//can make it modal once we have a window
if(nil != windowController.window)
{
//make modal on main thread
dispatch_sync(dispatch_get_main_queue(), ^{
//modal
[[NSApplication sharedApplication] runModalForWindow:windowController.window];
});
//all done
break;
}
//nap
[NSThread sleepForTimeInterval:0.05f];
}//until 1 second
return;
}
//given a pid, get its parent (ppid)
pid_t getParentID(int pid)
{
//parent id
pid_t parentID = -1;
//kinfo_proc struct
struct kinfo_proc processStruct = {0};
//size
size_t procBufferSize = sizeof(processStruct);
//mib
const u_int mibLength = 4;
//syscall result
int sysctlResult = -1;
//init mib
int mib[mibLength] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
//make syscall
sysctlResult = sysctl(mib, mibLength, &processStruct, &procBufferSize, NULL, 0);
//check if got ppid
if( (STATUS_SUCCESS == sysctlResult) &&
(0 != procBufferSize) )
{
//save ppid
parentID = processStruct.kp_eproc.e_ppid;
}
return parentID;
}
//get path to XPC service
NSString* getPath2XPC()
{
//path to XPC service
NSString* xpcService = nil;
//build path
xpcService = [NSString stringWithFormat:@"%@/Contents/XPCServices/%@", [[NSBundle mainBundle] bundlePath], XPC_SERVICE];
//make sure its there
if(YES != [[NSFileManager defaultManager] fileExistsAtPath:xpcService])
{
//nope
// ->nil out
xpcService = nil;
}
return xpcService;
}
//get path to kernel
NSString* path2Kernel()
{
//kernel path
NSString* kernel;
//check Yosemite's location first
if(YES == [[NSFileManager defaultManager] fileExistsAtPath:KERNEL_YOSEMITE])
{
//set
kernel = KERNEL_YOSEMITE;
}
//go w/ older location
else
{
//set
kernel = KERNEL_PRE_YOSEMITE;
}
return kernel;
}
//determine if process is (still) alive
BOOL isAlive(pid_t targetPID)
{
//flag
BOOL isAlive = YES;
//try 'kill' with 0
// ->no harm done, but will fail with 'ESRCH' if process is dead!
if( (0 != kill(targetPID, 0)) &&
(ESRCH == errno) )
{
isAlive = NO;
}
//NSLog(@"killing %d: %d/%d", targetPID, result, errno);
return isAlive;
}
+39
View File
@@ -0,0 +1,39 @@
//
// vtButton.h
// KnockKnock
//
// Created by Patrick Wardle on 3/26/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "Binary.h"
#import <Cocoa/Cocoa.h>
//#import "ItemTableController.h"
@class TaskTableController;
@interface VTButton : NSButton
{
}
//properties
//parent object
@property(assign)TaskTableController *delegate;
//File object
@property(nonatomic, retain)Binary* fileObj;
//button's row index
//flag indicating press
@property BOOL mouseDown;
//flag indicating exit
@property BOOL mouseExit;
@end
+206
View File
@@ -0,0 +1,206 @@
//
// vtButton.m
// KnockKnock
//
// Created by Patrick Wardle on 3/26/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "Consts.h"
#import "VTButton.h"
#import "Utilities.h"
#import "TaskTableController.h"
@implementation VTButton
@synthesize fileObj;
@synthesize delegate;
@synthesize mouseDown;
@synthesize mouseExit;
//automatically invoked
// ->create tracking area for mouse events
-(void)awakeFromNib
{
//create the mouse-over tracking area
[self createTrackingArea];
}
//create the mouse-over tracking area
-(void)createTrackingArea
{
//tracking area
NSTrackingArea *trackingArea = nil;
//alloc/init tracking area
trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:(NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
//add tracking area
[self addTrackingArea:trackingArea];
return;
}
//automatically invoked when mouse-down occurs
// ->set color to light gray or light red
-(void)mouseDown:(NSEvent *)theEvent;
{
//mouse down/over color
NSColor* color = nil;
//set flag
self.mouseDown = YES;
//flagged files
// ->make em red!
if( (nil != self.fileObj.vtInfo) &&
(0 != [self.fileObj.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
{
//set color (light red)
color = [NSColor colorWithCalibratedRed:(255/255.0f) green:(1.0/255.0f) blue:(1.0/255.0f) alpha:0.5];
}
//non-flagged files
// ->just gray
else
{
//gray
color = [NSColor lightGrayColor];
}
//set string
[self setAttributedTitle:setStringColor(self.attributedTitle, color)];
return;
}
//automatically invoked when mouse-up occurs
// ->reset color to gray or red and trigger mouse click logic (if necessary)
-(void)mouseUp:(NSEvent *)theEvent;
{
//mouse up color
NSColor* color = nil;
//shoud treat at click?
// ->mouse up inside in non-disabled button
if( (YES == self.isEnabled) &&
(YES != self.mouseExit) )
{
//show virus total window
[self.delegate performSelector:@selector(showVTInfo:) withObject:self];
}
//reset flag
self.mouseDown = NO;
//flagged files
// ->make em red!
if( (nil != self.fileObj.vtInfo) &&
(0 != [self.fileObj.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
{
//set color (light red)
color = [NSColor redColor];
}
//non-flagged files
// ->just black
else
{
//gray
color = [NSColor blackColor];
}
//set string
[self setAttributedTitle:setStringColor(self.attributedTitle, color)];
return;
}
//automatically invoked when mouse enters
// ->set mouse over color
-(void)mouseEntered:(NSEvent*)theEvent
{
//mouse entered color
NSColor* color = nil;
//set flag
self.mouseExit = NO;
//flagged files
// ->make em red!
if( (nil != self.fileObj.vtInfo) &&
(0 != [self.fileObj.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
{
//set color (lightish red)
color = [NSColor colorWithCalibratedRed:(255/255.0f) green:(1.0/255.0f) blue:(1.0/255.0f) alpha:0.66];
}
//non-flagged files
// ->just black
else
{
//gray
color = [NSColor grayColor];
}
//set string
[self setAttributedTitle:setStringColor(self.attributedTitle, color)];
return;
}
//automatically invoked when mouse exits
// ->reset color to black or red
-(void)mouseExited:(NSEvent*)theEvent
{
//mouse exit color
NSColor* color = nil;
//set flag
self.mouseExit = YES;
//check if mouse is down
// ->set color to gray/lightish red
if(YES == self.mouseDown)
{
//flagged files
// ->make em red!
if( (nil != self.fileObj.vtInfo) &&
(0 != [self.fileObj.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
{
//set color (lightish red)
color = [NSColor colorWithCalibratedRed:(255/255.0f) green:(1.0/255.0f) blue:(1.0/255.0f) alpha:0.66];
}
//non-flagged files
// ->just black
else
{
//gray
color = [NSColor grayColor];
}
}
//mouse is up
// ->reset color to black/red
else
{
//flagged files
// ->make em red!
if( (nil != self.fileObj.vtInfo) &&
(0 != [self.fileObj.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
{
//set color (light red)
color = [NSColor redColor];
}
//non-flagged files
// ->just black
else
{
//gray
color = [NSColor blackColor];
}
}
//set string
[self setAttributedTitle:setStringColor(self.attributedTitle, color)];
return;
}
@end
+62
View File
@@ -0,0 +1,62 @@
//
// VTInfoWindow.h
// KnockKnock
//
// Created by Patrick Wardle on 3/29/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
@class File;
@class HyperlinkTextField;
#import <Cocoa/Cocoa.h>
@interface VTInfoWindowController : NSWindowController
{
}
/* PROPERTIES */
//window controller
@property(nonatomic, strong)VTInfoWindowController *windowController;
//file object
@property(nonatomic, retain)Binary* fileObj;
//row index
@property NSUInteger rowIndex;
//properties in window
@property (weak) IBOutlet NSTextField *unknownFile;
@property (weak) IBOutlet NSTextField *fileNameLabel;
@property (weak) IBOutlet HyperlinkTextField *fileName;
@property (weak) IBOutlet NSTextField *detectionRatioLabel;
@property (weak) IBOutlet NSTextField *detectionRatio;
@property (weak) IBOutlet NSTextField *analysisURLLabel;
@property (weak) IBOutlet NSTextField *analysisURL;
@property (weak) IBOutlet NSButton *closeButton;
@property (weak) IBOutlet NSButton *submitButton;
@property (weak) IBOutlet NSProgressIndicator *progressIndicator;
@property (strong) IBOutlet NSView *overlayView;
@property (weak) IBOutlet NSTextField *statusMsg;
/* METHODS */
//init method
// ->save item and load nib
-(id)initWithItem:(File*)selectedItem rowIndex:(NSUInteger)itemRowIndex;
//'submit' button handler
-(IBAction)vtButtonHandler:(id)sender;
//'close' button handler
-(IBAction)closeButtonHandler:(id)sender;
@end
+444
View File
@@ -0,0 +1,444 @@
//
// VTInfoWindow.m
// KnockKnock
//
// Created by Patrick Wardle on 3/29/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "File.h"
#import "Consts.h"
#import "Utilities.h"
#import "VirusTotal.h"
#import "AppDelegate.h"
#import "VTInfoWindowController.h"
#import "3rdParty/HyperlinkTextField.h"
#import <QuartzCore/QuartzCore.h>
@interface VTInfoWindowController ()
@end
@implementation VTInfoWindowController
@synthesize rowIndex;
@synthesize windowController;
//init method
// ->save item and load nib
-(id)initWithItem:(File*)selectedItem rowIndex:(NSUInteger)itemRowIndex
{
self = [super init];
if(nil != self)
{
//load nib
self.windowController = [[VTInfoWindowController alloc] initWithWindowNibName:@"VTInfoWindow"];
//save item
self.windowController.fileObj = selectedItem;
//save row index
self.windowController.rowIndex = itemRowIndex;
}
return self;
}
//automatically invoked
// ->make it white
-(void)windowDidLoad
{
//super
[super windowDidLoad];
//make it modal
//[[NSApplication sharedApplication] runModalForWindow:self.window];
//make white
[self.window setBackgroundColor: NSColor.whiteColor];
//make close button selected
[self.window makeFirstResponder:self.closeButton];
return;
}
//automatically called when nib is loaded
// ->save self into iVar, and center window
-(void)awakeFromNib
{
//configure UI
[self configure];
//center
[self.window center];
}
//configure window
// ->add item's attributes (name, path, etc.)
-(void)configure
{
//flag
BOOL isKnown = NO;
//detection ratio
NSString* vtDetectionRatio = nil;
//color
NSColor* textColor = nil;
//get status
if(nil != self.fileObj.vtInfo[VT_RESULTS_URL])
{
//known
isKnown = YES;
}
//file status (known/unknown)
if(YES == isKnown)
{
//default color to black
textColor = [NSColor blackColor];
//set color to red if its flagged
if(0 != [self.fileObj.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue])
{
//red
textColor = [NSColor redColor];
}
//generate detection ratio
vtDetectionRatio = [NSString stringWithFormat:@"%lu/%lu", (unsigned long)[self.fileObj.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue], (unsigned long)[self.fileObj.vtInfo[VT_RESULTS_TOTAL] unsignedIntegerValue]];
//set name
[self.fileName setStringValue:self.fileObj.name];
//set color
self.fileName.textColor = textColor;
//detection ratio
[self.detectionRatio setStringValue:vtDetectionRatio];
//set color
self.detectionRatio.textColor = textColor;
//analysis url
[self.analysisURL setStringValue:@"VirusTotal report"];
//make analyis url a hyperlink
makeTextViewHyperlink(self.analysisURL, [NSURL URLWithString:self.fileObj.vtInfo[VT_RESULTS_URL]]);
//set 'submit' button text to 'rescan'
self.submitButton.title = @"rescan?";
}
//unknown file
else
{
//hide file name label
self.fileNameLabel.hidden = YES;
//hide file name
self.fileName.hidden = YES;
//hide detection ratio label
self.detectionRatioLabel.hidden = YES;
//hide detection ratio
self.detectionRatio.hidden = YES;
//hide analysis url label
self.analysisURLLabel.hidden = YES;
//hide analysis url
self.analysisURL.hidden = YES;
//set unknown file msg
[self.unknownFile setStringValue:[NSString stringWithFormat:@"no results found for '%@'", self.fileObj.name]];
//show 'unknown file' msg
self.unknownFile.hidden = NO;
}
return;
}
//automatically invoked when user clicks 'close'
// ->just close window
-(IBAction)closeButtonHandler:(id)sender
{
//close
[self.window close];
return;
}
//automatically invoked when window is closing
// ->tell OS that we are done with window so it can (now) be freed
-(void)windowWillClose:(NSNotification *)notification
{
//make un-modal
//[[NSApplication sharedApplication] stopModal];
//stop spinner
// ->will hide too
[self.progressIndicator stopAnimation:nil];
return;
}
//automatically invoked when user clicks 'rescan'/'submit'
// ->rescan or upload to VT!
-(IBAction)vtButtonHandler:(id)sender
{
//VT object
VirusTotal* vtObj = nil;
//result(s) from VT
__block NSDictionary* result = nil;
//analyis URL
NSMutableAttributedString* hyperlinkString = nil;
//VT scan ID
__block NSString* scanID = nil;
//alloc/init VT obj
vtObj = [[VirusTotal alloc] init];
//disable button
((NSButton*)sender).enabled = NO;
//disable close button
self.closeButton.enabled = NO;
//get current string
hyperlinkString = [self.analysisURL.attributedStringValue mutableCopy];
//start editing
[hyperlinkString beginEditing];
//remove url/link
[hyperlinkString removeAttribute:NSLinkAttributeName range:NSMakeRange(0, [hyperlinkString length])];
//done editing
[hyperlinkString endEditing];
//set text
// ->will look the same, but the URL will be disabled!
[self.analysisURL setAttributedStringValue:hyperlinkString];
//pre-req
[self.overlayView setWantsLayer:YES];
//set overlay's view color to black
self.overlayView.layer.backgroundColor = [NSColor whiteColor].CGColor;
//make it semi-transparent
self.overlayView.alphaValue = 0.85;
//show it
self.overlayView.hidden = NO;
//show spinner
self.progressIndicator.hidden = NO;
//animate it
[self.progressIndicator startAnimation:nil];
//rescan file?
if(YES == [((NSButton*)sender).title isEqualToString:@"rescan?"])
{
//set status msg
[self.statusMsg setStringValue:[NSString stringWithFormat:@"submitting re-scan request for %@", self.fileObj.name]];
//show status msg
self.statusMsg.hidden = NO;
//submit rescan request in background
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//make request to VT
result = [vtObj reScan:self.fileObj];
//got result
// ->update UI and launch browswer to show report
if(nil != result)
{
//grab scan ID
// ->need this for (re)queries
scanID = result[VT_RESULTS_SCANID];
/*
//if file was flagged
// ->remove it from list of plugin's flagged
if(0 != [self.fileObj.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue])
{
//sync
// ->since array will be reset if user clicks 'stop' scan
@synchronized(self.fileObj.plugin.flaggedItems)
{
//remove
[self.fileObj.plugin.flaggedItems removeObject:self.fileObj];
}
}
*/
//remove file's VT info (since it'd now out of date)
self.fileObj.vtInfo = nil;
//with a scan id can re-query VT
// ->will update VT button in UI once results are retrieved
if(nil != scanID)
{
//kick off task to re-query VT
// ->wait 60 seconds though to give VT servers some time to process
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 60 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[vtObj getInfoForItem:self.fileObj scanID:scanID rowIndex:self.rowIndex];
});
}
//ask app delegate to update item in table
// ->will change the item's VT status to ... (pending)
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) itemProcessed:self.fileObj rowIndex:self.rowIndex];
//nap so user can see msg 'submitting' msg
[NSThread sleepForTimeInterval:0.5];
//update status msg
dispatch_sync(dispatch_get_main_queue(), ^{
//update
[self.statusMsg setStringValue:@"request submitted"];
});
//nap so user can see msg
[NSThread sleepForTimeInterval:0.5];
//launch browser to show rew report
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:result[@"permalink"]]];
//wait to browser is up and happy
[NSThread sleepForTimeInterval:0.5];
//close window
dispatch_sync(dispatch_get_main_queue(), ^{
//close
[self.window close];
});
}
//error
else
{
//show error msg
dispatch_async(dispatch_get_main_queue(), ^{
//update status msg
[self.statusMsg setStringValue:@"failed to submit request :("];
//stop activity indicator
[self.progressIndicator stopAnimation:nil];
});
}
});
}
//submit file
else
{
//set status msg
[self.statusMsg setStringValue:[NSString stringWithFormat:@"submitting %@", self.fileObj.name]];
//show status msg
self.statusMsg.hidden = NO;
//submit rescan request in background
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//submit file to VT
result = [vtObj submit:self.fileObj];
// ->need this for (re)queries
scanID = result[VT_RESULTS_SCANID];
//reset file's VT info
self.fileObj.vtInfo = nil;
//with a scan id can query VT
// ->will update VT button in UI once results are retrieved
if(nil != scanID)
{
//kick off task to re-query VT
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 60 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[vtObj getInfoForItem:self.fileObj scanID:scanID rowIndex:self.rowIndex];
});
}
//got response
// ->update UI and launch browswer to show report
if(nil != result)
{
//ask app delegate to update item in table
// ->will change the item's VT status to ... (pending)
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) itemProcessed:self.fileObj rowIndex:self.rowIndex];
//update status msg
dispatch_sync(dispatch_get_main_queue(), ^{
//update
[self.statusMsg setStringValue:@"file submitted"];
});
//nap so user can see msg
[NSThread sleepForTimeInterval:0.5];
//launch browser to show rew report
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:result[@"permalink"]]];
//wait to browser is up and happy
[NSThread sleepForTimeInterval:0.5];
//close window
dispatch_sync(dispatch_get_main_queue(), ^{
//close
[self.window close];
});
}//got result
//error
else
{
//show error msg
dispatch_sync(dispatch_get_main_queue(), ^{
//update status msg
[self.statusMsg setStringValue:@"failed to submit request :("];
//stop activity indicator
[self.progressIndicator stopAnimation:nil];
});
}
});
}
return;
}
@end
+39
View File
@@ -0,0 +1,39 @@
//
// VirusTotal.h
// KnockKnock
//
// Created by Patrick Wardle on 3/8/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface VirusTotal : NSObject
{
}
/* METHODS */
//thread function
// ->runs in the background to get virus total info about a plugin's items
//-(void)getInfo:(PluginBase*)plugin;
//make the (POST)query to VT
-(NSDictionary*)postRequest:(NSURL*)url parameters:(id)params;
//submit a file to VT
-(NSDictionary*)submit:(File*)fileObj;
//submit a rescan request
-(NSDictionary*)reScan:(File*)fileObj;
//process results
// ->updates items (found, detection ratio, etc)
-(void)processResults:(NSArray*)items results:(NSDictionary*)results;
//get info for a single item
// ->will callback into AppDelegate to reload plugin
-(void)getInfoForItem:(File*)fileObj scanID:(NSString*)scanID rowIndex:(NSUInteger)rowIndex;
@end
+541
View File
@@ -0,0 +1,541 @@
//
// VirusTotal.m
// KnockKnock
//
// Created by Patrick Wardle on 3/8/15.
// Copyright (c) 2015 Objective-See. All rights reserved.
//
#import "File.h"
#import "Consts.h"
#import "ItemBase.h"
#import "VirusTotal.h"
#import "AppDelegate.h"
@implementation VirusTotal
/*
//thread function
// ->runs in the background to get virus total info about a plugin's items
-(void)getInfo:(PluginBase*)plugin
{
//plugin file items
// ->in dictionary w/ SHA1 hash as key
NSMutableDictionary* uniqueItems = nil;
//File object
File* item = nil;
//item data
NSMutableDictionary* itemData = nil;
//items
NSMutableArray* items = nil;
//VT query URL
NSURL* queryURL = nil;
//results
NSDictionary* results = nil;
//alloc dictionary for plugin file items
uniqueItems = [NSMutableDictionary dictionary];
//alloc list for items
items = [NSMutableArray array];
//init query URL
queryURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", VT_QUERY_URL, VT_API_KEY]];
//sync
// ->since array will be reset if user clicks 'stop' scan
@synchronized(plugin.allItems)
{
//place all plugin file items into dictionary
// ->key: hash, filter's out dups for queries
for(ItemBase* item in plugin.allItems)
{
//skip non-file items
if(YES != [item isKindOfClass:[File class]])
{
//skip
continue;
}
//skip item's without hashes
// ...not sure how this could ever happen
if(nil == ((File*)item).hashes[KEY_HASH_SHA1])
{
//skip
continue;
}
//add item
uniqueItems[((File*)item).hashes[KEY_HASH_SHA1]] = item;
}
}//sync
//iterate over all hashes
// ->create item dictionary (JSON), and add it to list
for(NSString* itemKey in uniqueItems)
{
//alloc item data
itemData = [NSMutableDictionary dictionary];
//exit if thread was cancelled
// ->i.e. user pressed 'stop' scan
if(YES == [[NSThread currentThread] isCancelled])
{
//exit
[NSThread exit];
}
//extract item
item = uniqueItems[itemKey];
//auto start location
itemData[@"autostart_location"] = plugin.name;
//set item name
itemData[@"autostart_entry"] = item.name;
//set item path
itemData[@"image_path"] = item.path;
//set hash
itemData[@"hash"] = item.hashes[KEY_HASH_SHA1];
//set creation times
itemData[@"creation_datetime"] = [item.attributes.fileCreationDate description];
//add item info to list
[items addObject:itemData];
//less then 25 items
// ->just keep collecting items
if(VT_MAX_QUERY_COUNT != items.count)
{
//next
continue;
}
//make query to VT
results = [self postRequest:queryURL parameters:items];
if(nil != results)
{
//process results
[self processResults:plugin.allItems results:results];
}
//remove all items
// ->since they've been processed
[items removeAllObjects];
}
//process any remaining items
if(0 != items.count)
{
//query virus total
results = [self postRequest:queryURL parameters:items];
if(nil != results)
{
//process results
[self processResults:plugin.allItems results:results];
}
}
//exit if thread was cancelled
// ->i.e. user pressed 'stop' scan
if(YES == [[NSThread currentThread] isCancelled])
{
//exit
[NSThread exit];
}
//tell UI all plugin's items have all be processed
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) itemsProcessed:plugin];
return;
}
*/
//get VT info for a single item
// ->will then callback into AppDelegate to reload item in UI
-(void)getInfoForItem:(Binary*)fileObj scanID:(NSString*)scanID rowIndex:(NSUInteger)rowIndex
{
//VT query URL
NSURL* queryURL = nil;
//results
NSDictionary* results = nil;
//init query URL
queryURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@?apikey=%@&resource=%@", VT_REQUERY_URL, VT_API_KEY, scanID]];
//make queries until response is recieved
while(YES)
{
//make query to VT
results = [self postRequest:queryURL parameters:nil];
//check if scan is complete
if( (nil != results) &&
(1 == [results[VT_RESULTS_RESPONSE] integerValue]) )
{
//save result
fileObj.vtInfo = results;
//if its flagged save in File's plugin
if(0 != [results[VT_RESULTS_POSITIVES] unsignedIntegerValue])
{
/*
//sync
// ->since array will be reset if user clicks 'stop' scan
@synchronized(fileObj.plugin.flaggedItems)
{
//save
[fileObj.plugin.flaggedItems addObject:fileObj];
}
*/
}
//callback up into UI to reload item
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) itemProcessed:fileObj rowIndex:rowIndex];
//exit loop
break;
}
//nap
[NSThread sleepForTimeInterval:60.0f];
}
return;
}
//make the (POST)query to VT
-(NSDictionary*)postRequest:(NSURL*)url parameters:(id)params
{
//results
NSDictionary* results = nil;
//request
NSMutableURLRequest *request = nil;
//post data
// ->JSON'd items
NSData* postData = nil;
//error var
NSError* error = nil;
//data from VT
NSData* vtData = nil;
//response (HTTP) from VT
NSURLResponse* httpResponse = nil;
//alloc/init request
request = [[NSMutableURLRequest alloc] initWithURL:url];
//set user agent
[request setValue:VT_USER_AGENT forHTTPHeaderField:@"User-Agent"];
//serialize JSON
if(nil != params)
{
//convert items to JSON'd data for POST request
// ->wrap since we are serializing JSON
@try
{
//convert items
postData = [NSJSONSerialization dataWithJSONObject:params options:kNilOptions error:nil];
if(nil == postData)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: failed to convert request %@ to JSON", postData);
//bail
goto bail;
}
}
//bail on exceptions
@catch(NSException *exception)
{
//bail
goto bail;
}
//set content type
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
//set content length
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[postData length]] forHTTPHeaderField:@"Content-length"];
//add POST data
[request setHTTPBody:postData];
}
//set method type
[request setHTTPMethod:@"POST"];
//send request
// ->synchronous, so will block
vtData = [NSURLConnection sendSynchronousRequest:request returningResponse:&httpResponse error:&error];
//sanity check(s)
if( (nil == vtData) ||
(nil != error) ||
(200 != (long)[(NSHTTPURLResponse *)httpResponse statusCode]) )
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: failed to query VirusTotal (%@, %@)", error, httpResponse);
//bail
goto bail;
}
//serialize response into NSData obj
// ->wrap since we are serializing JSON
@try
{
//serialized
results = [NSJSONSerialization JSONObjectWithData:vtData options:kNilOptions error:nil];
}
//bail on any exceptions
@catch (NSException *exception)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: converting response %@ to JSON threw %@", vtData, exception);
//bail
goto bail;
}
//sanity check
if(nil == results)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: failed to convert response %@ to JSON", vtData);
//bail
goto bail;
}
//bail
bail:
return results;
}
//submit a file to VT
-(NSDictionary*)submit:(File*)fileObj
{
//results
NSDictionary* results = nil;
//submit URL
NSURL* submitURL = nil;
//request
NSMutableURLRequest *request = nil;
//body of request
NSMutableData* body = nil;
//file data
NSData* fileContents = nil;
//error var
NSError* error = nil;
//data from Vt
NSData* vtData = nil;
//response (HTTP) from VT
NSURLResponse* httpResponse = nil;
//init submit URL
submitURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@?apikey=%@&resource=%@", VT_SUBMIT_URL, VT_API_KEY, fileObj.hashes[KEY_HASH_MD5]]];
//init request
request = [[NSMutableURLRequest alloc] initWithURL:submitURL];
//set boundary string
NSString *boundary = @"qqqq___knockknock___qqqq";
//set HTTP method (POST)
[request setHTTPMethod:@"POST"];
//set the HTTP header 'Content-type' to the boundary
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forHTTPHeaderField: @"Content-Type"];
//set HTTP header, 'User-Agent'
[request setValue:VT_USER_AGENT forHTTPHeaderField:@"User-Agent"];
//init body
body = [NSMutableData data];
//load file into memory
fileContents = [NSData dataWithContentsOfFile:fileObj.pathForFinder];
//sanity check
if(nil == fileContents)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: failed to load %@ into memory for submission", fileObj.path);
//bail
goto bail;
}
//append boundary
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
//append 'Content-Disposition' file name, etc
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"\r\n", fileObj.name] dataUsingEncoding:NSUTF8StringEncoding]];
//append 'Content-Type'
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
//append file's contents
[body appendData:fileContents];
//append '\r\n'
[body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
//append final boundary
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
//set body
[request setHTTPBody:body];
//set content length
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[body length]] forHTTPHeaderField:@"Content-length"];
//send request
// ->synchronous, so will block
vtData = [NSURLConnection sendSynchronousRequest:request returningResponse:&httpResponse error:&error];
//sanity check(s)
if( (nil == vtData) ||
(nil != error) ||
(200 != (long)[(NSHTTPURLResponse *)httpResponse statusCode]) )
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: failed to query VirusTotal (%@, %@)", error, httpResponse);
//bail
goto bail;
}
//serialize response into NSData obj
// ->wrap since we are serializing JSON
@try
{
//serialize
results = [NSJSONSerialization JSONObjectWithData:vtData options:kNilOptions error:nil];
}
//bail on any exceptions
@catch (NSException *exception)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: converting response %@ to JSON threw %@", vtData, exception);
//bail
goto bail;
}
//sanity check
if(nil == results)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: failed to convert response %@ to JSON", vtData);
//bail
goto bail;
}
//bail
bail:
return results;
}
//submit a rescan request
-(NSDictionary*)reScan:(File*)fileObj
{
//result data
NSDictionary* result = nil;
//scan url
NSURL* reScanURL = nil;
//init scan url
reScanURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@?apikey=%@&resource=%@", VT_RESCAN_URL, VT_API_KEY, fileObj.hashes[KEY_HASH_MD5]]];
//make request to VT
result = [self postRequest:reScanURL parameters:nil];
if(nil == result)
{
//err msg
NSLog(@"OBJECTIVE-SEE ERROR: failed to re-scan %@", fileObj.name);
//bail
goto bail;
}
//bail
bail:
return result;
}
//process results
// ->save VT info into each File obj and all flagged files
-(void)processResults:(NSArray*)items results:(NSDictionary*)results
{
//process all results
// ->save VT result dictionary into File obj
for(NSDictionary* result in results[VT_RESULTS])
{
//sync
// ->since array will be reset if user clicks 'stop' scan
@synchronized(items)
{
//find all items that match
// ->might be dupes, which is fine
for(Binary* item in items)
{
//for matches, save vt info
if(YES == [result[@"hash"] isEqualToString:item.hashes[KEY_HASH_SHA1]])
{
//save
item.vtInfo = result;
//if its flagged save in File's plugin
if(0 != [result[VT_RESULTS_POSITIVES] unsignedIntegerValue])
{
/*
//sync
// ->since array will be reset if user clicks 'stop' scan
@synchronized(item.plugin.flaggedItems)
{
//save
[item.plugin.flaggedItems addObject:item];
}
*/
}
}
}
}//sync
}
return;
}
@end
+39
View File
@@ -0,0 +1,39 @@
KNOCKKNOCK CHANGELOG
VERSION 1.0.0 (4/23/2015)
initial release
VERSION 1.1.0 (4/24/2015)
added plugin to scan for Authorization Plugins
fixed NSJSONSerialization bug (parsing Google Chrome plugins)
VERSION 1.2.0 (4/25/2015)
added DYLD_INSERT_LIBRARIES plugin
browser extensions plugin now supports enumerating Opera plugins
browser extensions plugin improved to enumerate Google Chrome with multiple profiles
increased timeouts for making a popups modal (to avoid NSInternalInconsistencyException issues)
fixed nil dictionary insertion when processing Safari extensions with missin 'Bundle Identifier'
VERSION 1.2.1 (4/25/2015)
improved DYLD_INSERT_LIBRARIES plugin to report path to applications' Info.plist as string (instead of URL)
fixed issue in DYLD_INSERT_LIBRARIES plugin, where NSInvalidArgumentException would result if enviro var was string
VERSION 1.2.2 (4/28/2015)
browser extensions plugin now supports enumerating extensions in older versions of Safari
improved JSON output & fixed bug when saving JSON when file hash or signature was nil
recompiled with updated/improved (shared) MachO parser
fixed issue where on multiple scans, result popup was not properly updated
improved UI to display item's plist (when applicable) into the item's row
listed items in item table are now selectable
VERSION 1.2.3 (4/30/2015)
improved VirusTotal logic (e.g. when an signed OS file was flagged)
tweaked UI to be more compatible with OS X 10.9
+2
View File
@@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */
+255
View File
@@ -0,0 +1,255 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<development version="5000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="494" id="495"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<menu title="AMainMenu" systemMenu="main" id="29">
<items>
<menuItem title="KnockKnock" id="56">
<menu key="submenu" title="KnockKnock" systemMenu="apple" id="57">
<items>
<menuItem title="About" id="134">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="about:" target="494" id="1Av-a0-4RW"/>
</connections>
</menuItem>
<menuItem title="Preferences" tag="1" id="Cd7-Xq-jnw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="showPreferences:" target="494" id="h1a-NR-0PY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="149">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit" tag="2" keyEquivalent="q" id="136">
<connections>
<action selector="terminate:" target="-3" id="449"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<window allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" showsToolbarButton="NO" animationBehavior="default" id="371">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" unifiedTitleAndToolbar="YES"/>
<rect key="contentRect" x="0.0" y="0.0" width="1353" height="650"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<value key="minSize" type="size" width="1000" height="650"/>
<value key="maxSize" type="size" width="2000" height="650"/>
<view key="contentView" id="372">
<rect key="frame" x="0.0" y="0.0" width="1353" height="650"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<progressIndicator hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" maxValue="100" bezeled="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="839">
<rect key="frame" x="1157" y="-146" width="32" height="32"/>
</progressIndicator>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="745">
<rect key="frame" x="869" y="-137" width="268" height="18"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="status..." id="748">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" red="0.20000000000000001" green="0.67450980392156867" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button ambiguous="YES" misplaced="YES" tag="1002" translatesAutoresizingMaskIntoConstraints="NO" id="HoI-FQ-vTI">
<rect key="frame" x="640" y="4" width="29" height="32"/>
<buttonCell key="cell" type="bevel" bezelStyle="rounded" image="logoApple" imagePosition="only" alignment="center" alternateImage="logoAppleBG" imageScaling="proportionallyDown" inset="2" id="3g8-vm-R7Z">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="logoButtonHandler:" target="494" id="H4C-BT-arE"/>
</connections>
</button>
<segmentedControl verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gtq-gn-VPL">
<rect key="frame" x="465" y="329" width="223" height="24"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="rounded" trackingMode="selectOne" id="DHY-0u-YD7">
<font key="font" metaFont="system"/>
<segments>
<segment label="dylibs" width="73" selected="YES"/>
<segment label="files" width="72" tag="1"/>
<segment label="network" tag="2"/>
</segments>
</segmentedCell>
<connections>
<action selector="selectBottomPaneContent:" target="494" id="CQa-nn-jVf"/>
</connections>
</segmentedControl>
<searchField wantsLayer="YES" verticalHuggingPriority="750" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bNA-gy-9Ta">
<rect key="frame" x="1161" y="330" width="148" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="1yR-lY-9om"/>
<constraint firstAttribute="width" constant="148" id="XYi-Db-Iyc"/>
</constraints>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Filter" usesSingleLineMode="YES" bezelStyle="round" id="bct-8m-iWd">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
<button fixedFrame="YES" tag="1001" translatesAutoresizingMaskIntoConstraints="NO" id="gSG-Nq-plb">
<rect key="frame" x="9" y="4" width="35" height="32"/>
<buttonCell key="cell" type="bevel" bezelStyle="regularSquare" image="settings" imagePosition="overlaps" alignment="center" alternateImage="settingsBG" imageScaling="proportionallyDown" inset="2" id="1TF-i7-mBn">
<behavior key="behavior" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showPreferences:" target="494" id="U3q-gH-jC6"/>
</connections>
</button>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TNF-7q-Loy" userLabel="Top Pane">
<rect key="frame" x="0.0" y="369" width="1353" height="281"/>
</customView>
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E4M-PF-VD0" userLabel="Bottom Pane">
<rect key="frame" x="0.0" y="35" width="1353" height="281"/>
<subviews>
<progressIndicator horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" maxValue="100" bezeled="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="LMT-Bu-FAk">
<rect key="frame" x="660" y="124" width="32" height="32"/>
</progressIndicator>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kIC-ZZ-ldy">
<rect key="frame" x="584" y="106" width="184" height="17"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" allowsUndo="NO" sendsActionOnEndEditing="YES" alignment="center" title="no items found" id="LO4-i6-1es">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</customView>
</subviews>
<constraints>
<constraint firstAttribute="centerX" secondItem="gtq-gn-VPL" secondAttribute="centerX" id="2Nh-NZ-P5p"/>
<constraint firstAttribute="trailing" secondItem="bNA-gy-9Ta" secondAttribute="trailing" constant="12" id="5N8-Ye-mhe"/>
<constraint firstAttribute="centerX" secondItem="HoI-FQ-vTI" secondAttribute="centerX" constant="1" id="EcI-vS-3LG"/>
</constraints>
</view>
<toolbar key="toolbar" implicitIdentifier="EAE4838B-30FD-4B21-8BE5-8564B213BE96" autosavesConfiguration="NO" displayMode="iconAndLabel" sizeMode="regular" id="qEm-Os-zrh">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="NSToolbarShowColorsItem" id="RP7-Aw-wsx"/>
<toolbarItem implicitItemIdentifier="33BA6F3A-71D3-476F-B1FA-72F899CFDCA2" label="Toolbar Item" paletteLabel="Toolbar Item" tag="-1" id="1xB-mk-PMD" customClass="TAAdaptiveSpaceItem"/>
<toolbarItem implicitItemIdentifier="NSToolbarShowFontsItem" id="NU8-Nm-T2R"/>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="eEO-jq-TLG"/>
<toolbarItem implicitItemIdentifier="146A46B5-DE4B-42D4-98E4-7C3A803AC963" label="" paletteLabel="" id="7ph-jg-soj">
<nil key="toolTip"/>
<size key="minSize" width="100" height="28"/>
<size key="maxSize" width="100" height="28"/>
<popUpButton key="view" verticalHuggingPriority="750" id="nRz-eH-T6D">
<rect key="frame" x="0.0" y="0.0" width="100" height="28"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="l3Y-M3-yM2">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="IeP-xT-MKw">
<items>
<menuItem title="Flat View" tag="100" id="p1h-kw-5aA">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem title="Tree View" tag="101" id="uuF-ak-b7S">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
</items>
</menu>
</popUpButtonCell>
</popUpButton>
<connections>
<action selector="switchView:" target="494" id="1DR-jI-8ah"/>
</connections>
</toolbarItem>
<toolbarItem implicitItemIdentifier="CF826839-BC2B-4FEF-898A-77DC4D2486F1" label="" paletteLabel="" id="y4u-t8-Acq">
<nil key="toolTip"/>
<size key="minSize" width="96" height="22"/>
<size key="maxSize" width="119" height="22"/>
<searchField key="view" wantsLayer="YES" verticalHuggingPriority="750" id="4Kr-b9-X6j">
<rect key="frame" x="11" y="14" width="117" height="22"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" borderStyle="bezel" placeholderString="Filter Tasks" usesSingleLineMode="YES" bezelStyle="round" id="WXx-nE-N2S">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</searchFieldCell>
</searchField>
</toolbarItem>
<toolbarItem implicitItemIdentifier="A5784C30-D7FC-4958-875B-487768A4E610" label="" paletteLabel="" id="O1y-1z-g0u">
<nil key="toolTip"/>
<size key="minSize" width="38" height="17"/>
<size key="maxSize" width="38" height="17"/>
<textField key="view" horizontalHuggingPriority="251" verticalHuggingPriority="750" id="Pc9-qO-K4R">
<rect key="frame" x="6" y="15" width="38" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Tasks" id="jaa-xq-WqA">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</toolbarItem>
<toolbarItem implicitItemIdentifier="F54A1AEB-291E-4556-8B7E-D1C677012ABF" label="" paletteLabel="" image="kkText" id="UwA-pW-Mg8">
<nil key="toolTip"/>
<size key="minSize" width="48" height="48"/>
<size key="maxSize" width="330" height="48"/>
<imageView key="view" horizontalHuggingPriority="251" verticalHuggingPriority="251" id="aNo-Uq-I0N">
<rect key="frame" x="116" y="14" width="330" height="48"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkText" id="hwQ-Gs-JPJ"/>
</imageView>
</toolbarItem>
</allowedToolbarItems>
<defaultToolbarItems>
<toolbarItem reference="eEO-jq-TLG"/>
<toolbarItem reference="1xB-mk-PMD"/>
<toolbarItem reference="UwA-pW-Mg8"/>
<toolbarItem reference="eEO-jq-TLG"/>
<toolbarItem reference="7ph-jg-soj"/>
<toolbarItem reference="y4u-t8-Acq"/>
</defaultToolbarItems>
</toolbar>
<point key="canvasLocation" x="662.5" y="335"/>
</window>
<customObject id="494" customClass="AppDelegate">
<connections>
<outlet property="bottomPane" destination="E4M-PF-VD0" id="Au5-EH-OKZ"/>
<outlet property="bottomPaneBtn" destination="gtq-gn-VPL" id="Uxg-Ab-QzA"/>
<outlet property="bottomPaneSpinner" destination="LMT-Bu-FAk" id="a1H-Ag-GT8"/>
<outlet property="logoButton" destination="HoI-FQ-vTI" id="bzc-wu-4Hv"/>
<outlet property="noItemsLabel" destination="kIC-ZZ-ldy" id="nOm-8E-tZA"/>
<outlet property="progressIndicator" destination="839" id="870"/>
<outlet property="showPreferencesButton" destination="gSG-Nq-plb" id="MsG-Ve-uHw"/>
<outlet property="statusText" destination="745" id="871"/>
<outlet property="topPane" destination="TNF-7q-Loy" id="KZl-fO-P4O"/>
<outlet property="viewSelector" destination="nRz-eH-T6D" id="1YT-Nb-K3a"/>
<outlet property="window" destination="371" id="532"/>
</connections>
</customObject>
<customObject id="420" customClass="NSFontManager"/>
<customObject id="8VH-uv-w4O" customClass="TaskTableController"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="85d-Tb-wMk">
<rect key="frame" x="0.0" y="0.0" width="38" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Label" id="TbI-kK-19h">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</objects>
<resources>
<image name="kkText" width="426.48001098632812" height="85.919998168945312"/>
<image name="logoApple" width="194" height="236"/>
<image name="logoAppleBG" width="194" height="236"/>
<image name="settings" width="256" height="256"/>
<image name="settingsBG" width="256" height="256"/>
</resources>
</document>
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Some files were not shown because too many files have changed in this diff Show More