mirror of
https://github.com/objective-see/KnockKnock.git
synced 2026-03-22 06:52:25 +00:00
project cleanup, improved packer detection, UI / cmdline scan improvements
This commit is contained in:
@@ -44,9 +44,6 @@ extern Filter* itemFilter;
|
||||
//welcome view controller
|
||||
@property(nonatomic, retain)WelcomeWindowController* welcomeWindowController;
|
||||
|
||||
//friends
|
||||
@property (weak) IBOutlet NSWindow* friends;
|
||||
|
||||
//close button
|
||||
@property (weak) IBOutlet NSButton* closeButton;
|
||||
|
||||
|
||||
+15
-37
@@ -13,9 +13,12 @@
|
||||
//TODO: support delete items
|
||||
//TODO: search in UI
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
NSString* scanID = nil;
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
@synthesize friends;
|
||||
@synthesize plugins;
|
||||
@synthesize scanButton;
|
||||
@synthesize isConnected;
|
||||
@@ -35,6 +38,7 @@
|
||||
@synthesize resultsWindowController;
|
||||
@synthesize welcomeWindowController;
|
||||
|
||||
|
||||
//exception handler
|
||||
// show alert and log error
|
||||
void uncaughtExceptionHandler(NSException* exception) {
|
||||
@@ -124,13 +128,11 @@ void uncaughtExceptionHandler(NSException* exception) {
|
||||
//alloc shared item enumerator
|
||||
sharedItemEnumerator = [[ItemEnumerator alloc] init];
|
||||
|
||||
//request access
|
||||
//check/request for FDA
|
||||
// delay, so UI completes rendering
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 100 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
|
||||
|
||||
//request access
|
||||
[self requestFDA];
|
||||
|
||||
//request access
|
||||
[self requestFDA];
|
||||
});
|
||||
|
||||
//check for update
|
||||
@@ -199,35 +201,6 @@ void uncaughtExceptionHandler(NSException* exception) {
|
||||
|
||||
}
|
||||
|
||||
//close 'friends' window
|
||||
-(IBAction)closeFriendsWindow:(id)sender
|
||||
{
|
||||
//close to hide
|
||||
[self.friends close];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//window close handler
|
||||
-(void)windowWillClose:(NSNotification *)notification {
|
||||
|
||||
//closing friends window?
|
||||
// request full disk access
|
||||
if(self.friends == notification.object)
|
||||
{
|
||||
//request access
|
||||
// delay ensures (friends) window will close
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (100 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
|
||||
|
||||
//request access
|
||||
[self requestFDA];
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//automatically close when user closes last window
|
||||
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
|
||||
{
|
||||
@@ -419,6 +392,9 @@ void uncaughtExceptionHandler(NSException* exception) {
|
||||
// ->also shared enumerator thread (if needed)
|
||||
-(void)startScan
|
||||
{
|
||||
//scan ID
|
||||
scanID = [[NSUUID UUID] UUIDString];
|
||||
|
||||
//alloc scanner thread
|
||||
scannerThread = [[NSThread alloc] initWithTarget:self selector:@selector(scan) object:nil];
|
||||
|
||||
@@ -800,6 +776,9 @@ void uncaughtExceptionHandler(NSException* exception) {
|
||||
// ->ensures various threads are terminated, etc
|
||||
-(void)completeScan
|
||||
{
|
||||
//reset scan ID
|
||||
scanID = nil;
|
||||
|
||||
//tell enumerator to stop
|
||||
[sharedItemEnumerator stop];
|
||||
|
||||
@@ -1165,7 +1144,6 @@ void uncaughtExceptionHandler(NSException* exception) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
//show 'save file' popup
|
||||
// ->user clicks ok, save results (JSON) to disk
|
||||
-(IBAction)saveResults:(id)sender
|
||||
@@ -1215,7 +1193,7 @@ void uncaughtExceptionHandler(NSException* exception) {
|
||||
else
|
||||
{
|
||||
//err msg
|
||||
NSLog(@"ERROR: saving output to %@ failed with %@", [panel URL], error);
|
||||
//NSLog(@"ERROR: saving output to %@ failed with %@", panel.URL, error);
|
||||
|
||||
//init alert
|
||||
alert = [[NSAlert alloc] init];
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<window title="KnockKnock" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="371" userLabel="Main Window">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<rect key="contentRect" x="0.0" y="0.0" width="1295" height="671"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1280" height="769"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="3440" height="1409"/>
|
||||
<value key="minSize" type="size" width="1000" height="597"/>
|
||||
<value key="maxSize" type="size" width="2500" height="1000"/>
|
||||
<view key="contentView" id="372">
|
||||
@@ -202,7 +202,7 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="577">
|
||||
<rect key="frame" x="5" y="-2" width="50" height="61"/>
|
||||
<rect key="frame" x="5" y="-2" width="50" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="kB1-L8-KFN"/>
|
||||
<constraint firstAttribute="width" constant="50" id="wxT-p0-paD"/>
|
||||
@@ -452,14 +452,14 @@
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="kkText" id="r1Z-Hx-M6T"/>
|
||||
</imageView>
|
||||
<progressIndicator hidden="YES" horizontalHuggingPriority="750" verticalHuggingPriority="750" maxValue="100" bezeled="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="839">
|
||||
<rect key="frame" x="1255" y="10" width="32" height="32"/>
|
||||
<rect key="frame" x="1255" y="8" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="5xq-yG-SSJ"/>
|
||||
<constraint firstAttribute="height" constant="32" id="aeM-9z-lBy"/>
|
||||
</constraints>
|
||||
</progressIndicator>
|
||||
<textField hidden="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="745">
|
||||
<rect key="frame" x="1160" y="16" width="75" height="18"/>
|
||||
<rect key="frame" x="1160" y="13" width="75" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="18" id="1aa-3i-5H9"/>
|
||||
</constraints>
|
||||
@@ -672,11 +672,11 @@
|
||||
<constraint firstItem="3Vf-uL-OZX" firstAttribute="leading" secondItem="372" secondAttribute="leading" constant="107" id="YFa-JP-po1"/>
|
||||
<constraint firstAttribute="bottom" secondItem="gmd-EM-xEi" secondAttribute="bottom" constant="1" id="YMB-QL-QqB"/>
|
||||
<constraint firstItem="655" firstAttribute="centerX" secondItem="x7S-Ww-gLm" secondAttribute="centerX" id="bPe-nc-G8S"/>
|
||||
<constraint firstAttribute="bottom" secondItem="745" secondAttribute="bottom" constant="16" id="c9W-7d-MXn"/>
|
||||
<constraint firstAttribute="bottom" secondItem="745" secondAttribute="bottom" constant="13" id="c9W-7d-MXn"/>
|
||||
<constraint firstAttribute="bottom" secondItem="rqX-FA-o3e" secondAttribute="bottom" constant="52" id="drt-dw-JrT"/>
|
||||
<constraint firstItem="536" firstAttribute="leading" secondItem="rqX-FA-o3e" secondAttribute="trailing" constant="32" id="gzW-um-0eE"/>
|
||||
<constraint firstItem="5uI-IQ-e40" firstAttribute="leading" secondItem="372" secondAttribute="leading" constant="12" id="hwa-cU-Pnd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="839" secondAttribute="bottom" constant="10" id="ibd-gt-Ml2"/>
|
||||
<constraint firstAttribute="bottom" secondItem="839" secondAttribute="bottom" constant="8" id="ibd-gt-Ml2"/>
|
||||
<constraint firstAttribute="trailing" secondItem="KxO-Jf-gyu" secondAttribute="trailing" constant="-8" id="isR-LB-Ezc"/>
|
||||
<constraint firstItem="rqX-FA-o3e" firstAttribute="top" secondItem="372" secondAttribute="top" constant="151" id="j4C-hj-Nqa"/>
|
||||
<constraint firstItem="gmd-EM-xEi" firstAttribute="firstBaseline" secondItem="eJj-oN-VA2" secondAttribute="firstBaseline" constant="-1" id="jRI-Gh-Q9E"/>
|
||||
@@ -722,7 +722,7 @@
|
||||
<resources>
|
||||
<image name="Compare" width="128" height="128"/>
|
||||
<image name="CompareAlternate" width="128" height="128"/>
|
||||
<image name="NSActionTemplate" width="20" height="20"/>
|
||||
<image name="NSActionTemplate" width="19" height="19"/>
|
||||
<image name="NSColorPanel" width="32" height="32"/>
|
||||
<image name="Preferences" width="128" height="128"/>
|
||||
<image name="PreferencesAlternate" width="128" height="128"/>
|
||||
|
||||
@@ -448,8 +448,6 @@
|
||||
CD6FD7AB2C7AAD87001C59F2 /* MainMenu.xib */,
|
||||
CD5854D621A60B2000A438B0 /* PlistWindowController.h */,
|
||||
CD5854D721A60B2000A438B0 /* PlistWindowController.m */,
|
||||
CDF08CC71AC4C678009B3423 /* PrefsWindowController.h */,
|
||||
CDF08CC81AC4C678009B3423 /* PrefsWindowController.m */,
|
||||
CD24F076219DF3DB0081B0E5 /* Signing.h */,
|
||||
CD24F075219DF3DA0081B0E5 /* Signing.m */,
|
||||
1D21BC55172AF43D009D1CFD /* Supporting Files */,
|
||||
@@ -541,13 +539,13 @@
|
||||
CD0219511AD34D9A005148A2 /* AboutWindowController.h */,
|
||||
CD0219521AD34D9A005148A2 /* AboutWindowController.m */,
|
||||
CDA81D751A95B7C1009790E2 /* CategoryTableController.h */,
|
||||
CD5A5F7B2EB95C0C00F5068F /* WelcomeWindowController.h */,
|
||||
CD5A5F7C2EB95C0C00F5068F /* WelcomeWindowController.m */,
|
||||
CDA81D761A95B7C1009790E2 /* CategoryTableController.m */,
|
||||
CDA81DE71A997BF1009790E2 /* InfoWindowController.h */,
|
||||
CDA81DE81A997BF1009790E2 /* InfoWindowController.m */,
|
||||
CDA81D791A95D29B009790E2 /* ItemTableController.h */,
|
||||
CDA81D7A1A95D29B009790E2 /* ItemTableController.m */,
|
||||
CDF08CC71AC4C678009B3423 /* PrefsWindowController.h */,
|
||||
CDF08CC81AC4C678009B3423 /* PrefsWindowController.m */,
|
||||
CD02195F1AD39A83005148A2 /* ResultsWindowController.h */,
|
||||
CD0219601AD39A83005148A2 /* ResultsWindowController.m */,
|
||||
CD792FBA2D2530A800167649 /* UnknownItemsWindowController.h */,
|
||||
@@ -556,6 +554,8 @@
|
||||
CD2F21A321A8A7E300F67A83 /* UpdateWindowController.m */,
|
||||
CDF08CDC1AC886F2009B3423 /* VTInfoWindowController.h */,
|
||||
CDF08CDD1AC886F2009B3423 /* VTInfoWindowController.m */,
|
||||
CD5A5F7B2EB95C0C00F5068F /* WelcomeWindowController.h */,
|
||||
CD5A5F7C2EB95C0C00F5068F /* WelcomeWindowController.m */,
|
||||
);
|
||||
name = UIControllers;
|
||||
sourceTree = "<group>";
|
||||
|
||||
@@ -729,7 +729,7 @@ bail:
|
||||
//NSLog(@"final calc: %f\n", (1.0 * totalCompressedData)/fileData.length);
|
||||
|
||||
//final calculation for architecture
|
||||
if( ((1.0 * totalCompressedData)/fileData.length) > .2)
|
||||
if( ((1.0 * totalCompressedData)/fileData.length) > .25)
|
||||
{
|
||||
//set
|
||||
packed = YES;
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"'%@' isn't known to VirusTotal" : {
|
||||
"comment" : "'%@' isn't known to VirusTotal"
|
||||
},
|
||||
"a new version (%@) is available!" : {
|
||||
"comment" : "a new version (%@) is available!",
|
||||
"localizations" : {
|
||||
@@ -211,6 +214,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"ERROR: %@" : {
|
||||
"comment" : "ERROR: %@"
|
||||
},
|
||||
"ERROR: Failed to compare scans" : {
|
||||
"comment" : "ERROR: Failed to compare scans",
|
||||
"localizations" : {
|
||||
@@ -268,6 +274,7 @@
|
||||
},
|
||||
"failed to submit '%@' to VirusTotal (HTTP response %ld)." : {
|
||||
"comment" : "failed to submit '%@' to VirusTotal (HTTP response %ld).",
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
@@ -410,6 +417,7 @@
|
||||
},
|
||||
"No results found for '%@'" : {
|
||||
"comment" : "No results found for '%@'",
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
@@ -591,6 +599,7 @@
|
||||
},
|
||||
"Submitting '%@'" : {
|
||||
"comment" : "Submitting '%@'",
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
@@ -600,6 +609,9 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Submitting '%@'..." : {
|
||||
"comment" : "Submitting '%@'..."
|
||||
},
|
||||
"This allows the app to perform a comprehensive scan.\n\nIn System Preferences:\r ▪ Click the 🔒 to authenticate\r ▪ Click the ➕ to add KnockKnock.app\n" : {
|
||||
"comment" : "This allows the app to perform a comprehensive scan.\n\nIn System Preferences:\r ▪ Click the 🔒 to authenticate\r ▪ Click the ➕ to add KnockKnock.app\n",
|
||||
"extractionState" : "stale",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button hidden="YES" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Czs-Di-8Qw">
|
||||
<rect key="frame" x="400" y="24" width="168" height="33"/>
|
||||
<rect key="frame" x="400" y="26" width="168" height="33"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="View/Submit Items" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="71T-dO-S3a">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="UnknownItemsWindowController">
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="YFJ-fV-od8" id="0dA-VM-qhD"/>
|
||||
<outlet property="errorLabel" destination="Jld-3V-iRi" id="D9y-8x-9UR"/>
|
||||
<outlet property="errorPopover" destination="Y6l-tV-hl3" id="ek9-gu-D84"/>
|
||||
<outlet property="statusLabel" destination="cRD-QV-kp1" id="iww-ot-hR2"/>
|
||||
<outlet property="submit" destination="p2q-DR-J4n" id="V3O-dR-GsD"/>
|
||||
<outlet property="tableView" destination="4WG-Qw-U3m" id="n74-y3-lGx"/>
|
||||
@@ -19,21 +21,21 @@
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Unknown Items" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="pvW-8N-g8T">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<rect key="contentRect" x="403" y="305" width="643" height="339"/>
|
||||
<rect key="contentRect" x="403" y="305" width="643" height="398"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="3440" height="1409"/>
|
||||
<value key="minSize" type="size" width="643" height="339"/>
|
||||
<view key="contentView" id="XBF-k3-Nqu">
|
||||
<rect key="frame" x="0.0" y="0.0" width="643" height="339"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="643" height="398"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<scrollView autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mif-DC-CkF">
|
||||
<rect key="frame" x="1" y="62" width="643" height="278"/>
|
||||
<rect key="frame" x="1" y="62" width="643" height="284"/>
|
||||
<clipView key="contentView" id="I4Y-ET-V9m">
|
||||
<rect key="frame" x="1" y="1" width="641" height="276"/>
|
||||
<rect key="frame" x="1" y="1" width="641" height="282"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" alternatingRowBackgroundColors="YES" columnReordering="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="24" rowSizeStyle="large" headerView="mTM-rz-bsn" viewBased="YES" id="4WG-Qw-U3m">
|
||||
<rect key="frame" x="0.0" y="0.0" width="723" height="253"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="723" height="259"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@@ -55,7 +57,7 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button tag="1001" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SKb-o1-3O3">
|
||||
<rect key="frame" x="15" y="-3" width="29" height="18"/>
|
||||
<rect key="frame" x="15" y="-4" width="29" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="D3n-cB-7oB">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
@@ -93,6 +95,17 @@
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button tag="100" horizontalHuggingPriority="750" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Eqw-zW-Xa6">
|
||||
<rect key="frame" x="128" y="-3" width="16" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="help" bezelStyle="helpButton" alignment="center" controlSize="mini" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="YT4-vu-LOM">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="showErrorInfo:" target="-2" id="vfR-ay-JhZ"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<connections>
|
||||
<outlet property="textField" destination="Cay-Kj-Uc7" id="FJh-s6-D19"/>
|
||||
@@ -140,7 +153,7 @@
|
||||
</subviews>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="yyw-5X-sLC">
|
||||
<rect key="frame" x="1" y="260" width="641" height="17"/>
|
||||
<rect key="frame" x="1" y="266" width="641" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="gLe-AJ-eSK">
|
||||
@@ -167,13 +180,24 @@
|
||||
</connections>
|
||||
</button>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="cRD-QV-kp1">
|
||||
<rect key="frame" x="18" y="22" width="451" height="15"/>
|
||||
<rect key="frame" x="18" y="14" width="451" height="23"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="447" id="4L7-sa-Vav"/>
|
||||
<constraint firstAttribute="height" constant="15" id="HnK-1f-VOM"/>
|
||||
<constraint firstAttribute="height" constant="23" id="HnK-1f-VOM"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="left" id="on5-Un-vIc">
|
||||
<font key="font" size="13" name="Menlo-Regular"/>
|
||||
<font key="font" size="15" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MQ5-hC-zTd">
|
||||
<rect key="frame" x="20" y="354" width="605" height="37"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" id="061-1p-frg">
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="title">These items aren’t known to VirusTotal.
|
||||
Submitting them will upload the file to VirusTotal and open the resulting report in your browser.</string>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
@@ -188,19 +212,35 @@
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="mif-DC-CkF" secondAttribute="bottom" constant="62" id="00d-ob-Zdf"/>
|
||||
<constraint firstItem="mif-DC-CkF" firstAttribute="top" secondItem="XBF-k3-Nqu" secondAttribute="top" constant="-1" id="5wD-mE-WXa"/>
|
||||
<constraint firstItem="mif-DC-CkF" firstAttribute="top" secondItem="XBF-k3-Nqu" secondAttribute="top" constant="52" id="5wD-mE-WXa"/>
|
||||
<constraint firstItem="cRD-QV-kp1" firstAttribute="top" secondItem="mif-DC-CkF" secondAttribute="bottom" constant="25" id="9WZ-Bk-4uo"/>
|
||||
<constraint firstAttribute="trailing" secondItem="mif-DC-CkF" secondAttribute="trailing" constant="-1" id="CVV-X1-Kle"/>
|
||||
<constraint firstItem="cRD-QV-kp1" firstAttribute="leading" secondItem="XBF-k3-Nqu" secondAttribute="leading" constant="20" symbolic="YES" id="Cdy-dt-0gQ"/>
|
||||
<constraint firstItem="p2q-DR-J4n" firstAttribute="leading" secondItem="YFJ-fV-od8" secondAttribute="trailing" constant="16" id="FAn-FO-wk7"/>
|
||||
<constraint firstAttribute="bottom" secondItem="p2q-DR-J4n" secondAttribute="bottom" constant="20" symbolic="YES" id="L3W-cR-gQ9"/>
|
||||
<constraint firstAttribute="trailing" secondItem="p2q-DR-J4n" secondAttribute="trailing" constant="20" symbolic="YES" id="L9H-Gd-eDN"/>
|
||||
<constraint firstAttribute="bottom" secondItem="cRD-QV-kp1" secondAttribute="bottom" constant="22" id="XnE-Kt-4pq"/>
|
||||
<constraint firstAttribute="bottom" secondItem="cRD-QV-kp1" secondAttribute="bottom" constant="14" id="XnE-Kt-4pq"/>
|
||||
<constraint firstItem="mif-DC-CkF" firstAttribute="leading" secondItem="XBF-k3-Nqu" secondAttribute="leading" constant="1" id="h6B-Mm-oRi"/>
|
||||
<constraint firstAttribute="bottom" secondItem="YFJ-fV-od8" secondAttribute="bottom" constant="14" id="qWW-n0-w6s"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-8.5" y="28.5"/>
|
||||
<point key="canvasLocation" x="-8.5" y="-1"/>
|
||||
</window>
|
||||
<customView id="Y6l-tV-hl3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="479" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<subviews>
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jld-3V-iRi">
|
||||
<rect key="frame" x="18" y="15" width="447" height="67"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" selectable="YES" title="Error info:" id="bDg-MW-e9L">
|
||||
<font key="font" size="11" name="Menlo-Regular"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<point key="canvasLocation" x="47" y="363"/>
|
||||
</customView>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
@@ -19,6 +19,30 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"061-1p-frg.title" : {
|
||||
"comment" : "Class = \"NSTextFieldCell\"; title = \"These items aren’t known to VirusTotal. \\nSubmitting them will upload the file to VirusTotal and open the resulting report in your browser.\"; ObjectID = \"061-1p-frg\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "These items aren’t known to VirusTotal. \nSubmitting them will upload the file to VirusTotal and open the resulting report in your browser."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"bDg-MW-e9L.title" : {
|
||||
"comment" : "Class = \"NSTextFieldCell\"; title = \"Error info:\"; ObjectID = \"bDg-MW-e9L\";",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "Error info:"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"G1q-Ag-u0M.title" : {
|
||||
"comment" : "Class = \"NSButtonCell\"; title = \"View\"; ObjectID = \"G1q-Ag-u0M\";",
|
||||
"extractionState" : "stale",
|
||||
|
||||
@@ -32,6 +32,13 @@
|
||||
//status label
|
||||
@property (weak) IBOutlet NSTextField *statusLabel;
|
||||
|
||||
//error
|
||||
@property (strong) IBOutlet NSView *errorPopover;
|
||||
|
||||
//error label
|
||||
@property (weak) IBOutlet NSTextField *errorLabel;
|
||||
|
||||
|
||||
/* METHODS */
|
||||
|
||||
//checkbox button handler
|
||||
|
||||
@@ -102,6 +102,10 @@
|
||||
//result
|
||||
NSDictionary* result = self.results[@(row)];
|
||||
|
||||
//erorr button
|
||||
NSButton* moreInfo = (NSButton*)[cell viewWithTag:100];
|
||||
moreInfo.hidden = YES;
|
||||
|
||||
//nothing
|
||||
if(!result.count) {
|
||||
|
||||
@@ -117,6 +121,9 @@
|
||||
cell.textField.stringValue = @"Failed to Submit";
|
||||
cell.textField.toolTip = [NSString stringWithFormat:@"ERROR: %@", result[VT_ERROR]];
|
||||
|
||||
//show button
|
||||
moreInfo.hidden = NO;
|
||||
|
||||
}
|
||||
//ok
|
||||
else
|
||||
@@ -125,21 +132,29 @@
|
||||
cell.textField.toolTip = @"";
|
||||
cell.textField.stringValue = @"Submitted";
|
||||
|
||||
//already viewed?
|
||||
// no need to show again
|
||||
if(result[VT_REPORT_VIEWED]) {
|
||||
break;
|
||||
}
|
||||
|
||||
//got response?
|
||||
// launch browser to show user
|
||||
if(nil != result[VT_RESULTS_URL])
|
||||
{
|
||||
//update result to note we've shown report
|
||||
NSMutableDictionary* updatedResults = [result mutableCopy];
|
||||
updatedResults[VT_REPORT_VIEWED] = @(YES);
|
||||
|
||||
self.results[@(row)] = updatedResults;
|
||||
|
||||
//launch browser to show new report
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
//launch browser
|
||||
[NSWorkspace.sharedWorkspace openURL:[NSURL URLWithString:result[VT_RESULTS_URL]]];
|
||||
|
||||
|
||||
});
|
||||
|
||||
//wait to browser is up and happy
|
||||
[NSThread sleepForTimeInterval:0.5];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +175,47 @@
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (IBAction)showErrorInfo:(id)sender
|
||||
{
|
||||
|
||||
//get the row for this button
|
||||
NSInteger row = [self.tableView rowForView:sender];
|
||||
if (row == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//get the result for this row
|
||||
NSDictionary* result = self.results[@(row)];
|
||||
if (!result)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//popover
|
||||
NSPopover *popover = [[NSPopover alloc] init];
|
||||
|
||||
//view controller
|
||||
NSViewController *viewController = [[NSViewController alloc] init];
|
||||
|
||||
//set view
|
||||
viewController.view = self.errorPopover;
|
||||
|
||||
//set text
|
||||
self.errorLabel.stringValue = [NSString stringWithFormat:@"ERROR: %@", result[VT_ERROR]];
|
||||
|
||||
//init
|
||||
popover.contentViewController = viewController;
|
||||
popover.behavior = NSPopoverBehaviorTransient;
|
||||
|
||||
//show relative to the button
|
||||
[popover showRelativeToRect:[sender bounds]
|
||||
ofView:sender
|
||||
preferredEdge:NSRectEdgeMaxY];
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//automatically invoked when user checks/unchecks checkbox in row
|
||||
// enable/disable command state, plus handle some other button logic
|
||||
-(IBAction)toggleTest:(NSButton*)sender
|
||||
@@ -267,7 +323,7 @@
|
||||
}
|
||||
|
||||
//set status
|
||||
self.statusLabel.stringValue = [NSString stringWithFormat:NSLocalizedString(@"Submitting '%@'", @"Submitting '%@'"), ((File*)item).name];
|
||||
self.statusLabel.stringValue = [NSString stringWithFormat:NSLocalizedString(@"Submitting '%@'...", @"Submitting '%@'..."), ((File*)item).name];
|
||||
|
||||
//inc
|
||||
submittedItems++;
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
self.analysisURL.hidden = YES;
|
||||
|
||||
//set unknown file msg
|
||||
[self.unknownFile setStringValue:[NSString stringWithFormat:NSLocalizedString(@"No results found for '%@'", @"No results found for '%@'"), self.fileObj.name]];
|
||||
[self.unknownFile setStringValue:[NSString stringWithFormat:NSLocalizedString(@"'%@' isn't known to VirusTotal", @"'%@' isn't known to VirusTotal"), self.fileObj.name]];
|
||||
|
||||
//show 'unknown file' msg
|
||||
self.unknownFile.hidden = NO;
|
||||
@@ -312,14 +312,13 @@
|
||||
else {
|
||||
|
||||
//err msg
|
||||
NSLog(@"ERROR: %@", result[VT_ERROR]);
|
||||
//NSLog(@"ERROR: %@", result[VT_ERROR]);
|
||||
|
||||
//show error msg
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
||||
//TODO:
|
||||
//update status msg
|
||||
[self.statusMsg setStringValue:[NSString stringWithFormat:NSLocalizedString(@"failed to submit '%@' to VirusTotal (HTTP response %ld).", @"failed to submit '%@' to VirusTotal (HTTP response %ld)."), self.fileObj.name, [(NSHTTPURLResponse *)result[VT_HTTP_RESPONSE] statusCode]]];
|
||||
[self.statusMsg setStringValue:[NSString stringWithFormat:NSLocalizedString(@"ERROR: %@", @"ERROR: %@"), result[VT_ERROR]]];
|
||||
|
||||
//stop activity indicator
|
||||
[self.progressIndicator stopAnimation:nil];
|
||||
|
||||
+57
-11
@@ -18,21 +18,50 @@
|
||||
//cmdline flag
|
||||
extern BOOL cmdlineMode;
|
||||
|
||||
@implementation VirusTotal
|
||||
extern NSString* scanID;
|
||||
|
||||
@implementation VirusTotal
|
||||
|
||||
//ask VT about all files for a given plugin
|
||||
// note: always skips Apple binaries, as these won't be malware, and API keys usually rate limited
|
||||
-(void)checkFiles:(PluginBase*)plugin apiKey:(NSString*)apiKey uiMode:(BOOL)uiMode completion:(void(^)(void))completion {
|
||||
-(void)checkFiles:(PluginBase*)plugin apiKey:(NSString*)apiKey uiMode:(BOOL)uiMode completion:(void(^)(void))completion
|
||||
{
|
||||
//grab scan id
|
||||
NSString* currentScanID = scanID;
|
||||
|
||||
//cmdline verbose mode
|
||||
BOOL isVerbose = NO;
|
||||
|
||||
//make a snapshot
|
||||
// prevents issues if scan was (re)started
|
||||
NSArray* items = nil;
|
||||
@synchronized(plugin.allItems) {
|
||||
items = [plugin.allItems copy];
|
||||
}
|
||||
|
||||
//sanity check
|
||||
if(!plugin.allItems.count) {
|
||||
if(!items.count) {
|
||||
if(completion) completion();
|
||||
return;
|
||||
}
|
||||
|
||||
//for error msg
|
||||
if( (!uiMode) &&
|
||||
([NSProcessInfo.processInfo.arguments containsObject:@"-verbose"]) )
|
||||
{
|
||||
isVerbose = YES;
|
||||
}
|
||||
|
||||
//all items in the plugin
|
||||
for(ItemBase* item in plugin.allItems) {
|
||||
for(ItemBase* item in items) {
|
||||
|
||||
//check if scan was stopped restarted
|
||||
if( uiMode &&
|
||||
![currentScanID isEqualToString:scanID])
|
||||
{
|
||||
if(completion) completion();
|
||||
return;
|
||||
}
|
||||
|
||||
//skip non-file items
|
||||
if(![item isKindOfClass:[File class]]) {
|
||||
@@ -53,6 +82,9 @@ extern BOOL cmdlineMode;
|
||||
continue;
|
||||
}
|
||||
|
||||
//TODO: remove
|
||||
if(![file.name isEqualToString:@"orbit"]) continue;
|
||||
|
||||
//semaphore for synchronous request
|
||||
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
||||
|
||||
@@ -68,7 +100,11 @@ extern BOOL cmdlineMode;
|
||||
NSURLSessionDataTask* task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||
|
||||
if (error) {
|
||||
NSLog(@"VirusTotal ERROR: %@", error.localizedDescription);
|
||||
|
||||
//err msg
|
||||
if(isVerbose) {
|
||||
printf("\nERROR (VirusTotal): %s\n", error.localizedDescription.UTF8String);
|
||||
}
|
||||
|
||||
//signal
|
||||
dispatch_semaphore_signal(sema);
|
||||
@@ -81,8 +117,11 @@ extern BOOL cmdlineMode;
|
||||
//401 is API key issue
|
||||
if (httpResponse.statusCode == 401) {
|
||||
|
||||
NSLog(@"VirusTotal ERROR: API key %@ is not valid", apiKey);
|
||||
|
||||
//err msg
|
||||
if(isVerbose) {
|
||||
printf("\nERROR (VirusTotal): API key %s issue (not valid?)\n", apiKey.UTF8String);
|
||||
}
|
||||
|
||||
if(uiMode) {
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
@@ -104,8 +143,7 @@ extern BOOL cmdlineMode;
|
||||
|
||||
//404 is file not found
|
||||
if (httpResponse.statusCode == 404) {
|
||||
|
||||
NSLog(@"%@ is unknown to VirusTotal (hash: %@)", file.name, sha1);
|
||||
//NSLog(@"%@ is unknown to VirusTotal (hash: %@)", file.name, sha1);
|
||||
|
||||
@synchronized(item.plugin.unknownItems) {
|
||||
[item.plugin.unknownItems addObject:item];
|
||||
@@ -126,7 +164,11 @@ extern BOOL cmdlineMode;
|
||||
|
||||
//all other error(s)
|
||||
if (httpResponse.statusCode != 200) {
|
||||
NSLog(@"VirusTotal HTTP error: %ld", (long)httpResponse.statusCode);
|
||||
|
||||
//err msg
|
||||
if(isVerbose) {
|
||||
printf("\nERROR (VirusTotal): HTTP %ld\n", (long)httpResponse.statusCode);
|
||||
}
|
||||
|
||||
//signal
|
||||
dispatch_semaphore_signal(sema);
|
||||
@@ -137,7 +179,11 @@ extern BOOL cmdlineMode;
|
||||
NSError* jsonError = nil;
|
||||
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
|
||||
if (jsonError) {
|
||||
NSLog(@"VirusTotal JSON error: %@", jsonError.localizedDescription);
|
||||
|
||||
//err msg
|
||||
if(isVerbose) {
|
||||
printf("\nERROR (VirusTotal): invalid JSON %s\n", jsonError.localizedDescription.UTF8String);
|
||||
}
|
||||
|
||||
//signal
|
||||
dispatch_semaphore_signal(sema);
|
||||
|
||||
@@ -239,6 +239,9 @@ enum Signer{None, Apple, AppStore, DevID, AdHoc};
|
||||
//result url
|
||||
#define VT_RESULTS_URL @"permalink"
|
||||
|
||||
//report was shown
|
||||
#define VT_REPORT_VIEWED @"reportViewed"
|
||||
|
||||
//result hash
|
||||
#define VT_RESULT_HASH @"hash"
|
||||
|
||||
|
||||
+2
-2
@@ -1170,12 +1170,12 @@ BOOL hasFDA(void) {
|
||||
NSString *tccPath = [@"~/Library/Application Support/com.apple.TCC/TCC.db" stringByExpandingTildeInPath];
|
||||
|
||||
//dbg msg
|
||||
NSLog(@"Checking for 'Full Disk Access'");
|
||||
//NSLog(@"Checking for 'Full Disk Access'");
|
||||
|
||||
fileIsReadable = [NSFileManager.defaultManager isReadableFileAtPath:tccPath];
|
||||
|
||||
//dbg msg
|
||||
NSLog(@"Result: %d", fileIsReadable);
|
||||
//NSLog(@"Result: %d", fileIsReadable);
|
||||
|
||||
return fileIsReadable;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user