c - How to interpret PTRACE_PEEKTEXT return value -


i've been working on recode of mini strace program without using ptrace_syscall in order familiar registers.

so in code after using ptrace(ptrace_getregs, ...) set user_reg_struct field, i'm using ptrace(ptrace_peekdata, ...) read it.

not knowing retur of function use it's data (syscalls etc...), started looking @ code , came across things like:

int is_a_syscall() {  struct user_reg_struct regs; unsigned short int ret;  ret = ptrace(ptrace_peekdata, pid, regs.rip, 0); if (ret == 0xffff) {    perror("failed")    exit(1); } if (ret == 0x80cd || ret == 0x50f)    return (true); return (false); } 

now can explain me numbers in if() statement, a.k.a:

  • 0xffff, assume has architecture of processor couldn't verify it
  • 0x80cd , 0x50f

i wish know are, can find them, can interpret them , how can use them system calls , arguments.

the code included unconventional, i'll explain , show different way it.

unsigned short int ret; ret = ptrace(ptrace_peekdata, pid, regs.rip, 0); 

ptrace on linux returns long, not unsigned short. author of code looking @ low-order 2 bytes of 4 or 8 bytes ptrace returns. since x86 little-endian, gets job done, i'll show way later.

if (ret == 0xffff) {    perror("failed")    exit(1); } 

ptrace returns -1 on failure. since code stored low-order 2 bytes of return value, , treating value unsigned, test -1 uses 0xffff instead.

since ptrace(ptrace_peekdata, ...) can return -1 when succeeds, better @ errno (i'll show later).

if (ret == 0x80cd || ret == 0x50f)    return (true); return (false); 

you can find opcode lists @ sites http://ref.x86asm.net/coder64.html . cd int , cd80 int 80 , 0f05 syscall. these 2 opcodes used in x86 linux system calls. further info @ what better “int 0x80” or “syscall”?.

here's way check system call instructions (untested):

int is_a_syscall(regs) struct user_reg_struct regs; {     long ret;     unsigned char primary, secondary;     extern int errno;      errno = 0;     ret = ptrace(ptrace_peektext, pid, regs.rip, 0);     if (ret == -1 && errno != 0) {         perror("failed")         exit(1);     }     primary = (unsigned)0xff & ret;     secondary = ((unsigned)xff00 & ret) >> 8;     if (primary == 0xcd && secondary == 0x80 || primary == 0x0f && secondary == 0x05)         return true;     return false; } 

i use full width of ptrace's return value. if it's -1 , if errno has been set, indicates error. use ptrace_peektext instead of ptrace_peekdata, although on x86 doesn't matter. bitmasks used primary , secondary opcode bytes.

how can use them system calls , arguments.

for this, please see detailed answer: what calling conventions unix & linux system calls on x86-64.


Comments

Popular posts from this blog

php - Permission denied. Laravel linux server -

google bigquery - Delta between query execution time and Java query call to finish -

python - Pandas two dataframes multiplication? -