1

I noticed with Sophos Anti-Virus for Mac OSX that when I download a file, it immediately scans it. This works without a browser plugin in any of the browsers I have installed and tested. Therefore, on OSX, what Objective C API does one use in an application to detect a file was downloaded from the browser? I noticed that people recommend the DTrace command (and derivative scripts), but El Capitan release of OSX broke that command.

Volomike
  • 23,743
  • 21
  • 113
  • 209

3 Answers3

2

FSEvents allow you to get notified of changes to directories and everything below. It is a C API and as such of course available in ObjcC. There are many examples available.

Gerd K
  • 2,933
  • 1
  • 20
  • 23
  • This would work, sure. But users can download files to wherever they want on their mac and so the TO's app would have to get notified for every directory available. But maybe scanning the default "Downloads" folder (or perhaps the user's home folder and below) may be sufficient. – Alex Mar 22 '16 at 06:59
2

There's a couple solutions I can think of off the top of my head.

1) use a Launch Agent to watch when your Downloads folder is modified, whereupon it could launch a helper app (written in Objective C) to do something.

2) Since you tagged this with kext, you might want to do something at the kernel event layer. Consider Kernel Queues. Looking at this tutorial, it appears that this runs at the user level.

3) And use can use GCD to monitor file system events (+1 to Gerd!), here's another tutorial I found by the same author of the previous one

More information might be available here.

Community
  • 1
  • 1
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • Your first link (on Launch Agents) appears to be a dead link -- my browser just sits there, waiting. – Volomike Mar 23 '16 at 16:00
  • The GCD tutorial showed only how to detect changes to a specific file. I contacted the author on Twitter to see if it can be used to detect changes to /Users/mike/* (my home folder). – Volomike Mar 23 '16 at 16:08
  • I used [this](http://stackoverflow.com/a/1516034/105539) LaunchAgent example with the WatchPaths option. I switched it with a bash script that outputted to /tmp/output.txt with an append. It told me that a file event occurred in Downloads, but didn't tell me the filename. So, I can't scan that file with my tool I'm coding. It also seemed to keep running over and over again, never stopping, even though I didn't do any more file activities in my Downloads folder. – Volomike Mar 23 '16 at 17:03
  • I tried to get the GCD example to work on a single file -- nothing happened. I then tried [this example](http://stackoverflow.com/a/12314586/105539) on checking FSEvents changes, and it didn't work either. So, I'm still stuck. – Volomike Mar 23 '16 at 17:51
0

I wasn't able to achieve something in Objective C alone, but I could probably have a /Library/LaunchDaemon that can use an Objective C application to run /usr/bin/fs_usage command to detect events, and then parse that, and then run the scan on the file. An Objective C script could use C's popen() API to open that command in a background task and then scan it for changes. This would have to run as root, which is why it's called from /Library/LaunchDaemon (one would have to know how to make a launchd plist file, of course). (Of course, you can also make a C/C++ or other means to launch this process and filter it too, including a Perl script, all called from /Library/LaunchDaemon.)

Here's an example I just ran to detect when I downloaded an example.txt from Google Chrome browser into my /Users/mike/Downloads/test folder. Note that there's only one open system call. So, you'd need to grep on mds, which stands for Apple's MetaData Service worker, and then look for the open call, which will occur only once on a file download from the browser, and then get the path name from that in order to scan that one file.

sh-3.2# fs_usage -w -f pathname | grep '/Users/mike/Downloads/test' | grep mds
14:26:08.424743  getattrlist                            /Users/mike/Downloads/test/example.txt                                                                                                  0.000023   mds.3432456
14:26:08.424750  open              F=20       (R_____)  /Users/mike/Downloads/test/example.txt                                                                                                  0.000007   mds.3432456
14:26:08.478919  getattrlist                            /Users/mike/Downloads/test/example.txt                                                                                                  0.000057   mds.3432457
14:26:08.504923  stat64                                 /Users/mike/Downloads/test/example.txt                                                                                                  0.000018   mds.3432457
14:26:08.504969  fsgetpath                              /Users/mike/Downloads/test/example.txt                                                                                                  0.000005   mds.3432457
14:26:08.505001  stat64                                 /Users/mike/Downloads/test/example.txt                                                                                                  0.000020   mds.3432457
14:26:08.505076  getattrlist                            /Users/mike/Downloads/test/example.txt                                                                                                  0.000021   mds.3432457
14:26:08.505126  listxattr                              /Users/mike/Downloads/test/example.txt                                                                                                  0.000032   mds.3432457
Volomike
  • 23,743
  • 21
  • 113
  • 209