2

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.

1 Answer 1

3

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'
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.