The code you included is somewhat unconventional, so I'll explain what it does and then show a different way to do it.
unsigned short int ret;
ret = ptrace(PTRACE_PEEKDATA, pid, regs.rip, 0);
ptrace on Linux returns a long, not an unsigned short. The author of the code is just looking at the low-order 2 bytes of the 4 or 8 bytes that ptrace returns. Since the x86 is little-endian, this gets the job done, but I'll show another way to do this later.
if (ret == 0xFFFF) {
perror("failed")
exit(1); }
ptrace returns -1 on failure. Since the code stored only the low-order 2 bytes of the return value, and is treating the value as unsigned, the test for -1 uses 0xFFFF
instead.
Since ptrace(PTRACE_PEEKDATA, ...)
can return -1 even when it succeeds, it would be better to also look at errno
(I'll show this later).
if (ret == 0x80CD || ret == 0x50F)
return (true);
return (false);
You can find opcode lists at sites like http://ref.x86asm.net/coder64.html . CD
is int
and CD80
is int 80
and 0F05
is syscall
. These are two opcodes used in x86 Linux to do system calls. Further info at What is better “int 0x80” or “syscall”?.
Here's another way to check for 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)0xFF00 & ret) >> 8;
if (primary == 0xCD && secondary == 0x80 || primary == 0x0F && secondary == 0x05)
return true;
return false;
}
I use the full width of ptrace's return value. If it's -1 and if errno
has been set, then that indicates an error. I also use PTRACE_PEEKTEXT
instead of PTRACE_PEEKDATA
, although on x86 it doesn't matter. Bitmasks are used to get the primary and secondary opcode bytes.
how can I use them to get my system calls and their arguments.
For this, please see this detailed answer: What are the calling conventions for UNIX & Linux system calls on x86-64.