将十六进制输入到sed中,并将其输出附加到文件中

时间:2019-01-23 17:50:23

标签: bash sed hex pipe ascii

我正在尝试编写一个脚本,该脚本获取目标文件的十六进制字符,然后将输出(以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

这会将我打印出十六进制代码(shellcode):

\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通过将\ x41转换为'A'而不是插入\ x41来插入十六进制代码而不是ASCII。

谢谢

4 个答案:

答案 0 :(得分:2)

类似于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

答案 1 :(得分:1)

我会在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

答案 2 :(得分:0)

一般而言,我建议您将这个问题更多地看做是“模板”而不是“替换”。也就是说,将文件从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#/中。

答案 3 :(得分:0)

我最终得到了这个

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