Debuggers can be used to change program execution. You can change the control flags, the instruction pointer, or the code itself to modify the way that a program executes.
For example, to avoid a function call, you could set a breakpoint where the function is called. When the breakpoint is hit, you could set the instruction pointer to the instruction after the call, thus preventing the call from taking place. If the function is particularly important, the program might not run properly when it is skipped or it might crash. If the function does not impact other areas of the program, the program might continue running without a problem.
You can also use a debugger to change the instruction pointer. For example, say you have a function that manipulates a string called encodeString
, but you can’t determine where encodeString
is called. You can use a debugger to run a function without knowing where the function is called. To debug encodeString
to see what happens if the input string is "Hello World"
, for instance, set the value at esp+4
to a pointer to the string "Hello World"
. You could then set the instruction pointer to the first instruction of encodeString
and single-step through the function to see what it does. Of course, in doing so, you destroy the program’s stack, and the program won’t run properly once the function is complete, but this technique can prove extremely useful when you just want to see how a certain section of code behaves.