pwntools is working as intended for you. Using p64() does send the input as raw bytes. You can check it by adding pwntools' DEBUG flag while running your script. The debug output then prints everything that is sent and received. E.g.:

python2 solve.py DEBUG
[+] Starting local process './script': pid 23732
[DEBUG] Received 0x11 bytes:
    'Enter your name: '
[DEBUG] Sent 0x9 bytes:
    00000000  90 41 41 00  00 00 00 00  0a                        │·AA·│····│·│
    00000009
[*] Switching to interactive mode
[DEBUG] Received 0x18 bytes:
    00000000  90 41 41 45  6e 74 65 72  20 79 6f 75  72 20 70 61  │·AAE│nter│ you│r pa│
    00000010  73 73 77 6f  72 64 3a 20                            │sswo│rd: │
    00000018
\x90AAEnter your password: $ 

In the example above, you see that the bytes 90 41 41 00 00 00 00 00 0a are sent to the program, and not the string \x90.

Answer from maritio_o on Stack Overflow
🌐
pwntools
docs.pwntools.com › en › stable › util › packing.html
pwnlib.util.packing — Packing and unpacking of strings — pwntools 4.15.0 documentation
pwnlib.util.packing.p64(number, endianness, sign, ...) → bytes[source] · Packs an 64-bit integer · Parameters: number (int) – Number to convert ·
🌐
pwntools
docs.pwntools.com › en › dev › elf › elf.html
pwnlib.elf.elf — ELF Files — pwntools 5.0.0dev documentation
p64(address, data, *a, **kw)[source] · Writes a 64-bit integer data to the specified address · p8(address, data, *a, **kw)[source] · Writes a 8-bit integer data to the specified address · pack(address, data, *a, **kw)[source] · Writes a packed integer data to the specified address ·
🌐
Gitbook
ir0nstone.gitbook.io › notes › misc › pwntools › packing
Packing | Cybersecurity Notes
Packing with the in-built python struct module is often a pain with loads of unnecessary options to remember. pwntools makes this a breeze, using the context global variable to automatically calculate how the packing should work. Packs addr depending on context, which by default is little-endian. ... p64(0x04030201) == b'\x01\x02\x03\x04' context.endian = 'big' p64(0x04030201) == b'\x04\x03\x02\x01'
🌐
Readthedocs
python3-pwntools.readthedocs.io › en › latest › util › packing.html
pwnlib.util.packing — Packing and unpacking of strings — pwntools 2.2.1 documentation
pwnlib.util.packing.p64(number, sign, endian, ...) → str[source]¶ · Packs an 64-bit integer · pwnlib.util.packing.p8(number, sign, endian, ...) → str[source]¶ · Packs an 8-bit integer · pwnlib.util.packing.pack(number, word_size=None, endianness=None, sign=None, **kwargs) → ...
🌐
GitHub
github.com › Gallopsled › pwntools-tutorial
GitHub - Gallopsled/pwntools-tutorial: Tutorials for getting started with Pwntools · GitHub
There are bits of code everyone has written a million times, and everyone has their own way of doing it. Pwntools aims to provide all of these in a semi-standard way, so that you can stop copy-pasting the same struct.unpack('>I', x) code around and instead use more slightly more legible wrappers like pack or p32 or even p64(..., endian='big', sign=True).
Starred by 1.6K users
Forked by 261 users
Languages   Jupyter Notebook 84.9% | Python 12.9% | C 1.6% | Makefile 0.6%
🌐
pwntools
docs.pwntools.com › en › stable › elf.html
pwnlib.elf — ELF Executables and Libraries — pwntools 4.15.0 documentation
ELF.p64() ELF.p8() ELF.pack() ELF.process() ELF.read() ELF.save() ELF.search() ELF.section() ELF.string() ELF.u16() ELF.u32() ELF.u64() ELF.u8() ELF.unpack() ELF.vaddr_to_offset() ELF.write() ELF.__weakref__ ELF.address · ELF.arch · ELF.asan · ELF.aslr · ELF.bits ·
🌐
Medium
medium.com › @ria.banerjee005 › pwntools-the-binary-exploitation-toolkit-c41828eef506
Pwntools: The Binary Exploitation Toolkit | by Ria Banerjee | Medium
January 27, 2025 - For now, to make sure we have made the padding corrct, we fill the EIP with a dummy value. We cannot, of course, simply write “0xdeadbeef” as a string, because the computer would interpret it as ascii, and we need it as raw hex. So we use p32() from pwntools (p64 for 64 bit).
🌐
Zeshan Ahmed Nobin
nobinpegasus.github.io › blog › a-beginners-guide-to-pwntools
A beginners guide to pwntools | Zeshan Ahmed Nobin
September 27, 2023 - If we are getting the address leaked as byte code, we need to pad it to get 8 bytes and then unpack it to convert it to interger as we already know that p64() accepts non strings(hex, int) and not bytecode. E.g. puts_address = u64(output[0].ljust(8, b"\x00")) Sometimes the leaked address is in ASCII format. We need to retrieve flag from the leaked address. So converting the ASCII value to string is important. E.g. flag += bytes.fromhex(word.decode("utf-8"))[::-1].decode("utf-8") Another great utility pwntools offer is getting functions from different sections of a binary.
Find elsewhere
🌐
Agr0 Hacks Stuff
agrohacksstuff.io › posts › pwntools-tricks-and-examples
Pwntools Tricks and Examples | Agr0 Hacks Stuff
September 12, 2024 - What’s important to know here is that the exe variable now knows how to handle packing data based on the executable’s architecture. If it’s 64-bit, you don’t have to use p64(), you can just use pack().
🌐
pwntools
docs.pwntools.com › en › stable › util › cyclic.html
pwnlib.util.cyclic — Generation of unique sequences — pwntools 4.15.0 documentation
Creates a stateful cyclic generator which can generate sequential chunks of de Bruijn sequences · Find a chunk and subindex from all the generates de Bruijn sequences
🌐
PWN? PWN!
ch4r1l3.github.io › 2018 › 07 › 19 › pwn从入门到放弃第四章——pwntools的基本使用教程
pwn从入门到放弃第四章——pwntools的基本使用教程 | PWN? PWN!
July 20, 2018 - pwntools是除了ida和gdb以外最常用的工具,python的语法并不难,大概只要懂一些c和c++的编程,转换到python的编程非常简单 这里随便给一个教程,你也可以找其他自己觉得好的教程学一下 python教程 基本学一下循环,函数之类的就可以直接写python了 这里还要说一下,pwntools只能安装在python2下面,所以语法什么的都是python2的,但是如果学过python3
🌐
Zhihu
zhuanlan.zhihu.com › p › 83373740
pwntools的简单介绍
知乎,让每一次点击都充满意义 —— 欢迎来到知乎,发现问题背后的世界。
🌐
Google Books
books.google.fr › books
Handbook for CTFers - Nu1L Team - Google Livres
"Handbook for CTFers: Zero to One" was written by the Nu1L team, one of Chinas top CTF teams. As for Jeopardy-style CTFs, the content in the first 10 chapters of this book not only covers traditional categories of tasks like WEB, PWN and Crypto, but also includes some of the latest hot topics and techniques, such as blockchain.
🌐
Medium
mybagoftricks.medium.com › rop-emporiums-callme-x64-with-radare2-69822352a9e5
ROP Emporium’s callme (x64) with Radare2 | by Mark Higgins | Medium
November 17, 2020 - Pwntools can even run programs, giving you access to send and receive data, and interact. #!/usr/bin/env python3 from pwn import *payload = b"\xCC"*40 # Pack the address of sym.usefulFunction with p64 payload += p64(0x00401a57) # sym.usefulFunctionp = process("./callme") # open a new process p.sendline(payload) # send the payload p.interactive() # interact with the process
🌐
YouTube
youtube.com › christopher schafer
Pwntools: Fit and Address Packing - YouTube
Some of my favorite utilities that people forget to use.If you missed the first video, or need a refresher on pwn template, check out https://youtu.be/NhNbiv...
Published   November 20, 2017
Views   1K
🌐
X
x.com › JeshuaErickson › status › 1513160098675314692
X
April 10, 2022 - We’ve detected that JavaScript is disabled in this browser. Please enable JavaScript or switch to a supported browser to continue using x.com. You can see a list of supported browsers in our Help Center · ヘルプセンター · 利用規約 プライバシーポリシー Cookieのポリシー ...
🌐
HackMD
hackmd.io › @1ptrKd-hTF-40MNeKRIoSw › SyoKb1v8t
hkcert - training - HackMD
We can build a rop chain to leak the libc address First, we can use ```ROPgadget``` to find our needed gadget ![](https://i.imgur.com/4HIivBA.png) Here we use pwntools to do our exploit: ```python= offset = 56 payload = b'A' * offset payload += p64(pop_rdi) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(main) p.sendlineafter("input", payload) ``` This rop chain will let program output the puts address in libc and return to main function again.
🌐
Katastros
blog.katastros.com › a
Use of dynELF function in pwntools under 64-bit - Katastros
from pwn import * elf = ELF('./pwn_final') got_write = elf.got['write'] print 'got_write= ' + hex(got_write) call_get_name_func = 0x400966 print 'call_get_name_func= ' + hex(call_get_name_func) got_read = elf.got['read'] print "got_read: " + hex(got_read) bss_addr = 0x6020c0 pad = 'a' p = process('./pwn_final') gdb.attach(p) #get system address def leak(address): p.recvuntil('please enter your name:') payload1 = pad * 56 payload1 += p64(0x400d9a)+ p64(0) + p64(1) + p64(got_write) + p64(128) + p64(address) + p64(1) + p64(0x400d80) payload1 += "\x00"*56 payload1 += p64(call_get_name_func) p.send