Uncle Bob Martin has a post up called Wading through Code where he talks about becoming a better developer by reading someone else's code. The value of reading good code, or just plain different code, from someone else is obvious, and you'll pick up plenty of coding strategems that way. However, the first comment immediately fires back with "how does one learn to write better code by reading through a lot of really bad code?"
My answer is to try to redesign the code. Figure out how I would design the system if I had been the one to build it. Find a smell in the code, think up a possible refactoring to clean it up. Look for duplication in the code and invent a new abstraction to eliminate the duplication.
It's mostly just a thought game, but it forces you to really get inside the existing code to understand what it does and look for the domain concepts of the code. More than once I've ended up putting those design ideas into use when it became time to rewrite or at least refactor the legacy system. It's also a great way to get more practice in designing software. I have reused design ideas from these mental exercises and abandoned projects many times on later projects.
I have a colleague who takes a very perverse pride in being able to wring meaning and function out of even the worst code. It's a valuable skill, because there's a lot of nasty legacy code out there that's too useful to throw out. Supporting and changing bad code is expensive though. Assuming that a rewrite is infeasible, the best choice is to improve the legacy code over time to extend its lifecycle and reduce the costs of working with it.
My contention is that you'll never make substantial progress unless you're constantly thinking about ways to improve the legacy code to improve coupling, testability, eliminate duplication, excise really ugly code, etc.. You never know when proposed changes to the legacy system will afford you the chance to make those improvements.
I'd recommend doing a little bit of this on your own code too. I've never completed a system that I didn't look back on and say "I wish I'd done xyz differently."