mirror of
https://github.com/Gallopsled/pwntools.git
synced 2026-11-08 08:06:05 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f7f0de984 | ||
|
|
16b507e197 | ||
|
|
53f041a4d2 | ||
|
|
b2a5b76cf7 | ||
|
|
9c2f0f4e89 | ||
|
|
d1edd275d9 | ||
|
|
cb4991c41d | ||
|
|
323975f343 | ||
|
|
f65c258956 |
No files matched your search
+27
-1
@@ -11,7 +11,10 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
| ---------------- | -------- | ---------------------- |
|
||||
| [3.5.0](#350) | `dev` | Mar 18, 2017 (planned)
|
||||
| [3.4.0](#340) | `beta` | Feb 4, 2017 (planned)
|
||||
| [3.3.1](#331) | `stable` | Jan 10, 2016
|
||||
| [3.3.4](#334) | `stable` | Jan 12, 2016
|
||||
| [3.3.3](#333) | | Jan 10, 2016
|
||||
| [3.3.2](#332) | | Jan 10, 2016
|
||||
| [3.3.1](#331) | | Jan 10, 2016
|
||||
| [3.3.0](#330) | | Dec 24, 2016
|
||||
| [3.2.1](#321) | | Dec 24, 2016
|
||||
| [3.2.0](#320) | | Nov 12, 2016
|
||||
@@ -32,6 +35,29 @@ To be released on Mar 18, 2017.
|
||||
|
||||
To be released on Feb 4, 2017.
|
||||
|
||||
## 3.3.4
|
||||
|
||||
- [#850][850] and [#846][846] fix issues with `hexdump` and the `phd` command-line utility, when using pipes (e.g. `echo foo | phd`)
|
||||
- [#852][852] Fixes register ordering in `regsort`
|
||||
- [#853][853] Fixes the registers restored in `shellcraft.amd64.popad`
|
||||
|
||||
[846]: https://github.com/gallopsled/pwntools/pull/846
|
||||
[850]: https://github.com/gallopsled/pwntools/pull/850
|
||||
[852]: https://github.com/gallopsled/pwntools/pull/852
|
||||
[853]: https://github.com/gallopsled/pwntools/pull/853
|
||||
|
||||
## 3.3.3
|
||||
|
||||
- [#843][843] fixed a bug in `amd64.mov`.
|
||||
|
||||
[843]: https://github.com/gallopsled/pwntools/pull/843
|
||||
|
||||
## 3.3.2
|
||||
|
||||
- [#840][840] fixed a regression introduced by [#837][837].
|
||||
|
||||
[840]: https://github.com/gallopsled/pwntools/pull/840
|
||||
|
||||
## 3.3.1
|
||||
|
||||
- [#833][833] Fixed a performance-impacting bug in the adb module.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||

|
||||
|
||||
[](https://docs.pwntools.com/)
|
||||
[](https://pypi.python.org/pypi/pwntools/)
|
||||
[](https://pypi.python.org/pypi/pwntools/)
|
||||
[](https://travis-ci.org/Gallopsled/pwntools)
|
||||
[](https://coveralls.io/github/Gallopsled/pwntools?branch=dev)
|
||||
[](https://twitter.com/pwntools)
|
||||
|
||||
+5
-1
@@ -224,6 +224,8 @@ def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
('mov', 'b', 'c'),
|
||||
('mov', 'c', 'x'),
|
||||
('mov', 'x', '1')]
|
||||
>>> regsort({'a': 'b', 'b': 'c'}, ['a','b','c'], xchg=0)
|
||||
[('mov', 'a', 'b'), ('mov', 'b', 'c')]
|
||||
"""
|
||||
if randomize is None:
|
||||
randomize = context.randomize
|
||||
@@ -333,7 +335,9 @@ def regsort(in_out, all_regs, tmp = None, xchg = True, randomize = None):
|
||||
# If XCHG is expressly disabled, and there is no temporary register,
|
||||
# try to see if there is any register which can be used as a temp
|
||||
# register instead.
|
||||
if not (xchg or tmp):
|
||||
#
|
||||
# If there are no cycles, there's no need for a temporary register.
|
||||
if in_cycle and not (xchg or tmp):
|
||||
for reg in in_out:
|
||||
if not depends_on_cycle(reg, in_out, in_cycle):
|
||||
tmp = reg
|
||||
|
||||
@@ -61,17 +61,26 @@ Example:
|
||||
mov rax, 0x1010110dfac01fe
|
||||
xor [rsp], rax
|
||||
pop rax
|
||||
>>> with context.local(os = 'linux'):
|
||||
... print shellcraft.amd64.mov('eax', 'SYS_read').rstrip()
|
||||
xor eax, eax /* (SYS_read) */
|
||||
>>> with context.local(os = 'freebsd'):
|
||||
... print shellcraft.amd64.mov('eax', 'SYS_read').rstrip()
|
||||
push (SYS_read) /* 3 */
|
||||
pop rax
|
||||
>>> with context.local(os = 'linux'):
|
||||
... print shellcraft.amd64.mov('eax', 'PROT_READ | PROT_WRITE | PROT_EXEC').rstrip()
|
||||
push (PROT_READ | PROT_WRITE | PROT_EXEC) /* 7 */
|
||||
pop rax
|
||||
>>> print shellcraft.amd64.mov('rax', 0xffffffff).rstrip()
|
||||
mov eax, 0xffffffff
|
||||
>>> print shellcraft.amd64.mov('rax', 0x7fffffff).rstrip()
|
||||
mov eax, 0x7fffffff
|
||||
>>> print shellcraft.amd64.mov('rax', 0x80010101).rstrip()
|
||||
mov eax, 0x80010101
|
||||
>>> print shellcraft.amd64.mov('rax', 0x80000000).rstrip()
|
||||
mov eax, 0x1010101 /* 2147483648 == 0x80000000 */
|
||||
xor eax, 0x81010101
|
||||
>>> with context.local(os = 'linux'):
|
||||
... print shellcraft.amd64.mov('eax', 'SYS_read').rstrip()
|
||||
xor eax, eax /* (SYS_read) */
|
||||
>>> with context.local(os = 'freebsd'):
|
||||
... print shellcraft.amd64.mov('eax', 'SYS_read').rstrip()
|
||||
push (SYS_read) /* 3 */
|
||||
pop rax
|
||||
>>> with context.local(os = 'linux'):
|
||||
... print shellcraft.amd64.mov('eax', 'PROT_READ | PROT_WRITE | PROT_EXEC').rstrip()
|
||||
push (PROT_READ | PROT_WRITE | PROT_EXEC) /* 7 */
|
||||
pop rax
|
||||
|
||||
Args:
|
||||
dest (str): The destination register.
|
||||
@@ -99,7 +108,6 @@ if get_register(src):
|
||||
if dest.size == 64 and src.size <= 32:
|
||||
dest = get_register(dest.native32)
|
||||
|
||||
src_size = src.size
|
||||
else:
|
||||
with ctx.local(arch = 'amd64'):
|
||||
src = eval(src)
|
||||
@@ -107,9 +115,9 @@ else:
|
||||
if not dest.fits(src):
|
||||
log.error("cannot mov %s, %r: dest is smaller than src" % (dest, src))
|
||||
|
||||
src_size = bits_required(src)
|
||||
orig_dest = dest
|
||||
|
||||
if dest.size == 64 and src_size <= 32:
|
||||
if dest.size == 64 and bits_required(src) <= 32:
|
||||
dest = get_register(dest.native32)
|
||||
|
||||
# Calculate the packed version
|
||||
@@ -117,7 +125,15 @@ else:
|
||||
|
||||
# Calculate the unsigned and signed versions
|
||||
srcu = packing.unpack(srcp, dest.size, sign=False)
|
||||
srcs = packing.unpack(srcp, dest.size, sign=True)
|
||||
|
||||
# N.B.: We may have downsized the register for e.g. mov('rax', 0xffffffff)
|
||||
# In this case, srcp is now a 4-byte packed value, which will expand
|
||||
# to "-1", which isn't correct.
|
||||
if orig_dest.size != dest.size:
|
||||
srcs = src
|
||||
else:
|
||||
srcs = packing.unpack(srcp, dest.size, sign=True)
|
||||
|
||||
%>\
|
||||
% if is_register(src):
|
||||
% if src == dest:
|
||||
|
||||
@@ -6,8 +6,8 @@ in the same order.
|
||||
pop rdi
|
||||
pop rsi
|
||||
pop rbp
|
||||
pop rsp
|
||||
pop rbp
|
||||
pop rbx /* add rsp, 8 */
|
||||
pop rbx
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
+22
-22
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import base64
|
||||
import random
|
||||
import os
|
||||
import re
|
||||
import string
|
||||
import StringIO
|
||||
@@ -10,7 +11,7 @@ from . import packing
|
||||
from ..context import context
|
||||
from ..log import getLogger
|
||||
from ..term import text
|
||||
from .cyclic import cyclic
|
||||
from .cyclic import de_bruijn
|
||||
from .cyclic import cyclic_find
|
||||
|
||||
log = getLogger(__name__)
|
||||
@@ -559,13 +560,15 @@ default_style = {
|
||||
}
|
||||
|
||||
cyclic_pregen = ''
|
||||
de_bruijn_gen = de_bruijn()
|
||||
|
||||
def sequential_lines(a,b):
|
||||
return (a+b) in cyclic_pregen
|
||||
|
||||
def update_cyclic_pregenerated(size):
|
||||
global cyclic_pregen
|
||||
cyclic_pregen = cyclic(size)
|
||||
while size > len(cyclic_pregen):
|
||||
cyclic_pregen += de_bruijn_gen.next()
|
||||
|
||||
def hexdump_iter(fd, width=16, skip=True, hexii=False, begin=0, style=None,
|
||||
highlight=None, cyclic=False):
|
||||
@@ -608,22 +611,6 @@ def hexdump_iter(fd, width=16, skip=True, hexii=False, begin=0, style=None,
|
||||
spacer = ' '
|
||||
marker = (style.get('marker') or (lambda s:s))('│')
|
||||
|
||||
# Total length of the input stream
|
||||
total = 0
|
||||
|
||||
if hasattr(fd, 'len'):
|
||||
total = fd.len
|
||||
else:
|
||||
# Save the current file offset
|
||||
cur = fd.seek(0, os.SEEK_CUR)
|
||||
|
||||
# Determine the total size of the file
|
||||
fd.seek(0, os.SEEK_END)
|
||||
total = fd.tell()
|
||||
|
||||
# Restore the file offset
|
||||
fd.seek(cur, os.SEEK_SET)
|
||||
|
||||
if hexii:
|
||||
column_sep = ''
|
||||
line_fmt = '%%(offset)08x %%(hexbytes)-%is│' % (len(column_sep)+(width*byte_width))
|
||||
@@ -643,17 +630,29 @@ def hexdump_iter(fd, width=16, skip=True, hexii=False, begin=0, style=None,
|
||||
return hbyte, abyte
|
||||
cache = [style_byte(chr(b)) for b in range(256)]
|
||||
|
||||
if cyclic:
|
||||
update_cyclic_pregenerated(total)
|
||||
|
||||
numb = 0
|
||||
while True:
|
||||
offset = begin + numb
|
||||
chunk = fd.read(width)
|
||||
|
||||
# If a tube is passed in as fd, it will raise EOFError when it runs
|
||||
# out of data, unlike a file or StringIO object, which return an empty
|
||||
# string.
|
||||
try:
|
||||
chunk = fd.read(width)
|
||||
except EOFError:
|
||||
chunk = ''
|
||||
|
||||
# We have run out of data, exit the loop
|
||||
if chunk == '':
|
||||
break
|
||||
|
||||
# Advance the cursor by the number of bytes we actually read
|
||||
numb += len(chunk)
|
||||
|
||||
# Update the cyclic pattern in case
|
||||
if cyclic:
|
||||
update_cyclic_pregenerated(numb)
|
||||
|
||||
# If this chunk is the same as the last unique chunk,
|
||||
# use a '*' instead.
|
||||
if skip and last_unique:
|
||||
@@ -673,6 +672,7 @@ def hexdump_iter(fd, width=16, skip=True, hexii=False, begin=0, style=None,
|
||||
|
||||
# Chunk is unique, no longer skipping
|
||||
skipping = False
|
||||
last_unique = chunk
|
||||
|
||||
# Generate contents for line
|
||||
hexbytes = ''
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
__version__ = '3.3.1'
|
||||
__version__ = '3.3.4'
|
||||
Reference in new issue
Block a user