summaryrefslogtreecommitdiff
path: root/hypodermic/process.py
diff options
context:
space:
mode:
authorjakob <jakob@memeware.net>2017-09-09 15:41:20 -0400
committerjakob <jakob@memeware.net>2017-09-09 15:41:20 -0400
commit81e47a4dba4a44624ec56708c1655206ae19cbfc (patch)
tree0519728c9f679a2959d0e25e502f2181256898e1 /hypodermic/process.py
parent915e6fb7fcc9f7540b1123128eb7f8cf892c1288 (diff)
Implemented more syscall wrappers.
Diffstat (limited to 'hypodermic/process.py')
-rw-r--r--hypodermic/process.py90
1 files changed, 85 insertions, 5 deletions
diff --git a/hypodermic/process.py b/hypodermic/process.py
index c2c7409..e26978b 100644
--- a/hypodermic/process.py
+++ b/hypodermic/process.py
@@ -361,10 +361,95 @@ class Process(object):
fd = self.get_register("eax")
self.set_register("eax", old_eax)
+ # FIXME: fd is parsed as a ctypes.c_ulonglong...
if fd < 0:
raise OSError("Couldn't open {}".format(path))
return fd
+ def close(self, fd: int):
+ """Attempts to close a file descriptor within the inferior.
+
+ Args:
+ fd (int): The file descriptor to close.
+ """
+ if self.arch == "x64":
+ self.run_code(close_shellcode(fd))
+ else:
+ self.run_code(close_shellcode(fd, arch="i386"))
+
+ def mmap(self, addr=0, size=0, prot=0, flags=0, fd=-1, off=0) -> int:
+ """Introduce a new mapping to the process' address space.
+
+ Args:
+ addr (:obj:`int`, optional): The address, or 0 if
+ unimportant.
+ size (:obj:`int`, optional): The desired size of the
+ mapping.
+ prot (:obj:`int`, optional): The protections for the
+ mapping.
+ flags (:obj:`int`, optional): Any other flags for the
+ mapping.
+ fd (:obj:`int`, optional): A file descriptor to map.
+ off (:obj:`int`, optional): An offset in the file
+ descriptor.
+
+ Raises:
+ OSError: If the mapping cannot be made.
+
+ Returns:
+ The address the mapping was made at.
+ """
+ if self.arch == "x64":
+ old_rax = self.get_register("rax")
+ self.run_code(mmap_shellcode(addr, size, prot, flags, fd, off, path),
+ preserve=["rax"])
+ res = self.get_register("rax")
+ self.set_register("rax", old_rax)
+ else:
+ old_eax = self.get_register("eax")
+ self.run_code(mmap_shellcode(addr, size, prot, flags, fd, off, path,
+ arch="i386"), preserve=["eax"])
+ res = self.get_register("eax")
+ self.set_register("eax", old_eax)
+
+ # FIXME: fd is parsed as a ctypes.c_ulonglong...
+ if res == -1:
+ raise OSError("Couldn't complete mapping.")
+ return res
+
+ def munmap(self, addr=0, size=0):
+ """Removes a mapping from the process' address space.
+
+ Args:
+ addr (:obj:`int`, optional): The address, or 0 if
+ unimportant.
+ size (:obj:`int`, optional): The desired size of the
+ mapping.
+ Raises:
+ OSError: If the mapping cannot be made.
+
+ Returns:
+ The address the mapping was made at.
+ """
+ if self.arch == "x64":
+ self.run_code(munmap_shellcode(addr, size))
+ else:
+ self.run_code(munmap_shellcode(addr, size, arch="i386"))
+
+ def page_start(self, addr: int) -> int:
+ return addr & ~(self.page_size - 1)
+
+ def page_offset(self, addr: int) -> int:
+ return addr & (self.page_size - 1)
+
+ def page_align(self, addr: int) -> int:
+ return (addr + self.page_size - 1) & ~(self.page_size - 1)
+
+ # FIXME: Not tested on i386.
+ @property
+ def page_size(self) -> int:
+ return 4096
+
@property
def arch(self) -> str:
"""Returns the architecture of the host processor.
@@ -381,11 +466,6 @@ class Process(object):
"""
return "x64" if self._isamd64 else "x86"
- # FIXME: Not tested on i386.
- @property
- def page_size(self) -> int:
- return 4096
-
@property
def maps(self) -> list:
"""Obtain the process' memory map.