More accurate identification of running applications on Mac OS - macos

By using runningApplications of NSWorkspace, it is possible to get a list of running apps on Mac OS as NSRunningApplication objects, and from this get additional information like what application is in the foreground.
It is possible to identify the running application using their name (localizedName), but I'm sure that can be spoofed by rogue applications. Other things like bundleIdentifier seem better, but I believe that too could be spoofed.
I would imagine that pretty much all of the metadata could be spoofed for applications outside of the public app store, but for any apps gotten from the app store things like bundleIdentifier should be safe ways to identify an app, right?
If we include arbitrary apps that someone downloads from the Internet, is there any better way to identify an app as to filter out rogue apps? I realize that there may be no solution that has no drawbacks, but looking for a best-effort attempt.

As you mention, all of these things can be pretty easily spoofed. Having written a product that does exactly what you're describing professionally, the solution is relatively straightforward: fingerprint every version of every popular app into a massive database, and then fingerprint each app you discover on the machine and look them up in your database. When you discover an app you've never seen before, flag it for adding to your database.
Maintaining that database is very large and ongoing endeavor. That's where most of the value of the product is. The agent code is not that complicated. The up-to-date database is what customers pay for. It's a pretty hard space to get into.
You're correct that you can verify signatures to make sure that things downloaded from MAS or part of the OS are what they claim to be. This will get you started, but isn't nearly enough; there's just so much that doesn't come from MAS.
The other headache is that you can see what "apps" are currently running in NSWorkspace, but it's pretty messy what it means. A lot of things that you don't think of as "apps" show up in runningApplications, like MobileDeviceUpdater and nbagent. On the other hand, things like mysqld aren't. Fingerprinting from runningApplications can miss things that aren't in that list, or malicious apps could lie about their bundle path to make themselves look legitimate. You can use tools like lsof to see what files a process really has open, but it gets more and more complicated.
Best of luck; it's a deep rabbit hole with dozens of corner cases, and very little documentation.

Related

Use Crashlytics on macOS daemon

I have a macOS application that is integrated with Crashlytics. If I run it as an agent, everything seems to work fine. But when I run it as a daemon, the crashs and errors don't show up on the web panel.
I'm thinking the problem might be that crashlytics uses a framework that is not daemon-safe.
Apple documentation regarding the subject says:
If your daemon uses frameworks that aren't daemon-safe, you can run
into a variety of problems.
Is this really the issue? Is there a workaround so I can get it to work?
Former maintainer for the Crashlytics SDK on Apple platforms here. However, I haven't been with the organization for a while, so my information could be out of date. You should definitely reach out to them for assistance. However, I'll still give this a shot.
A number of others have asked for this kind of functionality in the past, and from what I know, have successfully integrated Crashlytics into non-UI processes. There are some things to watch out for, though. I'm also aware of the daemon-safe issue, and that could be a problem. However, I'm unsure of how it might manifest itself.
When you say agent vs daemon, are you talking about per-process vs per-user launchd jobs, or something else? One thing I can be fairly certain of, is Crashlytics does not support multiple processes with the same bundle id running simultaneously. If there can be multiple copies of your process running at the same time, you cannot make this work. Even if it seems like it does work sometimes, it will not work reliably, at best, can could lead to serious issues at worst (potentially crashes).
One thing that is absolutely essential for correct operation is a main runloop. Crashlytics will definitely not work correctly without one.
Crashlytics also requires an Info.plist. This is actually possible to add to standalone binaries, but often trips people up. I'm guessing you figured this one out.
On macOS, Crashlytics integrates a bit with AppKit, to improve exception reporting. If I recall right, it's possible to just skip this integration completely, as outlined in the docs.
Another thing that Crashlytics relies on is a standard user file system home directory. There must be a ~\Library directory present with the standard internal structure. This one might be problematic for launchd daemons, since they run as root.
Keeping those things in mind, I'm pretty sure it's possible to make this work. There could be some things I'm not remembering, as it's been a while. However, one thing I definitely do know is this is a bit of a gray area. It works, but wasn't an explicit design goal. It might now be unsupported. You should definitely check in with them about this before shipping something.

How can I show my app is not a keylogger?

