mirror of
https://github.com/objective-see/TaskExplorer.git
synced 2026-03-22 07:02:39 +00:00
-dynamic code signing -improved global search -ignore WindowServer -added/removed some @sync to prevent deadlock/mutation issues
360 lines
11 KiB
Objective-C
360 lines
11 KiB
Objective-C
//
|
|
// InfoWindowController.m
|
|
// TaskExplorer
|
|
//
|
|
// 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 "Consts.h"
|
|
#import "Signing.h"
|
|
#import "Utilities.h"
|
|
#import "Connection.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];
|
|
|
|
//no dark mode?
|
|
// make window white
|
|
if(YES != isDarkMode())
|
|
{
|
|
//make white
|
|
self.window.backgroundColor = 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"];
|
|
}
|
|
//load file info window
|
|
else if(YES == [selectedItem isKindOfClass:[File class]])
|
|
{
|
|
//load nib
|
|
self.windowController = [[InfoWindowController alloc] initWithWindowNibName:@"FileInfoWindow"];
|
|
}
|
|
|
|
//load networking info window
|
|
else if(YES == [selectedItem isKindOfClass:[Connection class]])
|
|
{
|
|
//load nib
|
|
self.windowController = [[InfoWindowController alloc] initWithWindowNibName:@"NetworkInfoWindow"];
|
|
}
|
|
|
|
//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;
|
|
|
|
//task arguments
|
|
NSMutableString* taskArguments = nil;
|
|
|
|
//binary
|
|
// ->when showing info about a dylib
|
|
Binary* dylib = nil;
|
|
|
|
//file
|
|
// ->when showing info about a file
|
|
File* file = nil;
|
|
|
|
//connection
|
|
// ->when showing info about a connection
|
|
Connection* connection = 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"]];
|
|
|
|
//flagged items
|
|
// ->make name red!
|
|
if( (nil != task.binary.vtInfo) &&
|
|
(0 != [task.binary.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
|
|
{
|
|
//red
|
|
self.name.textColor = [NSColor redColor];
|
|
}
|
|
|
|
//set command line
|
|
// ->done just in time (first time)
|
|
if(nil == task.arguments)
|
|
{
|
|
//get args
|
|
[((Task*)self.itemObj) getArguments];
|
|
}
|
|
|
|
//set default value for args
|
|
self.arguments.stringValue = @"no arguments/unknown";
|
|
|
|
//set any args
|
|
// ->task path and name, make up the first to 'args', so skip/ignore those
|
|
if(task.arguments.count > 2)
|
|
{
|
|
//alloc string to build up args
|
|
taskArguments = [NSMutableString string];
|
|
|
|
//build up args string
|
|
// ->start at index 2, to skip path/name
|
|
for(NSUInteger index = 2; index<task.arguments.count; index++)
|
|
{
|
|
//add arg
|
|
[taskArguments appendFormat:@"%@ ", task.arguments[index]];
|
|
}
|
|
|
|
//set args into text field
|
|
if(0 != taskArguments.length)
|
|
{
|
|
//add
|
|
self.arguments.stringValue = taskArguments;
|
|
}
|
|
}
|
|
|
|
//set path
|
|
[self.path setStringValue:[self valueForStringItem:task.binary.path default:@"unknown"]];
|
|
|
|
//hashes could still be, being generated
|
|
// ->but don't want to wait, so just created em directly
|
|
if(nil == task.binary.hashes[KEY_HASH_MD5])
|
|
{
|
|
//save hash
|
|
task.binary.hashes = hashFile(task.binary.path);
|
|
}
|
|
|
|
//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]];
|
|
|
|
//signing info still being generated?
|
|
// ->but don't want to wait, so just created em directly
|
|
if(nil == task.binary.signingInfo)
|
|
{
|
|
//generate signing info
|
|
task.binary.signingInfo = extractSigningInfo(task.pid.intValue, nil, kSecCSDefaultFlags);
|
|
|
|
//failed?
|
|
// try extract signing info statically
|
|
if(nil == task.binary.signingInfo)
|
|
{
|
|
//extract signing info statically
|
|
task.binary.signingInfo = extractSigningInfo(0, task.binary.path, kSecCSCheckAllArchitectures | kSecCSCheckNestedCode | kSecCSDoNotValidateResources);
|
|
}
|
|
}
|
|
|
|
//set signing info
|
|
[self.sign setStringValue:[self valueForStringItem:[task.binary formatSigningInfo] default:@"not signed"]];
|
|
}
|
|
|
|
//handle binaries (dylibs)
|
|
else if(YES == [self.itemObj isKindOfClass:[Binary class]])
|
|
{
|
|
//cast as binary/dylib
|
|
dylib = (Binary*)self.itemObj;
|
|
|
|
//set icon
|
|
self.icon.image = dylib.icon;
|
|
|
|
//set name
|
|
[self.name setStringValue:[self valueForStringItem:dylib.name default:@"unknown"]];
|
|
|
|
//flagged items
|
|
// ->make name red!
|
|
if( (nil != dylib.vtInfo) &&
|
|
(0 != [dylib.vtInfo[VT_RESULTS_POSITIVES] unsignedIntegerValue]) )
|
|
{
|
|
//red
|
|
self.name.textColor = [NSColor redColor];
|
|
}
|
|
|
|
//set path
|
|
[self.path setStringValue:[self valueForStringItem:dylib.path default:@"unknown"]];
|
|
|
|
//hashes still being generated?
|
|
// ->but don't want to wait, so just created em directly
|
|
if(nil == dylib.hashes[KEY_HASH_MD5])
|
|
{
|
|
//save hash
|
|
dylib.hashes = hashFile(dylib.path);
|
|
}
|
|
|
|
//set hash
|
|
[self.hashes setStringValue:[NSString stringWithFormat:@"%@ / %@", dylib.hashes[KEY_HASH_MD5], dylib.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, dylib.attributes.fileModificationDate]];
|
|
|
|
//signing info still being generated?
|
|
// ->but don't want to wait, so just created em directly
|
|
if(nil == dylib.signingInfo)
|
|
{
|
|
//generate signing info
|
|
dylib.signingInfo = extractSigningInfo(-1, dylib.path, kSecCSCheckAllArchitectures | kSecCSCheckNestedCode | kSecCSDoNotValidateResources);
|
|
}
|
|
|
|
//set signing info
|
|
[self.sign setStringValue:[self valueForStringItem:[dylib formatSigningInfo] default:@"not signed"]];
|
|
}
|
|
|
|
//handle File class
|
|
else if(YES == [self.itemObj isKindOfClass:[File class]])
|
|
{
|
|
//typecast
|
|
file = (File*)self.itemObj;
|
|
|
|
//first check if detailed info (such as 'type') was generated yet
|
|
// ->when not, do it directly here
|
|
if(nil == file.type)
|
|
{
|
|
//generated detailed info
|
|
[file generateDetailedInfo];
|
|
}
|
|
|
|
//set icon
|
|
self.icon.image = itemObj.icon;
|
|
|
|
//set name
|
|
[self.name setStringValue:self.itemObj.name];
|
|
|
|
//set path
|
|
[self.path setStringValue:self.itemObj.path];
|
|
|
|
//set type
|
|
[self.type setStringValue:[self valueForStringItem:file.type default:@"unknown"]];
|
|
|
|
//set size
|
|
[self.size setStringValue:[NSString stringWithFormat:@"%llu bytes", self.itemObj.attributes.fileSize]];
|
|
|
|
//set date
|
|
[self.date setStringValue:[NSString stringWithFormat:@"%@ (created) / %@ (modified)", self.itemObj.attributes.fileCreationDate, self.itemObj.attributes.fileModificationDate]];
|
|
}
|
|
|
|
//handle Connection class
|
|
else if(YES == [self.itemObj isKindOfClass:[Connection class]])
|
|
{
|
|
//typecast
|
|
connection = (Connection*)self.itemObj;
|
|
|
|
//set icon
|
|
self.icon.image = itemObj.icon;
|
|
|
|
//set connection string
|
|
[self.name setStringValue:connection.endpoints];
|
|
|
|
//set type
|
|
[self.type setStringValue:[self valueForStringItem:connection.type default:@"unknown"]];
|
|
|
|
//set proto
|
|
[self.protocol setStringValue:[self valueForStringItem:connection.proto default:@"unknown"]];
|
|
|
|
//set family
|
|
[self.family setStringValue:[self valueForStringItem:connection.family default:@"unknown"]];
|
|
|
|
//set status
|
|
[self.state setStringValue:[self valueForStringItem:connection.state default:@"unknown"]];
|
|
}
|
|
|
|
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
|