Преобразование шестнадцатеричной строки в python - PullRequest
2 голосов
/ 04 марта 2020

Я часами пытаюсь решить эту проблему - надеюсь, кто-нибудь сможет мне помочь. Я анализирую шестнадцатеричное число из вывода программы, которую я запускаю через Popen в Python. На следующем шаге этот шестнадцатеричный номер используется в качестве параметра для другого вызова программы через Popen. Проблема в том, что я не могу передать шестнадцатеричное значение Попену, чтобы оно работало:

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)

Следующая строка не работает так, как должна. В то время как первая часть строки интерпретируется правильно (как «AAA», символ ASCII с номером 41), «hex_string» используется в bash как «\ x35 \ xfe \ 9a \ x30». Это не проблема, что некоторые символы не могут быть напечатаны.

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

Когда я изменяю программу, чтобы вручную установить значение переменной (я не хочу этого делать), она работает без каких-либо проблемы.

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

Я уже пробовал много преобразований типов, но не смог.

1 Ответ

3 голосов
/ 04 марта 2020

ast.literal_eval - это способ сделать строку похожей, если вы набрали ее буквально.

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)

печатает True (обратите внимание, что hex_string является обращенной версией hex_output, которая не не упрощаем пример ...)

Мы только что сказали ast.literal_eval оценить строку (отсюда форматирование с кавычками), содержащую payload

. Возможно, с * 1014 могут быть более простые решения *, обрабатывая все данные как bytes вместо str:

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

отпечатки:

b'AAA5\xfe\x9a0'
...