How does software "tell" if it's been pirated?

Basically I heard about this rather amusing story of how the creator of the semi-independent game Gmod (with the help of the publisher) tricked a number of pirates into turning themselves in by having a bug only appear in pirated copies and including an error message that includes the steam ID of the user, allowing them to be banned (for those who don’t know, Steam is a digital distribution service for PC games which allows you to download and install as many copies of your purchases as you like as long as you verify them by logging into your account).

Now, I can recall a great deal of games (and other software) have systems in place which cause something like this to happen (mostly in the form of a message saying “This game is pirated, cheapskate!” delivered by an NPC or some sort of game breaking bug (my personal favorite being one in Earthbound which causes the entire save file to be deleted on reaching the final boss).

I realised I’ve been taking it for granted that there was a way software could tell it was a pirated copy.

How does software internally verify itself as a legitimate copy for the purpose of anti-piracy measures like this?

With great difficulty. Especially if we wish to allow legitimate users to backup disks, install on more than one machine or play offline.

On one project I worked on we used a technique where “errors” were written to the disk, which most disk-copying software would automatically correct. Without the errors though, the system would know you have a copy.
It didn’t work against all copying software, and obviously it’s not useful for software sold online.

If you are talking about magnetic media (floppies), that scheme was easily defeated by using a bit copier, which makes an exact copy of every bit on every track, even in between sectors, without attempting any error correction or logical sector sequencing. I used one for years quite successfully.

One way would be if the distrubuter put out tainted copies of their own game

There are many ways, but they pretty much all rely on communication with an outside trusted information source controlled by the developer/publisher.

As long as your software periodically communicates with some external source, you can slip in extra information or instructions. Now, a standard cracking technique is going to be to debug the program while it’s trying to check that the license is valid, or while it’s trying to call home to the server, or something, and work around those so that the program skips the check, or doesn’t actually talk directly to the server. Well-protected programs will have numerous checks in numerous ways to make it difficult to circumvent them all, or subtle ones like that mentioned in Batman that won’t necessarily be noticed until trying to play through the game.

Really well-protected programs will include some kind of timebomb authentication procedure that doesn’t go off immediately, but goes off later. Maybe it goes off when a few months have passed, or when a particular downloadable add-on is loaded, or… who knows. If the developer is smart enough (or the crackers are sloppy enough), they’ll miss that this is actually part of the authentication, and will not include a workaround for it.