I've created a simple Mac app that gives you statistics on your working behavior over time. For example, your average words per minute, what language you are typing in, usage of the delete key, etc. Interesting stuff! However, some test users have said they wouldn't use the app if they didn't know me personally, since it collects keystrokes like a keylogger.
Is there some certification I can get to show that I'm not doing anything nefarious? (I never keep more than one word in memory!) Or will it be enough to have my app signed? Or open-source that part of the code? (Other parts I know I cannot make open source.)
Distributing through the Mac App Store will help, since users can see that Apple has tried your application and found nothing nefarious in it. [Added:] Also, sandboxing your app means that your app is restricted to an explicit set of abilities, which technically-skilled users could inspect. Anything not listed, you're unable to do, so this would be an easy way to prove that you don't send anything back over the internet.
Another thing would be to save all data in user-readable files. No binary plists, no Core Data stores, etc. (Whether the XML variants of either of those should count as user-readable would be more arguable, but for this purpose, I think at least an XML plist would be readable enough. Not sure about Core Data.)
If the user can read all of the raw data you store using applications that they trust (such as TextEdit), and not just your usual fancy in-app presentation of it, then they can check for themselves, and eventually trust, that you're not storing anything they wouldn't want you to.
If any concerned potential users email you about whether you report their keystrokes to your own server via the internet, and assuming that you don't make any internet connections at all (not even an update check), you can recommend that they should install Little Snitch, which pops up a confirmation alert anytime any app tries to connect to something. When they don't see such an alert about your app, they know that you're not phoning home.
You might also, on your product webpage, include a link to a tech profile. Here's Jesper's article proposing them, and here's one example of such a document, for one of his products.
I would think that Gatekeeper would be adequate for most users. If it turns out an app is doing bad things, then Apple could pull the plug on a malware developer. So that and maybe some time live should establish your program as 'safe' to those who are not technically inclined (e.g. cannot understand your source).
Simply distributing it in your or your company's name can do a lot to build trust in an app (provided of course your other products/programs have not violated users' trust).
If you can get the application onto Apple's App Store, then that means they will have checked it for such problems. There's no way they'd knowingly allow a key-logging app on there. Also, signing the app with an Apple certificate ensures that if it has been downloaded from the App Store and later is found to be nefarious, they can black list it.
Open-sourcing code would also be a good idea. I assume you can't Open Source all of it because it doesn't belong to you? If so, then make it clear what technologies it uses and be as open and honest about what the application does and how it goes about doing it.

How can I prevent the cracking of Mac OS apps?

I have developed a small app for OS X and I provided it in the Mac App Store. Some weeks later I found a cracked version of my app on rapidscene.me. It seems for me the code signing of Apple is not strong enough to prevent cracks. Are there any other techniques to make the life harder for the crackers? Maybe binary checksums? How can I implement it easily?
As always, my answer is "make better content" rather than try to battle it out with an endless cat and mouse game.
Few reasons:
Even the biggest players, were big companies dedicated to creating copy protection schemes always fail, you have very little chance of success
If you make a mistake, you will bite the only hand that feeds you. In other words, malfunctioning copy protection does not bother crackers but will bother your paying customers.
Focusing on making your application better and serving your customers better will get you more paying customers than any copy protection scheme.
What I mean with make better content is focusing on doing what you are good at. Or as Notch, creator of MineCraft puts it:
Wasting money on trying to stop pirates or laying a guilt-trip on them
are not approaches favored by Notch. Instead he prefers to offer
online-only services that will add something to the game experience
including level saving, centralized skins, friends lists and secure
name verification for multiplayer. He hopes that these subtle feature
additions can help to tempt pirates into become customers.
Apple's (or anyone's) code signing validates authenticity, it doesn't prevent cracks. Authenticity checks can be bypassed easily. If you search for ways to prevent cracking here on SO, you'll generally find answers about spending time on enriching the application rather than preventing cracking of the software. As long as the code runs on the a user's computer, they will be able to modify how it is executed.

What is the most secure manner of making a trial version of an OS X app?

I am interested in making a trial version of an application I am distributing via the Mac App Store. What is the most secure manner of doing so? Simply writing the first run date into user defaults seems a little easy to circumvent.
It's better to make trial versions be feature-limited rather than time-limited - features you can just actually leave out of your trial version's code, whereas you can't leave out "the rest of time eternal". You can try to artificially make your app stop working after a period of time, but rest assured that someone who wants to will find a way to bypass that restriction.
If you're dead-set on making it time-trial based, though, store a timestamp somewhere obscure in a non-obvious (e.g. basic encryption) format, and check against it. Yes, it'll get circumvented by someone determined, but it's not worth your time to try to prevent that.
Just do something that's "good enough" to encourage the mostly-honest users to pay for the app, and ignore the hardcore reverse engineers; they're a tiny segment of the market who probably wouldn't pay for your app no matter what you did (except possibly, they might pay for it if you didn't lock it down in the first place, as a matter of principle - some of them are fickle like that).

Extracting information from a MAC OS X application

I have a simple problem, I will be straighforward.
Suppose I have a third-party cocoa application running that has a chat box inside. Well, I need to capture the text inside that chat-box in real time from another application and write a logfile in real time with that information.
I am sure there is a way, I just don't know where to start. I have experience with cocoa and objective C, I have some apps in the iphone app store.
Thank you very much
Unless the app is suitably scriptable (e.g. AppleScript) or has some kind of external API then you're not going to be able to do this.
In short: Contact the developer of the application, but don't get your hopes up.
Unfortunately, in this day and age of protected memory and whatnot, we more or less have to be content with what the applications give us to work with.
However: You are not entirely without recourse. Using F-Script you might be able to attach to the process and cause some controller or other to emit notifications that you can capture and log.
Edit: If, as appears to be the case, it's a Carbon application, you are well and truly hosed:
F-script and similar is unlikely to be possible.
Even if it is, trying injection on a Carbon app, that is to say, a C++ app, is likely to be an exercise in futility and disappointment, if not completely impossible.
Seeing as how Carbon is deprecated (and how!), the application is unlikely to be updated with a proper API for that sort of thing.
All of the above.
Reedit: One tiny little aber; it is possible, although unlikely, that you can achieve something using Interface Scripting, but again; I wouldn't get my hopes up.

Resources