The signature covers everything except the signature itself. Since the signature and public key make up the input script for the most common payment type (pay-to-pubkey-hash), the input script is not part of the signed data. This means the input script can be modified and not break the signed transaction as long as the new input script is equivalent to the original input script. The recent attack did this by changing one of the script opcodes to an equivalent opcode. So the new script was valid and performed the same function. But since the opcode was changed, the transaction hash was different.
Once a transaction is part of a block, the transaction hash cannot be changed since it is now included in the Merkle tree for the block. So the attack window is only from the time the transaction is created until a miner includes it in a block. During this window, a modified transaction can be broadcast and it is a race to see which one makes it into the block. The one that loses will never be confirmed since it spends inputs that are already spent. No matter which one wins, the coins are sent to the proper destination.
The problem for Mt Gox (and others) is they track a transaction based on its transaction ID. If the modified transaction wins and gets included in a block, the original transaction will be discarded. This then led Mt Gox to think the money was not paid (since the transaction ID was not in the block chain) and they would create a new transaction to pay the money again.