outsauce it :)
If that isn't an option, well... first, try to make heads and tails of it. For the stuff I've dealt with, this is often the hardest part. You can manually create UML, you can use some of the commercial source code "reverse engineering" tools, or you can just trace the code.
When you have an understanding of the code, it's time to refactor. Plan well. Try to write a bunch of decent tests. Then go through an iterative approach of refactoring, writing additional tests, and checking (working!) modifications back into source control.
Depending on how masochistic you are, this can be great fun or your own personal hell :)