从十六进制字符串到int和back

时间:2014-04-03 16:35:14

标签: python binary scapy hex

我使用 Scapy 在Python中伪造数据包,但我需要手动修改特定数据包中的一系列位(scapy不支持),所以我执行以下操作:

给定数据包p,我将其转换为十六进制字符串,然后转换为基数10 ,最后转换为二进制数字。我修改了我感兴趣的位,然后我将它转换回到一个数据包。我无法将其转换回相同格式的十六进制字符串 ...

# I create a packet with Scapy
In [3]: p = IP(dst="www.google.com") / TCP(sport=10000, dport=10001) / "asdasdasd"
In [6]: p 
Out[6]: <IP  frag=0 proto=tcp dst=Net('www.google.com') |<TCP  sport=webmin dport=10001 |<Raw  load='asdasdasd' |>>>
# I convert it to a hex string
In [7]: p_str = str(p)
In [8]: p_str
Out[8]: "E\x00\x001\x00\x01\x00\x00@\x06Q\x1c\x86;\x81\x99\xad\xc2t\x13'\x10'\x11\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x19a\x00\x00asdasdasd"
# I convert it to an integer
In [9]: p_int = int(p_str.encode('hex'), 16)
In [10]: p_int
Out[10]: 2718738542629841457617712654487115358609175161220115024628433766520503527612013312415911474170471993202533513363026788L
# Finally, I convert it to a binary number
In [11]: p_bin = bin(p_int)
In [11]: p_bin
Out[11]: '0b1000101000000000000000000110001000000000000000100000000000000000100000000000110010100010001110010000110001110111000000110011001101011011100001001110100000100110010011100010000001001110001000100000000000000000000000000000000000000000000000000000000000000000101000000000010001000000000000000011001011000010000000000000000011000010111001101100100011000010111001101100100011000010111001101100100'
# ... (I modify some bits in p_bin, for instance the last three)...
In [12]: p_bin_modified = p_bin[:-3] + '000'
# I convert it back to a packet!
# First to int
In [13]: p_int_modified = int(p_bin_modified, 2)
In [14]: p_int_modified
Out[14]: 2718738542629841457617712654487115358609175161220115024628433766520503527612013312415911474170471993202533513363026784L
# Then to a hex string
In [38]: hex(p_int_modified)
Out[38]: '0x45000031000100004006511c863b8199adc274132710271100000000000000005002200019610000617364617364617360L'

行动!它看起来并不像原始十六进制字符串的格式。关于如何做的任何想法?

修改: 好吧,我发现decode('hex'),它适用于十六进制数,但它打破了整个转换的反身性......

In [73]: hex(int(bin(int(str(p).encode('hex'), 16)), 2)).decode('hex')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-73-f5b9d74d557f> in <module>()
----> 1 hex(int(bin(int(str(p).encode('hex'), 16)), 2)).decode('hex')

/usr/lib/python2.7/encodings/hex_codec.pyc in hex_decode(input, errors)
     40     """
     41     assert errors == 'strict'
---> 42     output = binascii.a2b_hex(input)
     43     return (output, len(input))
     44 

TypeError: Odd-length string

EDIT2:如果我将转换删除为二进制数字,我会得到同样的错误......

In [13]: hex(int(str(p).encode('hex'), 16)).decode('hex')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/ricky/<ipython-input-13-47ae9c87a5d2> in <module>()
----> 1 hex(int(str(p).encode('hex'), 16)).decode('hex')

/usr/lib/python2.7/encodings/hex_codec.pyc in hex_decode(input, errors)
     40     """
     41     assert errors == 'strict'
---> 42     output = binascii.a2b_hex(input)
     43     return (output, len(input))
     44 

TypeError: Odd-length string

1 个答案:

答案 0 :(得分:1)

好的,我解决了。

我必须删除long int中的尾部L和十六进制表示中的前导0x

In [76]: binascii.unhexlify(hex(int(binascii.hexlify(str(p)), 16)).lstrip('0x').rstrip('L')) == str(p)
Out[76]: True