Передайте hex в sed и добавьте его вывод в файл - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь написать скрипт, который получает шестнадцатеричные символы объектного файла, а затем перенаправляет вывод (в ascii) на определенную строку в файле.

В основном, я делаю

export FILE=myobj_file
export j=''
for b in $(objdump -d -M intel $FILE | grep "^ " | cut -f2); do j+='\x'$b; done; echo $j

Это распечатывает мне шестнадцатеричный код (шеллкод):

\xeb\x0d\x5e\x31\xc9\x67\x2a\x42\x4b\x55\x55\x55\x85\xc8\xc3\xc4\x85\xd9\xc2\xeb\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xe9

и я хочу записать это в файл, содержащий:

#include <stdio.h>
#include <string.h>

int main() { 
unsigned char code[] = {{PLACEHOLDER}} /*Here need to be inserted*/
printf("Length:  %d\n", strlen(code));

    int (*ret)() = (int(*)())code;
    ret();
    return 0;


}

Я попытался передать этот вывод в sed:

sed '6s/%d/$j/' file.c

но я получаю ошибку.

Мой результат должен быть:

#include <stdio.h>
#include <string.h>

int main() { 
unsigned char code[] = \
"\xeb\x0d\x5e\x31\xc9\x67\x2a\x42\x4b\x55\x55\x55\x85\xc8\xc3\xc4\x85\xd9\xc2\xeb\xe8\xe8\xe8\xe8\xe9\xe9\xe9\xe9";
printf("Length:  %d\n", strlen(code));

    int (*ret)() = (int(*)())code;
    ret();
    return 0;


}

И либо я получаю ошибку с sed, либо я получаю sed, чтобы вставить HEX-код вместо ASCII, преобразовав \ x41 в 'A' вместо вставки \ x41.

Спасибо

Ответы [ 4 ]

0 голосов
/ 23 января 2019

Я закончил с этим:

export j=''
for b in $(objdump -d -M intel /bin/ls | grep "^ " | cut -f2); do j+='\\x'$b; done; echo $j
sed "s/{{PLACEHOLDER}}/${j}/" file.c
0 голосов
/ 23 января 2019

Вообще говоря, я бы посоветовал вам взглянуть на эту проблему скорее как «шаблон», чем «замена».То есть переименуйте ваш файл с file.c на file.c.template.Затем добавьте в шаблон разметку, которую вы хотите изменить.Например:

#include <stdio.h>
#include <string.h>

int main() { 
unsigned char code[] = \
<% code_hex_string %>
printf("Length:  %d\n", strlen(code));

    int (*ret)() = (int(*)())code;
    ret();
    return 0;


}

Теперь все, что вам нужно сделать sed, это заменить <% code_hex_string %> фактической шестнадцатеричной строкой, и все готово.

sed -e 's/<%\s*code_hex_string\s*%>/'"$j"'/' < file.c.template > file.c

Как только вы получитеэта концепция хорошо переносится и на другие языки, и вы можете довольно легко превратить ваш bash-скрипт в perl / python / groovy / C # /.

0 голосов
/ 23 января 2019

Я бы использовал заполнитель в файле c:

/* ... */

int main() { 
    unsigned char code[] = "{{PLACEHOLDER}}"
    printf("Length:  %d\n", strlen(code));
    int (*ret)() = (int(*)())code;
    ret();
    return 0;
}

/* ... */

Затем используйте двухэтапный подход (например, / bin / ls):

string="$(objdump -d -M intel /bin/ls | awk -F'\t' '/^ /{gsub(/^|\y \y/, "\\\\x", $2);gsub(/ /,"",$2);printf "%s", $2}')"
sed "s/{{PLACEHOLDER}}/${string}/" file.c
0 голосов
/ 23 января 2019

Аналогично ответу hek2mgl , мы используем файл шаблона с заполнителем (идентичная копия здесь):

/* ... */

int main() { 
    unsigned char code[] = "{{PLACEHOLDER}}"
    printf("Length:  %d\n", strlen(code));
    int (*ret)() = (int(*)())code;
    ret();
    return 0;
}

/* ... */

Так что теперь мы можем заменить {{PLACEHOLDER}} на:

 awk 'BEGIN{FS="\t"}
      (NR==FNR) && /^ /{
         sub(" +$","",$2);gsub(" ","\\x",$2); string=string "\\x" $2
         next;
      }
      (NR == FNR) { next }
      /{{PLACEHOLDER}}/{ sub("{{PLACEHOLDER}}",string ) }
      1' <(objdump -d -M intel $FILE) code.c > updated_output.c
...