Permalink
Browse files

Merge branch 'beta' into dev

  • Loading branch information...
zachriggle committed Sep 17, 2018
2 parents c7e9778 + c627115 commit c89bed2555990d35f9cc4804bdedb4a007af5802
Showing with 40 additions and 26 deletions.
  1. +1 −0 docs/requirements.txt
  2. +32 −23 pwnlib/elf/corefile.py
  3. +6 −2 pwnlib/elf/elf.py
  4. +1 −1 pwnlib/log.py
View
@@ -14,3 +14,4 @@ pygments>=2.0
sphinx_rtd_theme
doc2dash
coveralls
sphinx<1.8.0
View
@@ -88,6 +88,7 @@
from pwnlib.tubes.ssh import ssh_channel
from pwnlib.tubes.tube import tube
from pwnlib.util.fiddling import b64d
from pwnlib.util.fiddling import enhex
from pwnlib.util.fiddling import unhex
from pwnlib.util.misc import read
from pwnlib.util.misc import write
@@ -228,6 +229,8 @@ def __getitem__(self, item):
return self._core.read(item, 1)
def __contains__(self, item):
if isinstance(item, Mapping):
return (self.start <= item.start) and (item.stop <= self.stop)
return self.start <= item < self.stop
def find(self, sub, start=None, end=None):
@@ -477,6 +480,7 @@ class Corefile(ELF):
>>> io = elf.process()
>>> io.wait()
>>> core = io.corefile
[!] End of the stack is corrupted, skipping stack parsing (got: 4141414141414141)
>>> core.argc, core.argv, core.env
(0, [], {})
>>> core.stack.data.endswith('AAAA')
@@ -550,36 +554,40 @@ def __init__(self, *a, **kw):
for segment in self.segments:
if not isinstance(segment, elftools.elf.segments.NoteSegment):
continue
# Note that older versions of pyelftools (<=0.24) are missing enum values
# for NT_PRSTATUS, NT_PRPSINFO, NT_AUXV, etc.
# For this reason, we have to check if note.n_type is any of several values.
for note in iter_notes(segment):
# Try to find NT_PRSTATUS. Note that pyelftools currently
# mis-identifies the enum name as 'NT_GNU_ABI_TAG'.
# Try to find NT_PRSTATUS.
if prstatus_type and \
note.n_descsz == ctypes.sizeof(prstatus_type) and \
note.n_type == 'NT_GNU_ABI_TAG':
note.n_type in ('NT_GNU_ABI_TAG', 'NT_PRSTATUS'):
self.NT_PRSTATUS = note
self.prstatus = prstatus_type.from_buffer_copy(note.n_desc)
# Try to find NT_PRPSINFO
# Note that pyelftools currently mis-identifies the enum name
# as 'NT_GNU_BUILD_ID'
if note.n_descsz == ctypes.sizeof(prpsinfo_type) and \
note.n_type == 'NT_GNU_BUILD_ID':
if prpsinfo_type and \
note.n_descsz == ctypes.sizeof(prpsinfo_type) and \
note.n_type in ('NT_GNU_ABI_TAG', 'NT_PRPSINFO'):
self.NT_PRPSINFO = note
self.prpsinfo = prpsinfo_type.from_buffer_copy(note.n_desc)
# Try to find NT_SIGINFO so we can see the fault
if note.n_type == 0x53494749:
if note.n_type in (0x53494749, 'NT_SIGINFO'):
self.NT_SIGINFO = note
self.siginfo = siginfo_type.from_buffer_copy(note.n_desc)
# Try to find the list of mapped files
if note.n_type == constants.NT_FILE:
if note.n_type in (constants.NT_FILE, 'NT_FILE'):
with context.local(bytes=self.bytes):
self._parse_nt_file(note)
# Try to find the auxiliary vector, which will tell us
# where the top of the stack is.
if note.n_type == constants.NT_AUXV:
if note.n_type in (constants.NT_AUXV, 'NT_AUXV'):
self.NT_AUXV = note
with context.local(bytes=self.bytes):
self._parse_auxv(note)
@@ -588,19 +596,13 @@ def __init__(self, *a, **kw):
if self.stack and self.mappings:
for mapping in self.mappings:
if mapping.stop == self.stack:
if self.stack in mapping or self.stack == mapping.stop:
mapping.name = '[stack]'
self.stack = mapping
break
else:
for mapping in self.mappings:
if self.stack in mapping:
mapping.name = '[stack]'
self.stack = mapping
break
else:
log.warn('Could not find the stack!')
self.stack = None
log.warn('Could not find the stack!')
self.stack = None
with context.local(bytes=self.bytes, log_level='warn'):
try:
@@ -902,18 +904,25 @@ def _parse_stack(self):
if not stack:
return
# If the stack does not end with zeroes, something is very wrong.
if not stack.data.endswith('\x00' * 8):
log.warn_once("End of the stack is corrupted, skipping stack parsing (got: %s)",
enhex(self.data[-8:]))
return
# AT_EXECFN is the start of the filename, e.g. '/bin/sh'
# Immediately preceding is a NULL-terminated environment variable string.
# We want to find the beginning of it
if self.at_execfn:
address = self.at_execfn-1
else:
log.debug('No AT_EXECFN')
if not self.at_execfn:
address = stack.stop
address -= 2*self.bytes
address -= 1
address = stack.rfind('\x00', None, address)
address += 1
self.at_execfn = address
address = self.at_execfn-1
# Sanity check!
try:
View
@@ -52,12 +52,17 @@
from elftools.elf.constants import SHN_INDICES
from elftools.elf.descriptions import describe_e_type
from elftools.elf.elffile import ELFFile
from elftools.elf.enums import ENUM_P_TYPE
from elftools.elf.gnuversions import GNUVerDefSection
from elftools.elf.relocation import RelocationSection
from elftools.elf.sections import SymbolTableSection
from elftools.elf.segments import InterpSegment
# See https://github.com/Gallopsled/pwntools/issues/1189
try:
from elftools.elf.enums import ENUM_P_TYPE
except ImportError:
from elftools.elf.enums import ENUM_P_TYPE_BASE as ENUM_P_TYPE
import intervaltree
from pwnlib import adb
@@ -1781,4 +1786,3 @@ def disable_nx(self):
return
log.error("Could not find PT_GNU_STACK, stack should already be executable")
View
@@ -364,7 +364,7 @@ def warning_once(self, message, *args, **kwargs):
"""
m = message % args
if m not in self._one_time_warnings:
if self.isEnabledFor(logging.INFO):
if self.isEnabledFor(logging.WARNING):
self._one_time_warnings.add(m)
self._log(logging.WARNING, message, args, kwargs, 'warning_once')

0 comments on commit c89bed2

Please sign in to comment.