0

I'm trying to write a script which gets the hex characters of an object file and then redirects the output (in ascii) to a specific line in a file.

Basically, i do

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

This prints me out the hex code (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

and i want to write that to a file containing:

#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;


}

I tried piping that output to sed as:

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

but i get an error.

My result should be:

#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;


}

And either i get an error with sed or i get sed to insert HEX code instead of ASCII, by converting \x41 to 'A', instead of inserting \x41.

Thanks

Iewicz
  • 193
  • 8

4 Answers4

2

Similar to the answer of hek2mgl, we make use of a template file with a placeholder (identical copy here):

/* ... */

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

/* ... */

So now we can replace the {{PLACEHOLDER}} as:

 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
kvantour
  • 25,269
  • 4
  • 47
  • 72
1

I would use a placeholder in the c file:

/* ... */

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

/* ... */

Then use a 2 step approach (using /bin/ls as example):

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
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • @kvantour I see what you mean. But that doesn't really match the input from the question. – hek2mgl Jan 23 '19 at 18:24
  • @lewicz ok. let me know if something doesn't work (meaning I misunderstood the question) – hek2mgl Jan 23 '19 at 18:24
  • @hek2mgl Thanks. Now it's inserting hex instead of ascii: unsigned char code[] = "x xxxxxxxxxxxxxxxxx – Iewicz Jan 23 '19 at 18:44
  • I thought you want hex. Btw, depending on the size of the output, the whole thing might fail with an `argument list too long error` when `${string}` becomes too large – hek2mgl Jan 23 '19 at 18:55
  • @hek2mgl hex as ascii: \x90\x0a\x0d and so on. – Iewicz Jan 23 '19 at 18:57
  • I tried the above commands with the `ls` binary and get the following output: `unsigned char code[] = "\x48\x83\xec\x08 ... "`. ( but see my previous comment about the possible _argument list too long_ error) – hek2mgl Jan 23 '19 at 18:59
  • 1
    Have you seen this? https://stackoverflow.com/questions/410980/include-a-text-file-in-a-c-program-as-a-char – hek2mgl Jan 23 '19 at 19:04
0

Generally speaking, I would suggest that you look at this problem more of a "template" than a "replacement." That is, rename your file from file.c to file.c.template. Then put markup in your template that is what you want to modify. For example:

#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;


}

Now all your sed has to do is replace <% code_hex_string %> with the actual hex string, and you're done.

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

Once you have this concept, it translates well to other languages as well, and you can grow your bash script into perl / python / groovy / C# / whatever fairly easily.

Tanktalus
  • 21,664
  • 5
  • 41
  • 68
  • Well i've tried that, the problem is that it's inserting hex code instead of ASCII as hex code: unsigned char code[] ="1��1۳1�Rho �hHell��1Ҳ̀1��1�̀" – Iewicz Jan 23 '19 at 18:42
0

I ended up with this:

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
Iewicz
  • 193
  • 8