I used to port Japanese RPG games into English for Working Designs, which were similar if not larger code bases. All the comments were in Japanese, and frequently many of the tools used to build the product and assets were missing.
The way I dealt with it was to only focus on the problem I was trying to solve, and not worry about the rest of the code. The poster who said to backup the code in a VCS was right on... once you know you have a stable base to go back to, you can try all the changes you want.
If you approach the code with a goal, you can then think about likely places where that code would be. Grep is your friend. If the code has embedded strings, you can search for those strings. Otherwise, you can find the handles for those strings, and search for those. If it is some sort of I/O or database access, search on those call names. Frequently there are naming conventions that you can learn and use to find stuff.
The idea the earlier poster said about putting breakpoints in and/or stepping through the code was right, this is also a very useful practice. It is much easier to follow the flow if can step through it, especially with C++, where inheritance can often leave one baffled as to which code will actually run.
Following main (or your language equivalent) and then drilling down is sometimes useful, but it is often easier to find the bottom and work your way back out.
Watchpoints can be really useful. Find a variable with a value that interests you, and put a watchpoint on it so that it will break when that memory is accessed. A great way to see which routines are involved.
If all else fails, pepper the code with print (or logging) statements and see what shows up. Try to narrow down what you are looking for.
Another useful technique is to comment out a section of code and see where the compile breaks to find dependencies.
As you figure stuff out, add comments. Perhaps also keep a file of notes when you find stuff or figure out how things work.
As long as you are focused on solving a particular problem, the code base isn't so unreasonable, because you don't care about most of it. As you knock down each problem, you learn a little more about the structure of the code.
Remember, programming is the art of breaking problems down into smaller problems until they disappear.