Search code examples
debuggingassemblygdbreverse-engineering

How disassemblers maintain the value of registers while analyzing object files?


When we analyze object files using gdb or any disassembler, we put break points into it. At any time it shows the current state of registers. There can be many programs running in background. Each of these programs will also use these registers and can change their value.

How does disassembler maintains the value of registers for our program when other processes may be continuously changing it?


Solution

  • Disassemblers like objdump -d do not run the program and don't have register values. All they have is the machine code, so they can print which registers each instruction uses, but not what value it will hold when the instruction runs.

    Any given instruction (like dec edx) could run multiple times over the life of the program, with multiple different values for EDX. So obviously you can't just statically print a single register value for an instruction in a disassembly listing.


    You're asking about debuggers, which do actually run the program as well as stopping it at breakpoints or single-stepping.

    In a multi-tasking OS like Linux, MacOS, or Windows, the OS provides system calls to trace another process, e.g. Linux ptrace. This lets GDB insert breakpoints, or single-step. And when the target process is stopped, GDB can use ptrace to read the saved architectural state (register values).

    Running multiple tasks on one CPU is done by the OS, with "context switches" that save register state for the old task, and restore state for the new task. Each task has its own register state that's loaded into the architectural registers whenever it's actually running.

    This is basic Operating Systems stuff, get a textbook or google some of these keywords if you want to learn more.