How do you make a cocoa demo app that only works for a limited time? - macos

I've used plenty of cocoa demo apps that stop working after 3 days or a month or so. How do they do that? What's the best way? Also, what are the limitations?

(Disclaimer: I've never made a trial version before, only read up on the subject and used a bunch of them.)
The limitations all come from the fact that anything on the user's system, the user can modify. So:
Clever cheapskates may alter your app's executable to stub out or otherwise defeat any check you make.
You have to store the amount of time used (or, more lazily but not as user-friendly, the date they started using your app) somewhere. Wherever you store it, the user must be able to change it (since your app runs as them), which means that if they find it, they can reset the clock.
It isn't possible if you run in a sandbox, unless you store the aforementioned time-tracking data in the user defaults or the Keychain, either of which might as well be in plain sight, or request the temporary exception entitlement for writing anywhere on the file-system. Time-limited trials can't be in the App Store anyway, but if either the App Store or sandboxing becomes required in a future version of Mac OS X, your time limit will break, and we can only hope it doesn't prevent the user from using your application entirely.
There's also the matter of handling payments. One way would be to sell the app in the App Store, without any trial-enforcement code, and distribute a separate build yourself that always enforces a time limit. If you do handle payments yourself, you need to store a record of the user's license on the user's system, and you need to check that license. This then becomes vulnerable to the same problem: The user may forge a license or “borrow” (e.g., download from a warez site) someone else's.
The upside, of course, is that the user has some amount of time to try the application for free without having to cough up any money, so at the end of that time (if your application is good and fills their needs), they'll be more likely to buy.
At the end of the trial period, you have a choice of what happens:
Lock the user out of the application entirely.
Cut out features. Acorn does this.
Let them open documents, but not save or print. (You can block screenshots, but then good luck handling bug reports.)
Let them save or (if applicable) print, but degrade part or all of the document in some way. For visual creations, such as images, a watermark may work. For audio, you can limit the sampling rate to something unpleasant like 20 kHz or less. (There's a case here for having your own proprietary format that you always handle losslessly, and only degrading exports to common formats such as TIFF, JFIF, or AIFF.) Fission does this.
Just nag them. (Can be combined with any of the above.)
Nag them and put a delay on the user's ability to dismiss it. You can even increase the delay the longer the user goes without paying.
One good alternative to the trial period is to have a separate “free” version with fewer features (or with ads). This is especially common on both App Stores.
Another consideration is whether the trial period is days used or days since first use. The latter is easier to implement, since you just record the date of first use and do subtraction. The former is more user-friendly, as it does not punish the user for launching the app once, playing with it for five minutes, and coming back to it for a real trial 31 days later.
You can also implement a limit on number of launches. It's as simple to implement as days-since-first-use, but doesn't punish only playing with the app once.
Some users just won't pay. Some users will do practically anything to not pay.
So you need to strike a balance. You need to provide a basic level of difficulty so that the laziest cheapskates cannot simply defaults write com.example.yourapp DaysSinceFirstUse -int 0 and keep using your app forever, while not making your app so onerous to try out (much less pay for) that they don't.
So here are some things not to do:
Attempt to enforce equality between the name of the user on their license (entered at purchase) and their name on their account or in the Address Book. There are a dozen different ways to write any name, and some people have multiple names (through marriage, aliases, legal name-changes, multiple languages, Star Trek fandom, etc.), so this or anything like it is a bogus check that will upset more legitimate users than discourage pirates.
Hold the user's data hostage. See my above point about the merit of a proprietary format that you always handle losslessly. If you do always degrade output during trial, make that absolutely clear up front in the app's on-launch “This is a trial version” dialog.
Require an internet connection. Not everybody has one (that can connect to arbitrary servers), and not everybody has one all of the time. Learn from the games industry: Don't alienate your users.
Install any sort of copyright enforcement software that runs in the background and/or is in a separate place from your application. Users will rightly hate you for this.
As for how to do it, here's what I recommend:
Implement a “days of actual use” check. This can be a selling point. It warms my heart when a trial explicitly says it uses this kind of check.
I'd say store it in hours. On launch, get the current number of hours from wherever you store it. Add two hours and write it back (so the user can't force-quit your app to defeat this). On quit, add the real number of hours since launch to the originally-read number and write the revised number back.
Store it in an invisible file in Application Support. Encrypt it (again, you want to defeat casual piracy), but don't waste too much time bulletproofing it. Remember, your app must contain everything to both encrypt it (to keep track) and decrypt it (to perform the check), so a sufficiently determined (and educated) cheapskate can break this no matter what you do.
On launch, get the current number of hours from wherever you store it and test whether it's over the limit. (If you take my add-two-hours-right-away suggestion, do that after you test against the limit.) 30 days is 30×24=720 hours. If it's over the limit, enact your trial-expired measures.
If you sell the software yourself, use symmetric public-key encryption for the license file. I think AquaticPrime does this. You encrypt licenses with your private key, and distribute the public key in the app, which uses the public key to decrypt and check the license. Practically unbreakable. You send license files to customers by email using the email address they provide at purchase. (Tell them that they will receive the license by email so they don't enter a made-up address.)
If you do this, make sure you test entering the license, both before the trial ends and after it ends.
Do the trial check only if there is no license.
If you can sell your app in the App Store, I recommend you just do that. If you want to also distribute a trial version yourself, do that with no licensing code in place, so the trial check simply happens unconditionally. The App Store version, of course, does not need (and must not have) a trial check.
Watch this. (Note: It pre-dates both of Apple's App Stores.)

In general, they save a count of days/hours/whatever used somewhere, e.g. in the app's user defaults.
Since it's fairly easy to change an app's user defaults, some write a simple hash to the file that has to match the number of days used. If not, they expire the build right then and there because a user obviously just mucked with that setting. Others keep several copies of the number of days used counter. If one is missing, they restore it based on the lowest number in one of the other locations.
Good locations are invisible files in locations the user wouldn't expect, maybe named so they look similar to a file by another app or a system file. But be careful that you don't litter files across the file system that then give the other app they look like a bad name. Also worth considering is writing a resource into a file's resource fork, where most people don't look anymore these days (one of your files! Another app or the system may replace their file and strip your info, or may use the same resource type and cause a collision).
Chances are, a casual hacker will try to edit the user defaults and then give up. A dedicated hacker will keep going no matter how much effort is put in the protection scheme, so it's not worth spending too much time on protecting it.
Some app developers instead generate a license key that has an expiration date in it and make the app refuse to run without a valid license key. There's a nice article by Allan Odgaard on how to sign information using OpenSSL (make sure you use LibreSSL or CommonCrypto.framework these days, which are very similar) to get the expiration date to your user without them being able to edit it: http://sigpipe.macromates.com/2004/09/05/using-openssl-for-license-keys/

Based on your ideas I made a short proof of concept in Java using Elliptic Curve Cryptography to generate a UUID on start up and then sign that UUID with ECC to create a registration key. The code is here if anyone wants it.1

Related

simple copy protection strategy

Just thought I'd run this idea past far more experienced heads.
I've made a desktop application in java 8. It is a niche app that will be sold via a single website. The market is individuals in a specific work environment who would not be "tech-savvy", and who are either on or chasing a 6-figure salary. My client, the publisher/vendor anticipates sales of maybe (don't laugh) 50-100 per year... so it's very niche. The retail price of the software, because of the low volume and niche setting, is to be around $100. So it's just a pet project that maybe helps to fund the family holiday at the end of the year.
The target customers will be on a high enough salary to not worry about paying the premium for the software (tax deduction anyway), which will directly enhance their ability to make more money, but they also have a reputation for having few scruples, and would generally not care about casually copying the software and giving it to their work mates.
The software will not be able to connect to the internet, so it's stand-alone, isolated.
So I need a copy protection scheme that is simple, not onerous to the end user and, due to it's target market and low volume, doesn't need to be "hacker-proof".
So this is what I've come up with:
Vendor has a "password" generator, that uses a simple algorithm, an
adaptation of the Luhn formula, that is capable of a few million
unique 8-char strings, out of a total possible pool of a few hundred
billion. So a valid password would be very hard to guess. Software
downloaded, generated password emailed to customer.
Software checks the "password" for validity, using a checksum-related
scheme. If valid, software is unlocked, and an invisible file is created somewhere generic on the hard drive, which flags that the software install is valid.
A different invisible file is written to the parent folder of the
software, which contains the provided original password. This is storage for passwords that have already been used, and are therefore invalid.
Next time the software is launched, it checks for the existence of
the validated-flag-file-- if it exists, then the software launches,
otherwise it asks the user to contact the vendor for a new password.
Whenever a user needs to type in a new password, the software checks the "invalidated passwords" file. If the user types in the original password, the software won't launch, because it's invalidated. But the file also needs to exist in the parent folder, so it cant be deleted either.
The idea is that if a casual user copies the software either by itself, or with its parent folder the software wont work on another machine, even if they have the original password, but if they are legitimate (registered user who needs a copy for working at home etc) then they can contact the vendor for a new valid password, that will then work on the new copy.
Hope that makes sense.
Comments, suggestions?
Full disclaimer: I work for Link Data Security and is your competitor, but this doesn't stop me from giving a few advises, as badly made protection damage the whole copy-protection community.
First of all you need to look into how hackers crack your program and try to deffend against their usual attacks. That would be debugging, changing your code when testing for validation, copy of key/validation-file and many more. This is the things I can remember from the top of my head. There will always come new cracking methods, due to hackers being very creative people.
If I was you I would try to run my program in a sandboxed enviroment, see what it does. Then make sure that files created or such doesn't help the hacker to find a good way to hack your protection.
Next time the software is launched, it checks for the existence of the validated-flag-file-- if it exists, then the software launches, otherwise it asks the user to contact the vendor for a new password.
From your description of your program I find it worrying that copy/move of your validated-flag-file to a new computer seems to break the copy protection. Also finding invisible files is the first thing a new hacker will learn, so this is the same as no protection.
A colleague of mine wrote a tutorial on what to take into consideration when making copy-protection, maybe this will help you on your way to being a copy-protection expert: All About Copy Protection

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.

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).

Implementing a 30 day time trial [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Question for indie Mac developers out there:
How do I implement a 30-day time trial in a non-evil fashion? Putting a counter in the prefs is not an option, since wiping prefs once a month is not a problem for an average user. Putting the counter in a hidden file somewhere sounds a bit dodgy - as a user I hate when apps sprinkle my hard drive with random files. Any ideas?
This issue comes up repeatedly on the cocoa-dev mailing list and the consensus answer is always do the simplest thing possible. Determined hackers will break all but the most over-engineered solution. And they're unlikely to pay for the software anyways. Go for the 80/20 solution: the easy solution that gets 80% effect for 20% effort. In this case, putting something in ~/Library/Application Support/your.app.com/. You might name the file something innocent if you want to obfuscate things just a bit. Using the user defaults is easy too.
Whatever you do, don't use the MAC address or an other hardware ID. Users with a network home directory (e.g. in a shared lab setting) will hate you. Using hardware IDs is just evil.
If someone is in love with your program so much that they're willing to break your trial limits, let them. The free software costs you nothing and their good will (and maybe recommendation to others) is worth a lot.
Finally, write software that people want to use and price it for its value. If your price is a good value and people want to use it, most people will pay for it.
I would suggest to implement few of things which are less intrusive and may avoid a normal user to either uninstall or buy at one month period.
Use a special series of trial-serial number which stores expiry date in it. You can use encrpytion to store expiry date within the serial number.
Now create a configuration file which stores data in the encypted format and contain the serial number.
Additionally implement these things in the config file.
Make a note of time/date every time user starts the application.
Note the duration of the time application was open.
By doing the logging of timestamp you can avoid these workarounds:
If user reverses the computer date, you would know that app was already run on that day. Say user ran app on 1 and 3 day of month. Now after 30 days reverses the date and sets it to 2nd of month. Now by config file you would know that app already ran on 1 and 3 so user has messed up dates on the computer.
Let’s say every time user starts your app by first setting date to 5th of the month. By logging your application running time you would see that if the total hours in a day exceed 24 then user is fooling around.
Ensure that your app doesn’t run without the config file. So essentially you send the encrypted serial number in a file or maybe upon entering the serial number you can create file. Since the serial number already has the expiry date user can’t reuse the serial number also.
I would not suggest the internet way because people get pissed off when app tries to connect to server every time. Plus, one may get suspicious that you trying to send some personal data of users to your servers.
One thing I would like to say: No matter how strong the anti-piracy technique you use, someone is bound to break it. You are not making your app for those guys. You are making your app for people who would like your software and will buy it happily. So have the anti-piracy in limits without losing the genuine customers by making your application too intrusive during the trial period. One thought also says, if your software is getting cracked that means it’s getting popular also. Again opinions may differ and would not like to digress on these issues.
Consider this. How many potential users of your software are out there, just itching to use it solidly for the next 30 days?
I suspect the far more normal case is: Users encounter a new software package that solves a problem they've had on a site like lifehacker.com. the software gets downloaded, played with briefly, then put aside. Perhaps its mp3 ripping software and they don't have any cd's to rip at that time. Or they're just busy that day, but they'll get round to reviewing that software 'soon'.
30 days pass. Probably more. Only Then do they buy a CD, encounter some sort of 'problem' and remember, 'aha, theres that trial version I downloaded! Where did I put it again?'
It doesn't matter. Without ever being used, the 'trial' has timed out.
I can't count the number of software tools that have fallen into that bucket for me. The day a piece of software is recommended to me, the day I see a positive review on lifehacker, is NEVER the day I actually have a need - or even the time - to use / analyse the program I've downloaded and intalled.
Having the software expire after 30 calendar days is bad because what if someone downloads it, runs it once, and then decides they'll evaluate it a month later? Next time they launch it, a month later, it'll say it's expired.
I'd go with having it limited to 14 launches, or something like 120 minutes of use.
As for implementation, a file (hidden or not) in the user's Preferences folder, with an obfuscated name, seems like the best way to go. The file isn't randomly placed on the hard drive, but the user can't easily figure out which file to delete.
The least evil way is to just ask the user to delete the program after one month or pay for it ;)
We did it for one of our client application. Granted it was done in .NET for Windows, but the same principles can be applied in MAC.
Like eckesickle mentioned, if your user have access to the internet (or should), then you can have a web service that will register some unique id from the host computer with the starting date trial (MAC adress is a good one). With this, the user cannot really cheat the program unless he chances his network card every month.
Now, if the user doesn't have access to the Internet for some reason, you can either shut down the program until he connect to it or use a grace period. This file records the last time the app is opened. When the Internet is not accessible, we stop writing the time (we still write something in it so the user doesn't notice the file is not updated).
Should a user notice that this file contains the information and delete it (or change it using a copy he has), then you need a way to counter that. You can have some other value in another config file (encrypted always) and check for consistency. What you do if you discover that the user is trying to cheat is up to you, but we force the user to connect to the internet for it to work.
It might be overkill for a program, but it definitly works.
At the time of download, provide them with a trial serial number. When they enter the serial number, have it connect to your server and gets expiration information (stored and encrypted locally to prevent any additional "phone home" calls).
By doing it this way, you make it fairly hard for them to get around your 30-day window, as the expiration date is permanently stored on the server. You could set it up so deleting the key and re-entering it would cause your application to connect to your server again and download the same expiration date as before.
Or you can do it like WinZip does (or used to do it?): Provide a 30-day trial and just pop-up a screen at every load that shows how long you've been using it and links to purchase.
I used to offer a 30-day lite edition of my iOS app that embedded the install date and various record dates in the export data file that the user could download to his/her computer.
If the user was a cheapskate and just reinstalled the lite edition and tried to re-import the data, logic would notice that at least one of the date was older than 30 days and the app would set its install date to the earliest such date from the file, rendering it expired again.
In the full paid edition, this logic didn't exist and the data file could be imported easily.
It was a pain supporting people in this data migration (since apps are completely sandboxed from one another) and some other users felt the lite edition was enough for them so they never upgraded.
I've since stopped offering my lite edition and just reduced the price of the full edition. Now potential customers just have to pay a small amount or go find some competing software.
All in all, that was the best strategy for getting paying users.
Read an UUID from some hardware component and make a check against your web service to see if your software has already been installed for 30-days upon program launch?

