Skip to content

Commit

Permalink
Invoke PTRACE_DETACH properly
Browse files Browse the repository at this point in the history
  • Loading branch information
n1nj4sec committed Apr 11, 2017
1 parent 1540b6e commit 64376ed
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions memorpy/LinProcess.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@
from ctypes import create_string_buffer, byref, c_int, c_void_p, c_long, c_size_t, c_ssize_t, POINTER, get_errno
import errno
import os
import time
import signal
from BaseProcess import BaseProcess, ProcessException
from structures import *
import logging

logger = logging.getLogger('memorpy')

libc=ctypes.CDLL("libc.so.6")
libc=ctypes.CDLL("libc.so.6", use_errno=True)
get_errno_loc = libc.__errno_location
get_errno_loc.restype = POINTER(c_int)

Expand Down Expand Up @@ -122,6 +122,10 @@ def check_ptrace_scope(self):
logger.warning("yama/ptrace_scope == 1 (restricted). you can't ptrace other process ... get root")
elif ptrace_scope == 2:
logger.warning("yama/ptrace_scope == 2 (admin-only). Warning: check you have CAP_SYS_PTRACE")

except IOError:
pass

except Exception as e:
logger.warning("Error getting ptrace_scope ?? : %s"%e)

Expand All @@ -134,7 +138,6 @@ def _open(self):
self.check_ptrace_scope()
#to raise an exception if ptrace is not allowed
self.ptrace_attach()
time.sleep(0.1) # IDK why, but I need to wait before detaching to avoid an error !?
self.ptrace_detach()

@staticmethod
Expand Down Expand Up @@ -168,11 +171,21 @@ def _ptrace(self, attach):
op = ctypes.c_int(PTRACE_ATTACH if attach else PTRACE_DETACH)
c_pid = c_pid_t(self.pid)
null = ctypes.c_void_p()

if not attach:
os.kill(self.pid, signal.SIGSTOP)
os.waitpid(self.pid, 0)

err = c_ptrace(op, c_pid, null, null)

if not attach:
os.kill(self.pid, signal.SIGCONT)

if err != 0:
if attach:
raise OSError("%s : Error using ptrace PTRACE_ATTACH"%(err))
raise OSError("%s : Error using ptrace PTRACE_DETACH"%(err))
raise OSError("%s: %s"%(
'PTRACE_ATTACH' if attach else 'PTRACE_DETACH',
errno.errorcode.get(ctypes.get_errno(), 'UNKNOWN')
))

def iter_region(self, start_offset=None, end_offset=None, protec=None, optimizations=None):
"""
Expand Down Expand Up @@ -204,7 +217,7 @@ def iter_region(self, start_offset=None, end_offset=None, protec=None, optimizat
if 'r' in optimizations and not 'w' in region_protec:
continue
yield start, chunk

def ptrace_attach(self):
if not self.ptrace_started:
res=self._ptrace(True)
Expand All @@ -223,8 +236,8 @@ def write_bytes(self, address, data):

c_pid = c_pid_t(self.pid)
null = ctypes.c_void_p()


#we can only copy data per range of 4 or 8 bytes
word_size=ctypes.sizeof(ctypes.c_void_p)
#mprotect(address, len(data)+(len(data)%word_size), PROT_WRITE|PROT_READ)
Expand Down Expand Up @@ -265,5 +278,3 @@ def read_bytes(self, address, bytes = 4):
if self.read_ptrace:
self.ptrace_detach()
return data


0 comments on commit 64376ed

Please sign in to comment.