mirror of
https://github.com/objective-see/TaskExplorer.git
synced 2026-03-22 07:02:39 +00:00
version 2.0.0
-avoid UI calls when run in cmdline mode -hide icon when run in cmdline mode -option to scan single process
This commit is contained in:
@@ -25,5 +25,4 @@
|
||||
//'support us' button
|
||||
@property (weak, atomic) IBOutlet NSButton *supportUs;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
+23
-9
@@ -53,9 +53,6 @@
|
||||
//kick off main window/logic
|
||||
-(void)taskExplore
|
||||
{
|
||||
//make foreground so it has an dock icon, etc
|
||||
transformProcess(kProcessTransformToForegroundApplication);
|
||||
|
||||
//for autolayout
|
||||
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints"];
|
||||
|
||||
@@ -115,15 +112,21 @@
|
||||
[self registerKeypressHandler];
|
||||
|
||||
//check if authenticated
|
||||
// ->display authentication request if needed
|
||||
// display authentication request if needed
|
||||
if(YES != [self isAuthenticated])
|
||||
{
|
||||
//display auth popup
|
||||
// will invoke 'go' method on successful auth
|
||||
[self askForRoot];
|
||||
//wait to allow app to become front
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .33 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||||
|
||||
//display auth popup
|
||||
// will invoke 'go' method on successful auth
|
||||
[self askForRoot];
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//go!
|
||||
// ->setup tracking areas and begin thread that explores tasks
|
||||
// setup tracking areas and begin thread that explores tasks
|
||||
else
|
||||
{
|
||||
//go!
|
||||
@@ -161,12 +164,23 @@
|
||||
//set delegate
|
||||
// ->ensures our 'windowWillClose' method, which has logic to fully exit app
|
||||
self.window.delegate = self;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//automatically invoked by OS
|
||||
// ->main entry point
|
||||
-(void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
|
||||
//toggle away
|
||||
[[[NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.loginwindow"] firstObject] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
|
||||
//toggle back
|
||||
// work-around for menu not showing since we set Application is agent(UIElement): YES
|
||||
[[[NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.objective-see.TaskExplorer"] firstObject] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
|
||||
|
||||
|
||||
//first time run?
|
||||
// show thanks to friends window!
|
||||
// note: on close, invokes method to show main window
|
||||
@@ -443,7 +457,7 @@ bail:
|
||||
|
||||
//kick off thread to enum task
|
||||
// ->will update table as results come in
|
||||
[NSThread detachNewThreadSelector:@selector(enumerateTasks) toTarget:taskEnumerator withObject:nil];
|
||||
[NSThread detachNewThreadSelector:@selector(enumerateTasks:) toTarget:taskEnumerator withObject:nil];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
+2
-9
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// ItemBase.h
|
||||
// BlockBlock
|
||||
// TaskExplorer
|
||||
//
|
||||
// Created by Patrick Wardle on 9/25/14.
|
||||
// Copyright (c) 2014 Synack. All rights reserved.
|
||||
// Copyright (c) 2014 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@@ -25,13 +25,6 @@
|
||||
//file attributes
|
||||
@property(nonatomic, retain)NSDictionary* attributes;
|
||||
|
||||
//flag if known
|
||||
// ->signed by apple and/or whitelisted
|
||||
//@property BOOL isTrusted;
|
||||
|
||||
|
||||
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//init method
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
[[NSColor colorWithCalibratedWhite:1.0 alpha:1.0] setStroke];
|
||||
|
||||
//set fill
|
||||
[[NSColor colorWithCalibratedWhite:.65 alpha:1.0] setFill];
|
||||
[[NSColor colorWithCalibratedWhite:.50 alpha:1.0] setFill];
|
||||
}
|
||||
//light mode highlight
|
||||
else
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// BlockBlock
|
||||
//
|
||||
// Created by Patrick Wardle on 9/26/14.
|
||||
// Copyright (c) 2014 Synack. All rights reserved.
|
||||
// Copyright (c) 2014 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// BlockBlock
|
||||
//
|
||||
// Created by Patrick Wardle on 9/26/14.
|
||||
// Copyright (c) 2014 Synack. All rights reserved.
|
||||
// Copyright (c) 2014 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "NSMutableArray+QueueAdditions.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Queue.h
|
||||
// BlockBlock
|
||||
// TaskExplorer
|
||||
//
|
||||
// Created by Patrick Wardle on 9/26/14.
|
||||
// Copyright (c) 2014 Synack. All rights reserved.
|
||||
// Copyright (c) 2014 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
//from: https://github.com/esromneb/ios-queue-object/blob/master/NSMutableArray%2BQueueAdditions.h
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//
|
||||
// Queue.m
|
||||
// BlockBlock
|
||||
// TaskExplorer
|
||||
//
|
||||
// Created by Patrick Wardle on 9/26/14.
|
||||
// Copyright (c) 2014 Synack. All rights reserved.
|
||||
// Copyright (c) 2014 Objective-See. All rights reserved.
|
||||
//
|
||||
|
||||
#import "Queue.h"
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
self.cancelButton.enabled = NO;
|
||||
|
||||
//update auth message
|
||||
self.statusMsg.stringValue = @"ok: authorization successful";
|
||||
self.statusMsg.stringValue = @"...authorization successful!";
|
||||
|
||||
//wait a bit
|
||||
// ->then hide window & kick off action
|
||||
|
||||
@@ -394,7 +394,11 @@ bail:
|
||||
|
||||
//reload bottom pane now
|
||||
// note: this will only reload if new task is the currently selected one, etc
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:DYLIBS_VIEW];
|
||||
if(YES != cmdlineMode)
|
||||
{
|
||||
//reload
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:DYLIBS_VIEW];
|
||||
}
|
||||
|
||||
//complete dylib processing for new dylib
|
||||
// ->get signing info, hash, etc, & save into global list
|
||||
@@ -415,15 +419,19 @@ bail:
|
||||
newDylib.isPacked = [newDylib.parser.binaryInfo[KEY_IS_PACKED] boolValue];
|
||||
}
|
||||
|
||||
//no need to reload if task is now longer current/selected
|
||||
if(((AppDelegate*)[[NSApplication sharedApplication] delegate]).currentTask != self)
|
||||
//need to load?
|
||||
if(YES != cmdlineMode)
|
||||
{
|
||||
//skip reload
|
||||
continue;
|
||||
//no need to reload if task is now longer current/selected
|
||||
if(((AppDelegate*)[[NSApplication sharedApplication] delegate]).currentTask != self)
|
||||
{
|
||||
//skip reload
|
||||
continue;
|
||||
}
|
||||
|
||||
//reload row
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadRow:newDylib];
|
||||
}
|
||||
|
||||
//reload row
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadRow:newDylib];
|
||||
}
|
||||
|
||||
//signal sema
|
||||
@@ -519,7 +527,12 @@ bail:
|
||||
}] mutableCopy];
|
||||
|
||||
//reload bottom pane
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:FILES_VIEW];
|
||||
if(YES != cmdlineMode)
|
||||
{
|
||||
//reload
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:FILES_VIEW];
|
||||
}
|
||||
|
||||
|
||||
}//sync
|
||||
|
||||
@@ -603,7 +616,11 @@ bail:
|
||||
}
|
||||
|
||||
//reload bottom pane
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:NETWORKING_VIEW];
|
||||
if(YES != cmdlineMode)
|
||||
{
|
||||
//reload
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBottomPane:self itemView:NETWORKING_VIEW];
|
||||
}
|
||||
|
||||
}//sync
|
||||
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@
|
||||
|
||||
//enumerate all tasks
|
||||
// ->call back into app delegate to update task (top) table
|
||||
-(void)enumerateTasks;
|
||||
-(void)enumerateTasks:(NSNumber*)pid;
|
||||
|
||||
//get list of all pids
|
||||
-(OrderedDictionary*)getAllTasks;
|
||||
|
||||
+90
-26
@@ -44,10 +44,9 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
//enumerate all tasks
|
||||
// calls back into app delegate to update task (top) table when pau
|
||||
-(void)enumerateTasks
|
||||
-(void)enumerateTasks:(NSNumber*)pid
|
||||
{
|
||||
//(new) task item
|
||||
Task* newTask = nil;
|
||||
@@ -65,18 +64,28 @@
|
||||
self.state = ENUMERATION_STATE_TASKS;
|
||||
|
||||
//get all tasks
|
||||
// ->pids and binary obj with just path/name
|
||||
// pids and binary obj with just path/name
|
||||
newTasks = [self getAllTasks];
|
||||
|
||||
//build ancestries
|
||||
// do here, and use 'new tasks' since there might be new parents too
|
||||
[self generateAncestries:newTasks];
|
||||
|
||||
//only interested in one task?
|
||||
if(nil != pid)
|
||||
{
|
||||
//enumerate task
|
||||
[self enumerateTask:newTasks[pid]];
|
||||
|
||||
//done
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//get all tasks that are pau
|
||||
deadTasks = [self.tasks.allKeys filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NOT SELF IN %@", newTasks.allKeys]];
|
||||
|
||||
//remove any old tasks that have exited/died
|
||||
// ->invoke custom method to handle kids too...
|
||||
// invoke custom method to handle kids too...
|
||||
for(NSNumber* key in deadTasks)
|
||||
{
|
||||
//sync to remove
|
||||
@@ -121,23 +130,26 @@
|
||||
}//add new tasks
|
||||
|
||||
//sort tasks
|
||||
// ->ensures that signing info etc w/ be generated for (top) visible tasks
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) sortTasksForView:newTasks];
|
||||
|
||||
//reload task table
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadTaskTable];
|
||||
|
||||
//reload bottom pain
|
||||
// call on main thread
|
||||
if(YES != [NSThread isMainThread])
|
||||
if(YES != cmdlineMode)
|
||||
{
|
||||
//main thread
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
|
||||
//reload bottom pane
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) selectBottomPaneContent:nil];
|
||||
//sort
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) sortTasksForView:newTasks];
|
||||
|
||||
//reload task table
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadTaskTable];
|
||||
|
||||
//reload bottom pain
|
||||
// call on main thread
|
||||
if(YES != [NSThread isMainThread])
|
||||
{
|
||||
//main thread
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
|
||||
});
|
||||
//reload bottom pane
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) selectBottomPaneContent:nil];
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//for new tasks
|
||||
@@ -173,12 +185,16 @@
|
||||
newTask.binary.isPacked = [newTask.binary.parser.binaryInfo[KEY_IS_PACKED] boolValue];
|
||||
}
|
||||
|
||||
//reload task (row) in table
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadRow:newTask];
|
||||
|
||||
//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];
|
||||
//reload UI
|
||||
if(YES != cmdlineMode)
|
||||
{
|
||||
//reload task (row) in table
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadRow:newTask];
|
||||
|
||||
//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 new tasks
|
||||
|
||||
@@ -298,6 +314,53 @@
|
||||
//set state
|
||||
self.state = ENUMERATION_STATE_COMPLETE;
|
||||
|
||||
bail:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//scan a single task
|
||||
-(void)enumerateTask:(Task*)task
|
||||
{
|
||||
//sanity check
|
||||
if(nil == task)
|
||||
{
|
||||
//bail
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//generate signing info dynamically
|
||||
task.binary.signingInfo = extractSigningInfo(task.pid.intValue, nil, kSecCSDefaultFlags);
|
||||
if(nil == task.binary.signingInfo)
|
||||
{
|
||||
//extract signing info statically
|
||||
task.binary.signingInfo = extractSigningInfo(0, task.binary.path, kSecCSCheckAllArchitectures | kSecCSCheckNestedCode | kSecCSDoNotValidateResources);
|
||||
}
|
||||
|
||||
//parse
|
||||
if(YES == [task.binary parse])
|
||||
{
|
||||
//save encrypted flag
|
||||
task.binary.isEncrypted = [task.binary.parser.binaryInfo[KEY_IS_ENCRYPTED] boolValue];
|
||||
|
||||
//save packed flag
|
||||
task.binary.isPacked = [task.binary.parser.binaryInfo[KEY_IS_PACKED] boolValue];
|
||||
}
|
||||
|
||||
//enumerate dylibs
|
||||
[task enumerateDylibs:self.dylibs shouldWait:YES];
|
||||
|
||||
//enumerate files
|
||||
[task enumerateFiles:YES];
|
||||
|
||||
//enumerate networking
|
||||
[task enumerateNetworking:YES];
|
||||
|
||||
//save task
|
||||
self.tasks[task.pid] = task;
|
||||
|
||||
bail:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -627,7 +690,8 @@ bail:
|
||||
|
||||
//when there are no flagged items
|
||||
// ->(re)set flagged icon to black
|
||||
if(0 == taskEnumerator.flaggedItems.count)
|
||||
if( (YES != cmdlineMode) &&
|
||||
(0 == taskEnumerator.flaggedItems.count) )
|
||||
{
|
||||
//set main image
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]).flaggedButton setImage:[NSImage imageNamed:@"flagged"]];
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2018 Objective-See, LLC. All rights reserved.</string>
|
||||
<string>Copyright © 2019 Objective-See, LLC. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?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/>
|
||||
</plist>
|
||||
@@ -238,6 +238,8 @@
|
||||
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>"; };
|
||||
CD42FF8F21CE0CED000A0461 /* TaskExplorer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = TaskExplorer.entitlements; sourceTree = SOURCE_ROOT; };
|
||||
CD42FF9021CE0D05000A0461 /* remoteTaskService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = remoteTaskService.entitlements; 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; };
|
||||
@@ -444,6 +446,7 @@
|
||||
1D21BC54172AF43D009D1CFD /* TaskExplorer */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD42FF8F21CE0CED000A0461 /* TaskExplorer.entitlements */,
|
||||
CD1508DE21BB13980081F1AF /* Signing.h */,
|
||||
CD1508DD21BB13980081F1AF /* Signing.m */,
|
||||
CD1D14F221B8F2FC00FF7F4B /* Assets.xcassets */,
|
||||
@@ -565,6 +568,7 @@
|
||||
CDA5F6AE1B16D805003CE340 /* remoteTaskService */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CD42FF9021CE0D05000A0461 /* remoteTaskService.entitlements */,
|
||||
CDA5F6B21B16D805003CE340 /* remoteTaskService.h */,
|
||||
CDA5F6B31B16D805003CE340 /* remoteTaskService.m */,
|
||||
CDA5F6B51B16D805003CE340 /* main.m */,
|
||||
@@ -715,10 +719,20 @@
|
||||
TargetAttributes = {
|
||||
1D21BC4A172AF43D009D1CFD = {
|
||||
DevelopmentTeam = VBG97UB4TA;
|
||||
SystemCapabilities = {
|
||||
com.apple.HardenedRuntime = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
CDA5F6AC1B16D805003CE340 = {
|
||||
CreatedOnToolsVersion = 6.3.2;
|
||||
DevelopmentTeam = VBG97UB4TA;
|
||||
SystemCapabilities = {
|
||||
com.apple.HardenedRuntime = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -1008,6 +1022,7 @@
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Carthage/Build/Mac",
|
||||
@@ -1031,6 +1046,7 @@
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Carthage/Build/Mac",
|
||||
@@ -1057,6 +1073,7 @@
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -1092,6 +1109,7 @@
|
||||
CODE_SIGN_IDENTITY = "Developer ID Application: Objective-See, LLC (VBG97UB4TA)";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
|
||||
BIN
Binary file not shown.
+9
-1
@@ -48,7 +48,15 @@
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "-scan"
|
||||
argument = "-pid"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "78779"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "-explore"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
|
||||
+4
-6
@@ -763,9 +763,12 @@ void makeModal(NSWindowController* windowController)
|
||||
//make modal on main thread
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
|
||||
//make app front
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
//modal
|
||||
[[NSApplication sharedApplication] runModalForWindow:windowController.window];
|
||||
|
||||
|
||||
});
|
||||
|
||||
//all done
|
||||
@@ -1375,8 +1378,3 @@ void transformProcess(ProcessApplicationTransformState location)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -208,6 +208,9 @@
|
||||
//VT scan ID
|
||||
__block NSString* scanID = nil;
|
||||
|
||||
//new report
|
||||
__block NSURL* newReport = nil;
|
||||
|
||||
//alloc/init VT obj
|
||||
vtObj = [[VirusTotal alloc] init];
|
||||
|
||||
@@ -313,8 +316,19 @@
|
||||
//nap so user can see msg
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
//launch browser to show rew report
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:result[@"permalink"]]];
|
||||
//launch browser to show new report
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
|
||||
//sanity check
|
||||
// then launch browser
|
||||
if( (nil != result[@"permalink"]) &&
|
||||
(nil != (newReport = [NSURL URLWithString:result[@"permalink"]])) )
|
||||
{
|
||||
//launch browser
|
||||
[[NSWorkspace sharedWorkspace] openURL:newReport];
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//wait to browser is up and happy
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
@@ -390,8 +404,19 @@
|
||||
//nap so user can see msg
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
//launch browser to show rew report
|
||||
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:result[@"permalink"]]];
|
||||
//launch browser to show new report
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
|
||||
//sanity check
|
||||
// then launch browser
|
||||
if( (nil != result[@"permalink"]) &&
|
||||
(nil != (newReport = [NSURL URLWithString:result[@"permalink"]])) )
|
||||
{
|
||||
//launch browser
|
||||
[[NSWorkspace sharedWorkspace] openURL:newReport];
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//wait to browser is up and happy
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
@@ -9,6 +9,11 @@
|
||||
#import "Binary.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
//cmdline flag
|
||||
extern BOOL cmdlineMode;
|
||||
|
||||
@interface VirusTotal : NSObject
|
||||
{
|
||||
|
||||
|
||||
+5
-2
@@ -606,11 +606,14 @@ bail:
|
||||
}
|
||||
|
||||
//call up into app delegate to smartly reload
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBinary:queriedItem];
|
||||
if(YES != cmdlineMode)
|
||||
{
|
||||
//reload
|
||||
[((AppDelegate*)[[NSApplication sharedApplication] delegate]) reloadBinary:queriedItem];
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// TaskExplorer
|
||||
//
|
||||
// Created by Patrick Wardle on 12/16/18.
|
||||
// Copyright © 2018 Lucas Derraugh. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef main_h
|
||||
@@ -33,6 +32,9 @@ VirusTotal* virusTotal = nil;
|
||||
//network connected flag
|
||||
BOOL isConnected = NO;
|
||||
|
||||
//cmdline flag
|
||||
BOOL cmdlineMode = NO;
|
||||
|
||||
//(privacy) protected directories
|
||||
NSArray* protectedDirectories = nil;
|
||||
|
||||
|
||||
@@ -80,6 +80,9 @@ int main(int argc, char *argv[])
|
||||
goto bail;
|
||||
}
|
||||
|
||||
//set flag
|
||||
cmdlineMode = YES;
|
||||
|
||||
//scan
|
||||
cmdlineExplore();
|
||||
|
||||
@@ -94,8 +97,14 @@ int main(int argc, char *argv[])
|
||||
// just kick off app for UI instance
|
||||
else
|
||||
{
|
||||
//set flag
|
||||
cmdlineMode = NO;
|
||||
|
||||
//make foreground so it has an dock icon, etc
|
||||
transformProcess(kProcessTransformToForegroundApplication);
|
||||
|
||||
//invoke app's main
|
||||
status = NSApplicationMain(argc, (const char **)argv);
|
||||
status = NSApplicationMain(argc, (const char **)argv);
|
||||
}
|
||||
|
||||
bail:
|
||||
@@ -114,8 +123,9 @@ void usage()
|
||||
printf(" -explore enumerate all tasks and dylibs\n");
|
||||
printf("\noptions:\n");
|
||||
printf(" -pretty json output is 'pretty-printed'\n");
|
||||
printf(" -pid [pid] just scan/explore the specified task'\n");
|
||||
printf(" -skipVT do not query VirusTotal (when '-explore' is specified)\n");
|
||||
printf(" -full for each task; include dylibs, files, & network connections\n\n");
|
||||
printf(" -detailed for each task; include dylibs, files, & network connections\n\n");
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -123,6 +133,9 @@ void usage()
|
||||
//perform a cmdline enumeration of all things
|
||||
void cmdlineExplore()
|
||||
{
|
||||
//args
|
||||
NSArray* arguments = nil;
|
||||
|
||||
//filter obj
|
||||
Filter* filter = nil;
|
||||
|
||||
@@ -141,6 +154,16 @@ void cmdlineExplore()
|
||||
//output
|
||||
NSMutableString* output = nil;
|
||||
|
||||
//formatter
|
||||
NSNumberFormatter* formatter = nil;
|
||||
|
||||
//pid
|
||||
// if single task was specified
|
||||
NSNumber* pid = nil;
|
||||
|
||||
//grab args
|
||||
arguments = [[NSProcessInfo processInfo] arguments];
|
||||
|
||||
//init filter obj
|
||||
filter = [[Filter alloc] init];
|
||||
|
||||
@@ -149,7 +172,7 @@ void cmdlineExplore()
|
||||
|
||||
//set flag
|
||||
// skip virus total?
|
||||
skipVirusTotal = [[[NSProcessInfo processInfo] arguments] containsObject:@"-skipVT"];
|
||||
skipVirusTotal = [arguments containsObject:@"-skipVT"];
|
||||
|
||||
//virus total?
|
||||
if(YES != skipVirusTotal)
|
||||
@@ -161,8 +184,22 @@ void cmdlineExplore()
|
||||
//be nice
|
||||
nice(15);
|
||||
|
||||
//scan just one pid?
|
||||
if( (YES == [arguments containsObject:@"-pid"]) &&
|
||||
(YES != [@"-pid" isEqualToString:arguments.lastObject]) )
|
||||
{
|
||||
//init formatter
|
||||
formatter = [[NSNumberFormatter alloc] init];
|
||||
|
||||
//set style
|
||||
formatter.numberStyle = NSNumberFormatterDecimalStyle;
|
||||
|
||||
//extract/convert pid
|
||||
pid = [formatter numberFromString:arguments[[arguments indexOfObject:@"-pid"] + 1]];
|
||||
}
|
||||
|
||||
//enumerate all tasks/dylibs/files/etc
|
||||
[taskEnumerator enumerateTasks];
|
||||
[taskEnumerator enumerateTasks:pid];
|
||||
|
||||
//wait for items to complete processing
|
||||
while(taskEnumerator.binaryQueue.itemsOut != taskEnumerator.binaryQueue.itemsOut)
|
||||
@@ -172,7 +209,7 @@ void cmdlineExplore()
|
||||
}
|
||||
|
||||
//determine what each dylib is loaded in
|
||||
// do here as all tasks and all dylibs are enum'd
|
||||
// do here as all tasks and all dylibs are (now) enum'd
|
||||
for(NSString* dylib in taskEnumerator.dylibs)
|
||||
{
|
||||
//loaded in
|
||||
@@ -189,21 +226,21 @@ void cmdlineExplore()
|
||||
|
||||
//set flag
|
||||
// include apple items?
|
||||
includeApple = [[[NSProcessInfo processInfo] arguments] containsObject:@"-apple"];
|
||||
includeApple = [arguments containsObject:@"-apple"];
|
||||
|
||||
//set flag
|
||||
// pretty print json?
|
||||
prettyPrint = [[[NSProcessInfo processInfo] arguments] containsObject:@"-pretty"];
|
||||
prettyPrint = [arguments containsObject:@"-pretty"];
|
||||
|
||||
//set flag
|
||||
// full output?
|
||||
detailed = [[[NSProcessInfo processInfo] arguments] containsObject:@"-detailed"];
|
||||
detailed = [arguments containsObject:@"-detailed"];
|
||||
|
||||
//alloc output JSON
|
||||
output = [NSMutableString string];
|
||||
|
||||
//only flagged items?
|
||||
if(YES == [[[NSProcessInfo processInfo] arguments] containsObject:@"-scan"])
|
||||
if(YES == [arguments containsObject:@"-scan"])
|
||||
{
|
||||
//start JSON
|
||||
[output appendString:@"{\"flagged items\":["];
|
||||
@@ -225,6 +262,7 @@ void cmdlineExplore()
|
||||
[output appendString:@"]}"];
|
||||
}
|
||||
|
||||
//all items
|
||||
else
|
||||
{
|
||||
//start JSON
|
||||
@@ -234,8 +272,10 @@ void cmdlineExplore()
|
||||
for(NSNumber* taskPid in taskEnumerator.tasks)
|
||||
{
|
||||
//skip apple?
|
||||
// unless we're scanning a single proc
|
||||
if( (YES != includeApple) &&
|
||||
(YES == [filter isApple:((Task*)taskEnumerator.tasks[taskPid]).binary]) )
|
||||
(1 != taskEnumerator.tasks.count) &&
|
||||
(YES == [filter isApple:((Task*)taskEnumerator.tasks[taskPid]).binary]) )
|
||||
{
|
||||
//skip
|
||||
continue;
|
||||
@@ -252,9 +292,10 @@ void cmdlineExplore()
|
||||
[output deleteCharactersInRange:NSMakeRange([output length]-1, 1)];
|
||||
}
|
||||
|
||||
//not detailed?
|
||||
// add separate array of dylibs
|
||||
if(YES != detailed)
|
||||
//not detailed or not just scanning 1 task
|
||||
// add separate array of for all the dylibs
|
||||
if( (YES != detailed) &&
|
||||
(1 != taskEnumerator.tasks.count) )
|
||||
{
|
||||
//append
|
||||
[output appendString:@"],\"dylibs\":["];
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
Patrons (2^6+):
|
||||
Halo Privacy, Ash Morgan, Nando Mendonca, Geoffrey Weber, Randy Wong, Aaron Kiemele, Beau Galbraith, Stuart Ashenbrenner, Gamer_Bot
|
||||
Halo Privacy, Ash Morgan, Nando Mendonca, Geoffrey Weber, Randy Wong, Aaron Kiemele, Beau Galbraith, Stuart Ashenbrenner, whiskerz, Gamer_Bot
|
||||
|
||||
Friends of Objective-See:
|
||||
Digita Security, Sophos, Malwarebytes, SmugMug, Guardian Mobile Firewall, SecureMac
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2.0.0</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2018 Objective-See, LLC. All rights reserved.</string>
|
||||
<string>Copyright © 2019 Objective-See, LLC. All rights reserved.</string>
|
||||
<key>XPCService</key>
|
||||
<dict>
|
||||
<key>ServiceType</key>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?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/>
|
||||
</plist>
|
||||
Reference in New Issue
Block a user