How to make a shareware program with a free demo [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have a game that I'd like to sell with the following system: give away a demo (say, with the first few levels) and sell the full version. I'd like to make the transition to the full version as seamless as possible for the user. I've never sold anything before online, so I'm not sure how that would work (even if there were no free demo).
This seems like a very common issue, so I'd imagine there's a standard solution. I'm writing in C++, targeting Windows, and my installer is generated by NSIS.
There are two options:
A separate demo and full version. Your ecommerce provider will send the full version to people who buy it.
A demo that is unlocked by a registration key or online activation process. Registration keys can be generated on the fly (or taken from a pre-generated list). Ecommerce providers can then send the keys to customers immediately after purchase.
Both approaches have their pros and cons.
Separate full version
Smaller demo file, saves bandwidth
Less technical support required for customers who buy full version (in my experience)
Two builds of the game, more testing
Harder to distribute updated versions to customers - need to keep a login for each customer or a secret URL that expires after a few days.
Unlockable demo
Contains all assets, may waste bandwidth
Easier to distribute cracked version (pirates can distribute a 10KB patch or reg key and link to your demo file, more bandwidth waste)
Single build, less testing
Easy to distribute updated versions (everybody can download the same public version)
Regarding a "general" solution, look around for commercial DRM wrappers such as this one. Some game portals/publishers also require that you use their own wrapper.
Don't ship your full product as a demo that can be activated. This way you don't eliminate piracy (which will still be something you will have to deal with) but at least you remove the possibility of someone just downloading the demo, cracking it, and spreading it around (or even just a cracked executable). They would at least have to buy the full version first.
As for checking a legit customer is using the software, you can indeed do some online authentication as Danny suggest but note that this will only stop people from using your online services and it often is just a matter of time before a qualified cracker/reverser makes sure that your product's offline features can be used without purchase.
By not shipping the full product immediately, it does make upgrading a little harder, but there are ways around this, ex: Updater that only works after online authentication.
If you develop it correctly you should be able to have a checking mechanism after the Xth level. This checking mechanism could basically hit a registry key. This registry key could have some encoded information which was generated by your program. The key could basically represent an MD5 hash (or SHA-1 or SHA-2 if you really concerned with high security) of the installed machine MAC Address, the first and last name, so and so forth. When someone purchases the game, you have them input that data in a form and then generate a code to send along to the user to unlock the game. You could even take that same algorithm and put it on your ASP.NET website and automate the key generation after a purchase has been made.
My 2 cents:
Dont spend too much time devising methods against piracy. Use simple serial generator mechanism to unlock the game which user can enter manually during the execution.
I would say have a single build which can switch to trial mode or full based on the serial key entered. This will reduce the overhead of maintaining two separate code.
It is a personal opinion, that people who really buy software at first place will buy your game no matter how many pirated versions are available. So make registeration purpose as simple as possible which will deter a normal user from cracking it and at the same time easy to use. Hackers will crack it no matter what protection you use it. Otherwise we wont see the pirated copies of microsoft/adobe products etc who spend so much on making their products piracy free. No matter what they charge, people do buy it. Its the quality of the product which will encourage your users to buy your product.
Also, try not to impose locks on your software like using MAC address etc for generating the serial numbers etc. Online activation may be a good idea but remember people are skeptical as to what information you try to transmit while activation. Also you might have to provide an alternate mechanism for offline activation if your customers dont have internet connection or work in separate LAN.
Once you see that you game is getting popular and you see more pirated copies with users, you may invest more time and money on developing anti-piracy techniques.

Resources