How do code coverage tools like NCover know what parts of the code were executed and what parts were not?
It requires that you run your tests once with code coverage analysis enables, and then simply counts the number of blocks (that is, scope blocks) covered and compares to the total number of blocks in the project(s) you are testing.
The basic reasoning is that if each possible combination of code blocks is covered, all code paths are covered1. The main argument against putting too much weight in code coverage numbers is that "easy" blocks like getters and setters, that give no real value (and could hardly go wrong...) count just as much as more error-prone blocks of code.
1) As noted by Ira Baxter in a comment, the previous wording of this sentence was incorrect. Please read the comments for some discussion on this.