Hex string type conversion in python

Lisa :

Since hours I try to solve this problem - hope anybody can help me. I parse a hex number out of the output of a program, which I run via Popen in Python. In the next step, this hex number is used as parameter for another call of the program via Popen. The problem is, that I am not able to pass the hex value to Popen, so that it works:

cmd = "./my_program"
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
response = p.stdout.read()
hexapattern = r'0x([0-9a-fA-F]+)'
hex_output = re.findall(hexapattern, str(response))[1]  #e.g.: hex_string = 35fe9a30
hex_string = '\\x' + hex_output[6] + hex_output[7] + '\\x' + hex_output[4] + hex_output[5] + '\\x' + hex_output[2] + hex_output[3] + '\\x' + hex_output[0] + hex_output[1]   #e.g.: hex_string = \x35\xfe\9a\x30
payload = '\x41\x41\x41' + hex_string
cmd = "echo -e -n " + payload + " | ./my_program"
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
response = p.stdout.read()
print(response)

The following line does not work the way it should. While the first part of the string is correctly interpreted (as 'AAA', ASCII character with number 41), the 'hex_string' is used in bash as '\x35\xfe\9a\x30'. It is not a problem, that some chars are not printable.

payload = '\x41\x41\x41' + hex_string
Output: AAA\x35\xfe\9a\x30

When I change the program to set the value manually to the variable (I don't want to do this), it works without any problems.

payload = '\x41\x41\x41' + '\x35\xfe\9a\x30'
Output: AAA[not printable char][not printable char][not printable char]

I already tried a lot of type conversions but failed.

Jean-François Fabre :

ast.literal_eval is a way to make the string like if you typed it literally.

hex_output = "35fe9a30"
hex_string = '\\x' + hex_output[6] + hex_output[7] + '\\x' + hex_output[4] + hex_output[5] + '\\x' + hex_output[2] + hex_output[3] + '\\x' + hex_output[0] + hex_output[1]   #e.g.: hex_string = \x35\xfe\9a\x30
payload = '\x41\x41\x41' + hex_string

import ast

result =  ast.literal_eval('"{}"'.format(payload))

print('\x41\x41\x41' + '\x30\x9a\xfe\x35' == result)

prints True (note that hex_string is the reverted version of hex_output, which doesn't simplify the example...)

We just told ast.literal_eval to evaluate the string (hence the formatting with quotes) containing payload

There may be simpler solutions with codec, handling the whole data as bytes instead of str:

import codecs
print(b'\x41\x41\x41' + codecs.decode(hex_output.encode(),"hex"))

prints:

b'AAA5\xfe\x9a0'

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=23655&siteId=1