dsPIC33 Code Protection, how does it work?
The code protect is (optionally) set using a configuration bit when programming. If not set then you can read back as normal, if set you read back all zeros and the only way to clear it is by erasing the chip.
The bit will control something like a couple of AND gates to control access to the flash memory lines - this page at Flylogic discusses the security bit structure of a PIC16 (how to defeat it here)
To defeat it usually requires access to the die itself - e.g decapping of the chip, a powerful microscope and some idea of what to look for.
This link describes the process of clearing the security bit on a PIC18F.