diff options
| -rw-r--r-- | hypodermic/process.py | 34 | ||||
| -rw-r--r-- | wrapper/ptrace.c | 75 |
2 files changed, 42 insertions, 67 deletions
diff --git a/hypodermic/process.py b/hypodermic/process.py index 9a321e0..8307e08 100644 --- a/hypodermic/process.py +++ b/hypodermic/process.py @@ -136,10 +136,9 @@ class Process(object): self._attach = self._so.attach self._detach = self._so.detach self._cont = self._so.cont - self._getreg32 = self._so.getreg32 - self._getreg32.restype = ctypes.c_ulong - self._getreg64 = self._so.getreg64 - self._getreg64.restype = ctypes.c_ulonglong + self._isamd64 = self._so.is_amd64 + self._getreg = self._so.getreg + self._getreg.restype = ctypes.c_ulonglong def detach(self): """Explicitly detaches from the process. @@ -210,25 +209,40 @@ class Process(object): def get_register(self, reg: str) -> int: """Returns the value of the given register. + Note: + Registers are tied to the host processor, not the target + processor. For example, a 32-bit ELF will still have 64-bit + registers on 64-bit Linux. + Args: reg (str): The register to inspect. (e.g. "rax") Returns: An integer representing the value of the register. + """ - regs = AMD64_INDICES if self.arch == "x64" else I386_INDICES + regs = AMD64_INDICES if self._isamd64 else I386_INDICES if reg not in regs: raise ValueError("{} is not a valid register".format(reg)) - if self.arch == "x64": - return self._getreg64(self.pid, regs.get(reg)) - return self._getreg32(self.pid, regs.get(reg)) + return self._getreg(self.pid, regs.get(reg)) @property def arch(self) -> str: - with open("/proc/{}/exe".format(self.pid), "rb") as elf: - return ELFFile(elf).get_machine_arch() + """Returns the architecture of the host processor. + + Note: + The architecture of the host platform is not necessarily + the architecture of the target executable. However, this + value will accurately represent how registers should be + addressed. + + Returns: + A string representing the host processor. As of now, only + "x64" and "x86" are supported. + """ + return "x64" if self._isamd64 else "x86" @property def maps(self) -> list: diff --git a/wrapper/ptrace.c b/wrapper/ptrace.c index 7e5dfa8..8517519 100644 --- a/wrapper/ptrace.c +++ b/wrapper/ptrace.c @@ -19,9 +19,12 @@ #include <sys/ptrace.h> #include <sys/types.h> +#include <sys/user.h> +#include <sys/utsname.h> #include <sys/wait.h> #include <stddef.h> +#include <string.h> #include <unistd.h> @@ -86,73 +89,31 @@ int cont(int pid) { } -/* user_regs_struct is copied from sys/user.h so that we can debug a - 32-bit executable on a 64-bit platform. */ -struct amd64_user_regs_struct { - __extension__ unsigned long long r15; - __extension__ unsigned long long r14; - __extension__ unsigned long long r13; - __extension__ unsigned long long r12; - __extension__ unsigned long long rbp; - __extension__ unsigned long long rbx; - __extension__ unsigned long long r11; - __extension__ unsigned long long r10; - __extension__ unsigned long long r9; - __extension__ unsigned long long r8; - __extension__ unsigned long long rax; - __extension__ unsigned long long rcx; - __extension__ unsigned long long rdx; - __extension__ unsigned long long rsi; - __extension__ unsigned long long rdi; - __extension__ unsigned long long orig_rax; - __extension__ unsigned long long rip; - __extension__ unsigned long long cs; - __extension__ unsigned long long eflags; - __extension__ unsigned long long rsp; - __extension__ unsigned long long ss; - __extension__ unsigned long long fs_base; - __extension__ unsigned long long gs_base; - __extension__ unsigned long long ds; - __extension__ unsigned long long es; - __extension__ unsigned long long fs; - __extension__ unsigned long long gs; -}; +/* TODO: As of now, Hypodermis is strongly tied to the Intel x86 + family of processors. This should really be expanded. */ +int is_amd64(void) { + struct utsname ub; + uname(&ub); -struct i386_user_regs_struct { - unsigned long ebx; - unsigned long ecx; - unsigned long edx; - unsigned long esi; - unsigned long edi; - unsigned long ebp; - unsigned long eax; - unsigned long xds; - unsigned long xes; - unsigned long xfs; - unsigned long xgs; - unsigned long orig_eax; - unsigned long eip; - unsigned long xcs; - unsigned long eflags; - unsigned long esp; - unsigned long xss; -}; + return !strcmp(ub.machine, "x86_64"); +} -unsigned long long getreg64(int pid, int idx) { - struct amd64_user_regs_struct regs; +#ifdef __x86_64__ +unsigned long long getreg(int pid, int idx) { + struct user_regs_struct regs; ptrace(PTRACE_GETREGS, pid, NULL, ®s); return ((unsigned long long *) ®s)[idx]; } - - -unsigned long getreg32(int pid, int idx) { - struct i386_user_regs_struct regs; +#else +unsigned long getreg(int pid, int idx) { + struct user_regs_struct regs; ptrace(PTRACE_GETREGS, pid, NULL, ®s); - return ((unsigned long *) ®s)[idx]; + return ((unsigned long *) ®s)[idx]; } +#endif |