2014-04-03 91 views
0

我使用Scapy在Python中伪造数据包,但我需要手动修改特定数据包内的一系列位(scapy不支持),所以我做了以下:from hex string to int and back

给定一个数据包p,I将其转换为十六进制字符串,然后到底座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\[email protected]\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 
+0

为什么使用字符串函数进行位操作?这不是很昂贵的往返? – Hyperboreus

+0

噢好吧,明白了。这只是一个例子。重要的是我必须通过十六进制字符串,它不会返回相同的原始值... –

+0

我删除了转换为二进制数,但我得到了同样的错误:(我在这里错过了什么? –

回答

0

好的,我解决了它。

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

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