Python3 has some quirks that can make binary exploitation more difficult.
Issue: ``print()` isn’t printing out the correct characters
If print is printing out characters with \x
, this is a problem with the way
the python3 print function works.
>>> a = "\xaa\xbb\x90\xff"
>>> a
'ª»\x90ÿ'
> python -c "print('\xaa\xbb\x90\xff')"|xxd
00000000: c2aa c2bb c290 c3bf 0a .........
> python2.7 -c "print('\xaa\xbb\x90\xff')"|xxd
00000000: aabb 90ff 0a
By default, print tries to print the characters as UTF-8, but some characters
like \x90
do not have valid UTF-8 characters. There’s a few ways to work
around this.
- Using
sys.stdout.buffer.write()
(you have to importsys
first!). Instead of a string, this function takes a bytes-like object. - Specify the encoding as “latin-1” (ISO 8859-1).
>>> import sys b = b'\xaa\xbb\x90\xff' sys.stdout.buffer.write(b)
4
> python -c "import sys;sys.stdout.buffer.write(b'\xaa\xbb\x90\xff')" | xxd
00000000: aabb 90ff
IssueL My pwntools code works in python2 but not python3
Many of the pwntools functions return bytes-like objects in python3. They work
closer to an array of bytes rather than a string. The main differences is that
you cannot concatenate bytes and strings. (Note: In python2, bytes
and str
are aliases for the same type. In python3, they are separate!)
>>> from pwn import *
>>> "A"*10 + p64(0xdeadbeef)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "bytes") to str
>>> b"A"*10 + p64(0xdeadbeef)
b'AAAAAAAAAA\xef\xbe\xad\xde\x00\x00\x00\x00'
Issue: All \x00
bytes are removed from my string
The codecs library seems to remove these bytes. Try manipulating your string without the codecs library. This can also happen when using bash command substitution (backtick notation) sometimes (specifically when using command substitution in radare2)