It's pretty simple to protect against that on most implementations. Since you mentioned it, let's take Windows as an example.
To protect against rainbow tables on Windows, all we need to do is generate a 16-byte salt at the time of creation of the password and prepend it to the password pre-hashing. Then we store the salt in plaintext right next to the hashed password. Suddenly, a rainbow table is useless unless you happen to have a pre-generated rainbow table for that particular salt (note that you'd have to generate 2^127 times as many rainbow tables for a 50% chance of having a table with that salt).
Not that this protects against any other attacks, but it certainly does mitigate the rainbow table threat.
One small step for man, one giant stumble for mankind.