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
Post a Comment