Stack walking works by rewriting the native stack. Basically we just let the native stack walker do its job, then strip out all python##.dll frames except for PyEval_EvalFrameEx. For that one we read the "f" argument and then parse the PyFrameObject to which it points, and replace the frame with our own using data from that frame object.
We parse the data structures ourselves, but use symbols to do so, which is why it'll work on any CPython build with symbols. This is why you can inspect objects even when process is stopped somewhere in native code, and it's impossible to eval using the interpreter.
We still use sys.settrace for breakpoints and Python stepping. Python-to-native stepping works by setting native breakpoints on code paths inside Python interpreter that can potentially invoke some user code (e.g. type_call invokes tp_init, which may point to a user function). When those breakpoints are hit, we eval the function pointer and see if it's outside of python##.dll, and if so, then set another breakpoint there. When it's hit, your step is complete.
So no, there are no special hooks added to the interpreter. We do end up relying quite a bit on internal implementation details, since we need to do things such as set breakpoints inside static functions, and read their arguments. However, because we use symbols for that, this works on any CPython build, including debug ones, and even customized ones so long as you don't rename anything that we rely on. E.g. adding a new field to PyObject is kosher, but renaming ob_type to something else would break us.
To accomplish that we require that we have symbols for the Python interpreter (which are typically available on python.org). The debug engine uses a combination of the native equivalent of sys.settrace, strategic breakpoints, and using the symbols to walk core Python data structures. There's a bunch of fun tricks for evaluating code when stopped at a Python frame and creating strings, ints, etc... when users type them into the watch window.
If you'd like to dig in more the source is at http://pytools.codeplex.com/SourceControl/latest under Python\Product\Debugger\DkmDebugger.
Here's a screenshot of a debug session with a custom host process written in C# running Python code that in turn uses a C++ extension module: http://i.imgur.com/IDPsWUu.png