Я пытался решить pwnable с помощью Python 3. Для этого мне нужно напечатать некоторые символы, которые не входят в диапазон ASCII.
Python 3 преобразует эти символы в какой-то странный Unicode.
Например, если я печатаю "\xff"
в Python 3, я получаю следующее:
root@kali:~# python3 -c 'print("\xff")' | xxd
00000000: c3bf 0a ...
\xff
превращается в \xc3\xbf
Но в Python 2 это работает, как и ожидалось, вот так:
root@kali:~# python -c 'print("\xff")' | xxd
00000000: ff0a ..
Так как же напечатать это в Python 3?
root@kali:~# python3 -c 'print("\xff")' | xxd 00000000: c3bf 0a ... root@kali:~# python -c 'print("\xff")' | ххд 00000000: ff0a
В вопросе пожалуйста!
сделал, добавил.
Хорошая работа отзывчивый
Что такое команда xxd
?
не уверен, что это шестнадцатеричный дамп?
Ну, я передаю стандартный вывод из python в стандартный ввод в команде xxd, которая преобразует его в шестнадцатеричный формат.
да это шестнадцатеричный дамп
В Python 2 str
и bytes
были одним и тем же, поэтому, когда вы писали '\xff'
, результат содержал фактический байт 0xFF
.
В Python 3 str
ближе к объекту unicode
Python 2 и не является псевдонимом для bytes
. \xff
больше не является запросом на вставку байта, а скорее запросом на вставку символа Unicode, код которого может быть представлен 8 битами. Строка печатается в вашей кодировке по умолчанию (вероятно, UTF-8), в которой символ 0xFF кодируется как байты \xc3\xbf
. \x
— это, по сути, однобайтовая версия \u
, когда она появляется в строке. Это все еще то же самое, что и раньше, когда оно появляется в bytes
.
Теперь о решении. Если вам просто нужны байты, сделайте
b'\xff'
Это будет работать так же, как и в Python 2. Вы можете записать эти байты в двоичный файл, но не сможете распечатать напрямую, так как все, что вы печатаете, преобразуется в str
. Проблема с печатью в том, что все кодируется в текстовом режиме. К счастью, sys.stdout
имеет атрибут buffer
, который позволяет напрямую выводить bytes
:
sys.stdout.buffer.write(b'\xff\n')
Это сработает только в том случае, если вы не замените sys.stdout
чем-то причудливым, без buffer
.
Это дает мне AttributeError: объект 'bytes' не имеет атрибута 'encode'
Это по-прежнему дает мне тот же результат, что и print("\xff")
root@kali:~# python3 -c "print(b'\xff'.decode('latin-1'))" |xxd 00000000: c3bf 0a ...
Да. Я только что понял, что я сделал. Он по-прежнему печатает в utf-8. Подожди секунду
@3xpl017. Фиксированный
В Python 2 print '\xff'
записывает строку байтов непосредственно в терминал, поэтому вы получаете байт, который печатаете.
В Python 3 print('\xff')
кодирует символ Unicode U+00FF на терминал, используя кодировку по умолчанию... в вашем случае UTF-8.
Чтобы напрямую выводить байты на терминал в Python 3, вы не можете использовать print
, но вы можете использовать следующее, чтобы пропустить кодирование и записать строку байтов:
python3 -c "import sys; sys.stdout.buffer.write(b'\xff')"
Пожалуйста, разместите код здесь вместо изображения