improved filtering/searching of network connections to include family/protocol/state

added network connections to global search
This commit is contained in:
Patrick Wardle
2015-09-02 21:47:23 -10:00
parent efa77f89b8
commit 309a507a0e
9 changed files with 265 additions and 111 deletions
+10 -9
View File
@@ -39,6 +39,10 @@
//TODO: remove task, remove from taskEnum's global list for executables, and dylibs, etc
//TODO: also refresh!....
//TODO: search include network (and improved filtering to include state/proto/type) - DONE!
//TODO: check all searches that use NSNotFound also check for nil (other != NSNotFound will be true for nil!!)
@implementation AppDelegate
@@ -227,18 +231,12 @@
return;
}
//invoked for any (and only) key-down events
//invoked for any (but only) key-down events
-(NSEvent*)handleKeypress:(NSEvent*)event
{
//flag indicating event was handled
BOOL wasHandled = NO;
//refresh (cmd+r)
//save (cmd+s)
//search (cmd+f)
//close window (cmd+w)
//info for selected task (cmd+i)
//only care about 'cmd' + something
if(NSCommandKeyMask != (event.modifierFlags & NSCommandKeyMask))
{
@@ -246,9 +244,12 @@
goto bail;
}
NSLog(@"key press: %x", [event keyCode]);
//handle key-code
// refresh (cmd+r)
// save (cmd+s)
// search (cmd+f)
// close window (cmd+w)
// info for selected task (cmd+i)
switch ([event keyCode])
{
//'r' (refresh)
+37 -6
View File
@@ -12,9 +12,6 @@
#import "ItemBase.h"
#import "Connection.h"
//file filter keywords
//NSString * const FILE_FILTERS[] = {@"#apple", @"#nonapple", @"#signed", @"#unsigned", @"#flagged"};
//binary filter keywords
NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#unsigned", @"#flagged"};
@@ -210,7 +207,6 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un
}
//filter network connections
//TODO: match on family/connection type
-(void)filterConnections:(NSString*)filterText items:(NSMutableArray*)items results:(NSMutableArray*)results
{
//first reset filter'd items
@@ -220,7 +216,8 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un
for(Connection* item in items)
{
//check local ip
if(NSNotFound != [item.localIPAddr rangeOfString:filterText options:NSCaseInsensitiveSearch].location)
if( (nil != item.localIPAddr) &&
(NSNotFound != [item.localIPAddr rangeOfString:filterText options:NSCaseInsensitiveSearch].location) )
{
//save match
[results addObject:item];
@@ -230,7 +227,8 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un
}
//check local port
if(NSNotFound != [[NSString stringWithFormat:@"%d", [item.localPort unsignedShortValue]] rangeOfString:filterText options:NSCaseInsensitiveSearch].location)
if( (nil != item.localIPAddr) &&
(NSNotFound != [[NSString stringWithFormat:@"%d", [item.localPort unsignedShortValue]] rangeOfString:filterText options:NSCaseInsensitiveSearch].location) )
{
//save match
[results addObject:item];
@@ -261,6 +259,39 @@ NSString * const BINARY_KEYWORDS[] = {@"#apple", @"#nonapple", @"#signed", @"#un
continue;
}
//check family
if( (nil != item.family) &&
(NSNotFound != [item.family rangeOfString:filterText options:NSCaseInsensitiveSearch].location) )
{
//save match
[results addObject:item];
//next
continue;
}
//check protocol
if( (nil != item.proto) &&
(NSNotFound != [item.proto rangeOfString:filterText options:NSCaseInsensitiveSearch].location) )
{
//save match
[results addObject:item];
//next
continue;
}
//check state
if( (nil != item.state) &&
(NSNotFound != [item.state rangeOfString:filterText options:NSCaseInsensitiveSearch].location) )
{
//save match
[results addObject:item];
//next
continue;
}
}//all connections
return;
+67 -11
View File
@@ -36,9 +36,9 @@ NSTableCellView* createItemView(NSTableView* tableView, id owner, id item)
}
//handle logic for search results
// ->dylibs and files have the special global 'loaded in' views
// ->dylibs/files/connections have the special global 'loaded in' views
else if( (YES == [owner isKindOfClass:[SearchWindowController class]]) &&
( (YES == [item isKindOfClass:[Binary class]]) || (YES == [item isKindOfClass:[File class]]) ) )
(YES != [item isKindOfClass:[Task class]]) )
{
//create & config view
itemCell = createLoadedItemView(tableView, owner, item);
@@ -164,7 +164,6 @@ NSTableCellView* createLoadedItemView(NSTableView* tableView, id owner, id item)
//get host tasks
// ->works with dylibs or files
//TODO: make work w/ network connections
tasks = [((AppDelegate*)[[NSApplication sharedApplication] delegate]).taskEnumerator loadedIn:item];
//add dylib indicator
@@ -181,6 +180,13 @@ NSTableCellView* createLoadedItemView(NSTableView* tableView, id owner, id item)
//init
loadedIn = [NSMutableString stringWithFormat:@"(file, loaded in:"];
}
//add connection indicator
//-> '(connection, in: ... '
else if(YES == [item isKindOfClass:[Connection class]])
{
//init
loadedIn = [NSMutableString stringWithFormat:@"(connection, in:"];
}
//add all tasks
for(Task* task in tasks)
@@ -213,6 +219,13 @@ NSTableCellView* createLoadedItemView(NSTableView* tableView, id owner, id item)
//create
loadedItemCell = [tableView makeViewWithIdentifier:@"FileCell" owner:owner];
}
//connections
// ->create cell
else if(YES == [item isKindOfClass:[Connection class]])
{
//create
loadedItemCell = [tableView makeViewWithIdentifier:@"ConnectionCell" owner:owner];
}
//sanity check
if(nil == loadedItemCell)
@@ -256,9 +269,21 @@ NSTableCellView* createLoadedItemView(NSTableView* tableView, id owner, id item)
// ->(re)set main textfield's color to black
loadedItemCell.textField.textColor = [NSColor blackColor];
//set main text
// ->name
[loadedItemCell.textField setStringValue:[item name]];
//dylibs/files
// ->main text is name
if( (YES == [item isKindOfClass:[Binary class]]) ||
(YES == [item isKindOfClass:[File class]]) )
{
//set name
[loadedItemCell.textField setStringValue:[item name]];
}
//connections
// ->main text is endpoints string
else
{
//set endpoints string
[loadedItemCell.textField setStringValue:[item endpoints]];
}
//get name frame
nameFrame = loadedItemCell.textField.frame;
@@ -273,13 +298,41 @@ NSTableCellView* createLoadedItemView(NSTableView* tableView, id owner, id item)
// ->should now be exact size of text
loadedItemCell.textField.frame = nameFrame;
//set pid
//set host task(s) string
// ->immediately follows name
[((NSTextField*)[loadedItemCell viewWithTag:TABLE_ROW_PID_LABEL]) setStringValue:loadedIn];
//set path
[[loadedItemCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:[item path]];
//dylibs/files
// ->subtext is path
if( (YES == [item isKindOfClass:[Binary class]]) ||
(YES == [item isKindOfClass:[File class]]) )
{
//set path
[[loadedItemCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:[item path]];
}
//connections
// ->subtext is connection status
else
{
//set details
// ->TCP socket
if(nil != ((Connection*)item).state)
{
//add state
[[loadedItemCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:((Connection*)item).state];
}
//set details
// ->UDP socket
else if(YES == [((Connection*)item).type isEqualToString:@"SOCK_DGRAM"])
{
//bound
// ->add state
[[loadedItemCell viewWithTag:TABLE_ROW_SUB_TEXT_TAG] setStringValue:@"bound (UDP) socket"];
//TODO: connected UDP socket?
}
}
//only dylibs have VT button
if(YES == [item isKindOfClass:[Binary class]])
{
@@ -343,7 +396,9 @@ NSTableCellView* createTaskView(NSTableView* tableView, id owner, Task* task)
//set code signing icon
((NSImageView*)[taskCell viewWithTag:TABLE_ROW_SIGNATURE_ICON]).image = getCodeSigningIcon(task.binary);
//TODO: red for flagged?
//default
// ->(re)set main textfield's color to black
taskCell.textField.textColor = [NSColor blackColor];
@@ -508,6 +563,7 @@ NSTableCellView* createNetworkView(NSTableView* tableView, id owner, Connection*
//item cell
NSTableCellView* connectionCell = nil;
//TODO: don't need this to be mutable str?
//connection details
NSMutableString* details = nil;
+54 -1
View File
@@ -503,6 +503,9 @@ bail:
//matching files
NSMutableDictionary* matchingFiles = nil;
//matching connections
NSMutableDictionary* matchingConnections = nil;
//task
Task* task = nil;
@@ -518,6 +521,9 @@ bail:
//alloc dictionary for matching files
matchingFiles = [NSMutableDictionary dictionary];
//alloc dictionary for matching connections
matchingConnections = [NSMutableDictionary dictionary];
//reset search results
[self.searchResults removeAllObjects];
@@ -564,6 +570,9 @@ bail:
@synchronized(allTasks)
{
//reset
[matchingItems removeAllObjects];
//TODO: B4 RELEASE! SYNC DYLIBS ARRAY!!!
//walk all tasks
// ->scan each for dylib matches, only processing first match
@@ -604,6 +613,9 @@ bail:
//sync
@synchronized(allTasks)
{
//reset
[matchingItems removeAllObjects];
//walk all tasks
// ->scan each for file matches, only processing first match
for(NSNumber* taskPid in allTasks)
@@ -639,7 +651,48 @@ bail:
//refresh table to display dylib
[self.searchTable reloadData];
//TODO: search network conns
//4th: search for all matching network comms
//sync
//TODO: sync network connections
@synchronized(allTasks)
{
//reset
[matchingItems removeAllObjects];
//walk all tasks
// ->scan each for file matches, only processing first match
for(NSNumber* taskPid in allTasks)
{
//extract task
task = allTasks[taskPid];
//filter
[self.filterObj filterConnections:searchString items:task.connections results:matchingItems];
//process all matching connections
// ->but first check if processed due to matching in another task already
for(Connection* connection in matchingItems)
{
//ignore if already seen/processed
if(nil != matchingConnections[connection.endpoints])
{
//skip
continue;
}
//process
[self.searchResults addObject:connection];
//save
matchingConnections[connection.endpoints] = connection;
}
}//all tasks
}//sync
//refresh table to display dylib
[self.searchTable reloadData];
//bail
bail:
+34 -2
View File
@@ -14,6 +14,7 @@
#import "AppDelegate.h"
#import "Utilities.h"
#import "TaskEnumerator.h"
#import "Connection.h"
#import <syslog.h>
#import <signal.h>
@@ -634,6 +635,9 @@ bail:
//file flag
BOOL isFile = NO;
//connection flag
BOOL isConnection = NO;
//tasks
hostTasks = [NSMutableArray array];
@@ -651,15 +655,24 @@ bail:
isFile = YES;
}
//check if item is connection
else if(YES == [item isKindOfClass:[Connection class]])
{
//file
isConnection = YES;
}
//sanity check
if( (YES != isDylib) &&
(YES != isFile) )
(YES != isFile) &&
(YES != isConnection) )
{
//bail
goto bail;
}
//sync
//TODO: B4 RELEASE, sync files/dylibs/connections
@synchronized(self.tasks)
{
//iterate over all tasks
@@ -687,7 +700,7 @@ bail:
}//dylib check
//file check
else
else if(YES == isFile)
{
//check if file is loaded in task
for(File* taskFile in task.files)
@@ -704,6 +717,25 @@ bail:
}
}//file check
//connection check
else if(YES == isConnection)
{
//check if connection is 'in' task
for(Connection* taskConnection in task.connections)
{
//check for task has connection
// note: ->check via endpoints, as that a good representation of connection(?)
if(YES == [taskConnection.endpoints isEqualToString: ((Connection*)item).endpoints])
{
//save
[hostTasks addObject:task];
//can bail, since match was found
break;
}
}
}
}//all tasks
@@ -7,14 +7,14 @@
<key>IDESourceControlProjectIdentifier</key>
<string>FE4103FE-6F26-4639-8C9F-D8D32C76D6A9</string>
<key>IDESourceControlProjectName</key>
<string>project</string>
<string>TaskExplorer</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>61F07AFB33748EF0C810BEEF6126283DAC63A899</key>
<string>https://bitbucket.org/objective-see/taskexplorer.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>TaskExplorer.xcodeproj/project.xcworkspace</string>
<string>TaskExplorer.xcodeproj</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>61F07AFB33748EF0C810BEEF6126283DAC63A899</key>
@@ -10,43 +10,11 @@
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "ItemView.m"
timestampString = "461741382.460449"
timestampString = "462956417.143953"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "44"
endingLineNumber = "44"
landmarkName = "createItemView()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "ItemView.m"
timestampString = "461741382.460449"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "35"
endingLineNumber = "35"
landmarkName = "createItemView()"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "ItemView.m"
timestampString = "462061810.500141"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "267"
endingLineNumber = "267"
startingLineNumber = "292"
endingLineNumber = "292"
landmarkName = "createLoadedItemView()"
landmarkType = "7">
</BreakpointContent>
@@ -74,11 +42,11 @@
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "SearchWindowController.m"
timestampString = "462871273.447907"
timestampString = "462871859.211461"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "196"
endingLineNumber = "196"
startingLineNumber = "192"
endingLineNumber = "192"
landmarkName = "-waitTillPau"
landmarkType = "5">
</BreakpointContent>
@@ -106,11 +74,11 @@
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "462870109.066579"
timestampString = "462958083.434603"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "1544"
endingLineNumber = "1544"
startingLineNumber = "1545"
endingLineNumber = "1545"
landmarkName = "-selectBottomPaneContent:"
landmarkType = "5">
</BreakpointContent>
@@ -170,47 +138,15 @@
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "462870109.066579"
timestampString = "462958083.434603"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "214"
endingLineNumber = "214"
startingLineNumber = "218"
endingLineNumber = "218"
landmarkName = "-registerKeypressHandler"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "462870109.066579"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "231"
endingLineNumber = "231"
landmarkName = "-handleKeypress:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "462870109.066579"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "252"
endingLineNumber = "252"
landmarkName = "-handleKeypress:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
@@ -259,5 +195,37 @@
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Filter.m"
timestampString = "462957835.231287"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "213"
endingLineNumber = "213"
landmarkName = "-filterConnections:items:results:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "AppDelegate.m"
timestampString = "462958621.25846"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "1507"
endingLineNumber = "1507"
landmarkName = "-selectBottomPaneContent:"
landmarkType = "5">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
+17 -4
View File
@@ -21,7 +21,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="95" y="481" width="1304" height="425"/>
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1080"/>
<value key="minSize" type="size" width="800" height="250"/>
<view key="contentView" id="se5-gp-TjO">
<rect key="frame" x="0.0" y="3" width="1304" height="425"/>
@@ -304,7 +304,7 @@
<outlet property="textField" destination="ugh-bk-muU" id="5Bo-1C-aqM"/>
</connections>
</tableCellView>
<tableCellView identifier="NetworkCell" id="waX-25-DeA" customClass="kkRowCell">
<tableCellView identifier="ConnectionCell" id="waX-25-DeA" customClass="kkRowCell">
<rect key="frame" x="0.0" y="0.0" width="1301" height="40"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
@@ -324,8 +324,8 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UR5-ag-OPP">
<rect key="frame" x="31" y="20" width="1000" height="19"/>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" ambiguous="YES" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UR5-ag-OPP">
<rect key="frame" x="31" y="20" width="229" height="19"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Network Info" id="WqN-YF-KzO">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -358,10 +358,23 @@
<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="3Oy-bR-CEo">
<rect key="frame" x="264" y="20" width="868" height="18"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="E10-59-IUU"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="loaded in" id="Ip4-Xq-eKJ">
<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="kT3-0V-Fwt" firstAttribute="leading" secondItem="71C-gs-Mno" secondAttribute="trailing" constant="8" id="5IU-du-URu"/>
<constraint firstItem="3Oy-bR-CEo" firstAttribute="leading" secondItem="UR5-ag-OPP" secondAttribute="trailing" constant="8" id="F12-0T-6Lr"/>
<constraint firstAttribute="trailing" secondItem="k5T-Yc-we2" secondAttribute="trailing" constant="19" id="JJb-oy-J0e"/>
<constraint firstAttribute="trailing" secondItem="3Oy-bR-CEo" secondAttribute="trailing" constant="171" id="S5V-cL-cnq"/>
<constraint firstItem="k5T-Yc-we2" firstAttribute="leading" secondItem="kT3-0V-Fwt" secondAttribute="trailing" constant="8" id="dOy-kF-uEl"/>
<constraint firstAttribute="trailing" secondItem="b9d-lc-cIV" secondAttribute="trailing" constant="20" id="gmk-OW-20W"/>
<constraint firstItem="71C-gs-Mno" firstAttribute="leading" secondItem="waX-25-DeA" secondAttribute="leading" constant="5" id="h2R-BV-oKU"/>