0

I'm trying to convert a hexadecimal number, like the stack address 0x7ffd6fa90940,
into its corresponding Byte representation b'\x40\x09\xa9\x6f\xfd\x7f\x00\x00'.
Just like how it is represented in gdb:

pwndbg> hexdump $rsp \32
+#### 0x7fffffffdc##   0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F  │                 │
+0000 0x7fffffffdc30  e0 af 4b 00 15 00 00 00 [40 dc ff ff ff 7f 00 00] │..K.....│........│
+0010 0x7fffffffdc40  25 39 24 73 00 00 00 00 [50 dc ff ff ff 7f 00 00] │%9$s....│P.......│

I found three functions, but they do not convert the hex number as expected:

import pwnlib.util.packing
import binascii

addr = '0000' + '0x7ffd6fa90940'[2:]
addr = binascii.unhexlify(addr)
print("[DEBUG] addr: {}".format(addr))
# Prints big endian: b'\x00\x00\x7f\xfdo\xa9\t@'
#                !=  b'\x7f\xfd\x6f\xa9\x09\x40'

addr = 0x7ffd6fa90940
addr = pwnlib.util.packing.p64(addr, endian='little')
print("[DEBUG] addr: {}".format(addr))
# Prints lit endian: b'@\t\xa9o\xfd\x7f\x00\x00'
#                !=  b'\x7f\xfd\x6f\xa9\x09\x40'

addr = 0x7ffd6fa90940
addr = pwnlib.util.packing.pack(addr, word_size=64, endianness='little')
print("[DEBUG] addr: {}".format(addr))
# Prints lit endian: b'@\t\xa9o\xfd\x7f\x00\x00'
#                !=  b'\x7f\xfd\x6f\xa9\x09\x40'

# Custom implementation:
addr = '0000' + '0x7ffd6fa90940'[2:]
addr = ''.join(reversed(['\\x'+addr[i:i+2] for i in range(0, len(addr), 2)]))
print("[DEBUG] addr: {}".format(addr))
# Prints lit endian notation as a string: \x40\x09\xa9\x6f\xfd\x7f\x00\x00
# But how to convert to actual Bytes?:  b'\x40\x09\xa9\x6f\xfd\x7f\x00\x00'
#
addr = addr.encode('utf-8').replace(b'\\\\',b'\\')
print("[DEBUG] addr: {}".format(addr))
# Results in:   b'\\x40\\x09\\xa9\\x6f\\xfd\\x7f\\x00\\x00'

Why is that and how can it be converted as expected?
Thanks in advance for any hints, links, and answers!

2
  • 1
    Your second and third tries already work. If a byte value can be shown as printable ASCII character, it is represented as such instead of the \x00 representation but it is the same value. Commented Dec 6, 2023 at 14:45
  • The struct module was created just for tasks like this. Commented Dec 6, 2023 at 14:50

1 Answer 1

1

I'd use the following:

import struct
struct.pack( "@P", 0x7ffd6fa90940 )   # Or just `"P"`

That said, your second and third solutions give what you want.

>>> b'\x40\x09\xa9\x6f\xfd\x7f\x00\x00' == b'@\t\xa9o\xfd\x7f\x00\x00'
True

They are equivalent because

  • b'\x40' and b'@' both produce byte 0x40.
  • b'\x6f' and b'o' both produce byte 0x6F.
  • b'\x09' and b'\t' both produce byte 0x09.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.