0

I want to get the registers for a user process and was thinking of doing so using asm like so:

int regVal;
asm("movl %%eax, %0" : "=r"(regVal) :);

For a user process calling asm does the call change the process's registers? I'm worried about things like the instruction pointer changing changing from the asm call.

Is there an easier way to store/retrieve the values of all registers from a user process at once?

EDIT: my compiler is Apple clang version 11.0.0 (clang-1100.0.33.17)

Jeffrey Chen
  • 225
  • 3
  • 16
  • Based on [this](https://stackoverflow.com/q/2114163/), I'd say you're doing the right thing. Not sure what you are trying to achieve though. "I want to get the registers for a user process." Not just _any_ user process: it'll be __your own__ process. What do you expect to find there? Register values are mainly interesting when investigating optimization strategies of the compiler you are using. But it makes more sense to investigate that with static analysis: just read the assembly output. – Ruud Helderman May 25 '20 at 18:02
  • I'm playing around with forking/process manipulation so I wanted to get the values of the registers for something along the lines of copying over a process control block – Jeffrey Chen May 25 '20 at 18:13
  • I saw that in Rust you can do something like nix::sys::ptrace::getregs to get all registers from a process, so I was wondering if there was something like this in C that would allow me to access the registers of a different process (and thus I wouldn't have to worry about changing the values of my own process's registers while I am trying to observe them) – Jeffrey Chen May 25 '20 at 18:23
  • [Rust's ptrace](https://docs.rs/nix/0.15.0/nix/sys/ptrace/index.html) is based on [C's ptrace](http://man7.org/linux/man-pages/man2/ptrace.2.html). You may want to look into that. – Ruud Helderman May 25 '20 at 18:32

1 Answers1

2

Since you're using Apple clang , the most reasonable way to do this is create a seperate assembly file, assemble it and link it to your project. You can create separate methods for each register, like so.

getregs.s

.intel_syntax noprefix
.text


.global _getrax
_getrax:
    ret


.global _getrdx
_getrdx:
    mov rax,rdx
    ret

.global _getrcx
_getrcx:
    mov rax,rcx
    ret

.global _getrbx
_getrbx:
    mov rax,rbx
    ret

In your C code you would just declare the prototypes and call the methods

main.c

#include <stdio.h>
uint64_t getrax(void);
uint64_t getrcx(void);
uint64_t getrdx(void);
uint64_t getrbx(void);
int main(int argc, const char * argv[]) {
    printf("%p\n",getrdx());
    return 0;
}

Then in your terminal you would assemble the getregs.s file

clang -c getregs.s -o getregs.o

Then you would compile and link your object file to your main.c file

clang main.c getregs.o -o main

Then run

./main

And it will print your register

Irelia
  • 3,407
  • 2
  • 10
  • 31