summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hypodermic/process.py34
-rw-r--r--wrapper/ptrace.c75
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, &regs);
return ((unsigned long long *) &regs)[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, &regs);
- return ((unsigned long *) &regs)[idx];
+ return ((unsigned long *) &regs)[idx];
}
+#endif