For me, if I can't understand code written by someone else (which happens much more frequently than I care to admit), I'll do a spike and I'll try to rewrite the core functionality from scratch. Now don't get me wrong. This doesn't mean that my code will be half as good as the original implementation, in fact, it won't be for sure, since I won't spend much time on it. For me, that exercise is just a way for me to initially orient myself (and I do not keep the code I write during that phase).
If I'm lucky enough to have a good original version history of the code base, I'll go and pull up the original 0.1 version of the code (while I'm doing my own rewrite). Even if that version of the code is completely wrong. It still has a much higher chance of being something I'll understand. And then, I'll have a better understanding of what the developers were trying to do in the subsequent evolution of the project. Then, I'll isolate the parts of the latest code base I can safely break without breaking the entire thing, and I'll focus on those parts first.
Of course, during that next phase, I'd like to say I write unit-tests for the parts I modify before I modify them, but that's usually not how I work. I'll often have to fall down flat on my face a couple of times, cry in pain and frustration, and tear my hair out, before I'm willing give up and go back to doing things properly with unit tests. This does happen quite frequently, because I never seem to learn my lesson.
And of course, like someone else said already, I will also draw all kinds of mind maps and doodles throughout the entire process. And also, if I have access to one of the original developers who wrote the code, that's even better. If I can pair program with one of those persons, that's the ideal. If I can't, then talking to that person is the second best alternative. That person will be the best person to know all the weak points of his code base, give you a thumbnail overview of the architecture, and he will also be the best person to point out what parts you can work on first (so that you can gain confidence and a gradual understanding) that are the least likely to break the entire thing.