Why stack and instruction pointer register dont change when i keep printing them using c and inline assembly , because logically others programs are running at the same time so they should keep changing while im printing
-
5Each process only sees its own register values. It's the operating system's job to ensure that is the case as part of context switching. – kaylum May 29 '21 at 23:01
-
And is it possible to read rip value of other programs same way to read process memory using ReadProcessMemory – SinusPi May 29 '21 at 23:03
-
Virtual memory means every process can have its own address space, so a fixed layout is possible. If you run under a debugger like GDB, it will by default disable address randomization, otherwise yes your stack will be at a different address every time. Code addresses (which RIP must have come from at some point) can also be randomized, e.g. in a Linux PIE executable. – Peter Cordes May 29 '21 at 23:03
-
@PeterCordes im using gcc – SinusPi May 29 '21 at 23:05
-
Under Windows, I assume, since you mentioned ReadProcessMemory? The compiler you use has no impact on this, except maybe on Linux where the default config could mean creating a PIE vs. a position-dependent executable. – Peter Cordes May 29 '21 at 23:08
-
1related, almost a duplicate: [How does the stack pointer work in several processes?](https://stackoverflow.com/q/46968410). Or [How does gdb read the register values of a program / process it's debugging? How are registers associated with a process?](https://stackoverflow.com/a/48798085) covers some of the necessary concepts. – Peter Cordes May 29 '21 at 23:15
-
@PeterCordes So if my exe is PIE ,will i get RIP values of only others PIE or every process running at the same time and how to make it PIE . Thanks – SinusPi May 29 '21 at 23:25
-
No, nothing like that. Your process will either have its own RIP randomized by the kernel, totally independent of every other process, or you'll always get the same RIP. Randomization is only possible for executable that are built to be relocatable, like a Linux PIE executable. Either way, there is absolutely zero dependency on other processes running on the same system; each process has its own virtual address space, and its own registers and program-counter. – Peter Cordes May 30 '21 at 00:12
-
1`"And is it possible to read rip value of other programs same way to read process memory using ReadProcessMemory"` -- On Windows, you can use [`GetThreadContext`](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreadcontext) (must call `SuspendThread` first). – Andreas Wenzel May 30 '21 at 00:16
2 Answers
The operating system and the CPU work together to give processes (running at the same time) slices of CPU. In effect, they virtualize the CPU by handing out time slices. A process that is interrupted so that CPU can be handed to another processes, when eventually resumed, restarts exactly where it stopped off — while overly simplified, a process doesn't even notice that it was interrupted. So, running of other processes simultaneously won't reveal register values changing except as needed for execution of the process attempting to observe the CPU. (This applies no matter how many observers. In fact, it is critical for programs to see only their own register values.)
We cannot look inside the CPU to see registers (without special hardware), so instead we command the CPU to copy its register values into memory one way or another in order to look at them. Such commands (e.g. simple stores of register to memory) are used when a process is interrupted, such as by a breakpoint or timer or (other) external interrupt. The operating system instructs the CPU to save register values to memory (e.g. a context block), and from there other programs (like the debugger) can see the values of the registers at the time of interruption.
When a program prints its own RIP, the RIP has to be captured by some instruction, in order to be serialized into a string to print so we can see it. That capture may always at the same place in the machine code of that program (e.g. when in a loop), so the same RIP value is captured each time. (If it wasn't the computer wouldn't work very well.) Such observing program is looking at its own execution (which happens to be virtualized via time slicing).
A multicore processor has multiple register sets, each of which includes an RIP register. The operating system and CPU (single core or multicore) work together to ensure that time slices of CPU are given to programs, who see register values change due to their own actions — programs expect this; they depend on this.
- 23,049
- 2
- 29
- 53
you are using the same function to print the register. while the program is running that function the stack is static. if you recurse the function or print in different nested functions it will change.
- 69,149
- 8
- 89
- 168