mirror of
https://github.com/objective-see/TaskExplorer.git
synced 2026-03-22 07:02:39 +00:00
changed exception handling code to use exception.callStackSymbols, which should give actual backtrace of exception finalized global search, to filter out duplicate dylibs, files, etc added 'nothing found' message to global search
343 lines
7.8 KiB
Objective-C
343 lines
7.8 KiB
Objective-C
//
|
|
// Extension.m
|
|
// TaskExplorer
|
|
//
|
|
// 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
|
|
|
|
@synthesize endpoints;
|
|
@synthesize remoteName;
|
|
|
|
//init method
|
|
-(id)initWithParams:(NSDictionary*)params
|
|
{
|
|
//super
|
|
//self = [super initWithParams:params];
|
|
self = [super init];
|
|
if(nil != self)
|
|
{
|
|
//alloc string for connection
|
|
endpoints = [NSMutableString string];
|
|
|
|
//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 = [self socketType2String:params[KEY_SOCKET_TYPE]];
|
|
|
|
//extract/save family
|
|
self.family = [self socketFamily2String:params[KEY_SOCKET_FAMILY]];
|
|
|
|
//extract/save proto
|
|
self.proto = [self socketProto2String:params[KEY_SOCKET_PROTO]];
|
|
|
|
//extract/save state
|
|
self.state = [self socketState2String:params[KEY_SOCKET_STATE]];
|
|
|
|
//set icon
|
|
[self setConnectionIcon];
|
|
|
|
//resolve DNS names
|
|
if(nil != self.remoteIPAddr)
|
|
{
|
|
//resolve
|
|
[self addressesForHost];
|
|
}
|
|
|
|
//build/set connection string
|
|
[self setConnectionString];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
//set icon
|
|
// ->based on state
|
|
-(void)setConnectionIcon
|
|
{
|
|
//set icon for TCP sockets
|
|
if(nil != self.state)
|
|
{
|
|
//listening
|
|
if(YES == [self.state isEqualToString:@"listening"])
|
|
{
|
|
//set
|
|
self.icon = [NSImage imageNamed:@"listeningIcon"];
|
|
}
|
|
//connected
|
|
else if(YES == [self.state isEqualToString:@"established"])
|
|
{
|
|
//set
|
|
self.icon = [NSImage imageNamed:@"connectedIcon"];
|
|
}
|
|
//wait related states
|
|
else if( (YES == [self.state isEqualToString:@"close/wait"]) ||
|
|
(YES == [self.state isEqualToString:@"in wait 1"]) ||
|
|
(YES == [self.state isEqualToString:@"closing"]) ||
|
|
(YES == [self.state isEqualToString:@"last act"]) ||
|
|
(YES == [self.state isEqualToString:@"fin wait 2"]) ||
|
|
(YES == [self.state isEqualToString:@"time wait"]) )
|
|
{
|
|
//set
|
|
self.icon = [NSImage imageNamed:@"closeWait"];
|
|
}
|
|
|
|
//closed
|
|
else if(YES == [self.state isEqualToString:@"closed"])
|
|
{
|
|
//set
|
|
self.icon = [NSImage imageNamed:@"closedIcon"];
|
|
}
|
|
}
|
|
|
|
//set icon for UDP sockets
|
|
// ->can't listen, so just show 'em as streaming
|
|
else if(YES == [self.type isEqualToString:@"SOCK_DGRAM"])
|
|
{
|
|
//set
|
|
self.icon = [NSImage imageNamed:@"streamIcon"];
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//resolve a remote IP address to nice DNS name
|
|
// ->uses address and port, which are passed to getaddrinfo
|
|
// note: call from bg thread, cuz it can be slow due to DNS resolution(s)
|
|
-(void)addressesForHost
|
|
{
|
|
//host
|
|
NSHost* host = nil;
|
|
|
|
//init host
|
|
host = [NSHost hostWithAddress:self.remoteIPAddr];
|
|
|
|
//extract/save name
|
|
self.remoteName = host.name;
|
|
|
|
return;
|
|
}
|
|
|
|
//convert a socket type into string
|
|
-(NSString*) socketType2String:(NSNumber*)type
|
|
{
|
|
//socket type
|
|
NSString* socketType = nil;
|
|
|
|
//convert
|
|
switch(type.intValue)
|
|
{
|
|
//stream
|
|
case SOCK_STREAM:
|
|
socketType = @"SOCK_STREAM";
|
|
break;
|
|
|
|
//dgram
|
|
case SOCK_DGRAM:
|
|
socketType = @"SOCK_DGRAM";
|
|
break;
|
|
|
|
//raw
|
|
case SOCK_RAW:
|
|
socketType = @"SOCK_RAW";
|
|
break;
|
|
|
|
//rdm
|
|
case SOCK_RDM:
|
|
socketType = @"SOCK_RDM";
|
|
break;
|
|
|
|
//seq packet
|
|
case SOCK_SEQPACKET:
|
|
socketType = @"SOCK_SEQPACKET";
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return socketType;
|
|
}
|
|
|
|
|
|
//convert a socket family into string
|
|
-(NSString*) socketFamily2String:(NSNumber*)family
|
|
{
|
|
//socket family
|
|
NSString* socketFamily = nil;
|
|
|
|
//sanity check
|
|
if( (family.intValue < 0) ||
|
|
(family.intValue >= SOCKET_FAMILY_MAX) )
|
|
{
|
|
//bail
|
|
goto bail;
|
|
}
|
|
|
|
//init socket family string
|
|
socketFamily = [NSString stringWithUTF8String:socketFamilies[family.intValue]];
|
|
|
|
//bail
|
|
bail:
|
|
|
|
return socketFamily;
|
|
}
|
|
|
|
//convert a socket protocol into string
|
|
-(NSString*) socketProto2String:(NSNumber*)proto
|
|
{
|
|
//socket proto
|
|
NSString* socketProto = nil;
|
|
|
|
//proto struct
|
|
struct protoent *protoInfo = NULL;
|
|
|
|
//get proto info
|
|
protoInfo = getprotobynumber(proto.intValue);
|
|
|
|
//sanity check
|
|
if(NULL == protoInfo)
|
|
{
|
|
//bail
|
|
goto bail;
|
|
}
|
|
|
|
//init proto string
|
|
// ->name comes from struct
|
|
socketProto = [NSString stringWithUTF8String:protoInfo->p_name];
|
|
|
|
//bail
|
|
bail:
|
|
|
|
return socketProto;
|
|
}
|
|
|
|
|
|
//convert a socket state into string
|
|
-(NSString*) socketState2String:(NSNumber*)state
|
|
{
|
|
//socket proto
|
|
NSString* socketState = nil;
|
|
|
|
//set state
|
|
if(state.intValue < TCP_NSTATES)
|
|
{
|
|
//set state
|
|
socketState = [NSString stringWithUTF8String:socketStates[state.intValue]];
|
|
}
|
|
//invalid/unknown socket state
|
|
else
|
|
{
|
|
socketState = [NSString stringWithFormat:@"unknown state (%d)", state.intValue];
|
|
}
|
|
|
|
return socketState;
|
|
}
|
|
|
|
//build printable connection string
|
|
-(void)setConnectionString
|
|
{
|
|
//add local addr/port to endpoint string
|
|
[self.endpoints appendString:[NSString stringWithFormat:@"%@:%d", self.localIPAddr, [self.localPort unsignedShortValue]]];
|
|
|
|
//for remote connections
|
|
// ->add remote endpoint
|
|
if( (nil != self.remoteIPAddr) &&
|
|
(nil != self.remotePort) )
|
|
{
|
|
//add remote IP:port
|
|
[self.endpoints appendString:[NSString stringWithFormat:@" -> %@:%d", self.remoteIPAddr, [self.remotePort unsignedShortValue]]];
|
|
|
|
//add DNS name
|
|
if(nil != self.remoteName)
|
|
{
|
|
//add
|
|
[self.endpoints appendString:[NSString stringWithFormat:@" (%@)", self.remoteName]];
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//override method
|
|
// ->hash
|
|
-(NSUInteger)hash
|
|
{
|
|
return [self.endpoints hash];
|
|
}
|
|
|
|
//override method
|
|
// ->equality check
|
|
-(BOOL)isEqual:(id)object
|
|
{
|
|
//flag
|
|
BOOL objEqual = NO;
|
|
|
|
//check self
|
|
if(self == object)
|
|
{
|
|
//match
|
|
objEqual = YES;
|
|
|
|
//bail
|
|
goto bail;
|
|
}
|
|
|
|
//check for type
|
|
if(YES != [object isKindOfClass:[Connection class]])
|
|
{
|
|
//no match
|
|
objEqual = NO;
|
|
|
|
//bail
|
|
goto bail;
|
|
}
|
|
|
|
//do check
|
|
if(YES == [((Connection*)object).endpoints isEqualToString:self.endpoints])
|
|
{
|
|
//happy
|
|
objEqual = YES;
|
|
|
|
//bail
|
|
goto bail;
|
|
}
|
|
|
|
//bail
|
|
bail:
|
|
|
|
return objEqual;
|
|
}
|
|
|
|
|
|
|
|
//convert Connection object to a JSON string
|
|
-(NSString*)toJSON
|
|
{
|
|
//json string
|
|
NSString *json = nil;
|
|
|
|
//init json
|
|
json = [NSString stringWithFormat:@"\"connection\": \"%@\", \"local IP\": \"%@\", \"local port\": \"%d\", \"remote IP\": \"%@\", \"remote port\": \"%d\", \"type\": \"%@\", \"family\": \"%@\", \"protocol\": \"%@\", \"state\": \"%@\"", self.endpoints, self.localIPAddr, [self.localPort unsignedShortValue], self.remoteIPAddr, [self.remotePort unsignedShortValue], self.type, self.family, self.proto, self.state];
|
|
|
|
return json;
|
|
}
|
|
|
|
@end
|