radare2/binr/ragg2/ragg2-cc
pancake 8186395ebd Fix rax2 -S and ragg2-cc -x, better radiff2 error msg
rax2 -S is now obeying 0 input length for stdin streams
ragg2-cc -x is now working properly (needed rax2 -S)
Fix stupid parsing bug introduced in previous commit in armass
2013-02-19 21:21:39 +01:00

248 lines
3.9 KiB
Bash
Executable File

#!/bin/sh
# ragg2-cc : a shellcode compiler -- pancake - 2011-2013
#
# Supported operating systems:
# - GNU/Linux
# - OSX
# - BSD
# Supported compilers
# - gcc
# - clang
# TODO
# remove temporary files
# add support for arm
# add support for nested shellcodes
if [ -z "${CC}" ]; then
for a in llvm-gcc clang gcc ; do
$a --version >/dev/null 2>&1
if [ $? = 0 ]; then
CC="$a"
break
fi
done
if [ -z "${CC}" ]; then
echo "Cannot find CC" > /dev/stderr
exit 1
fi
fi
A=x86
SFLIBPATH=`ragg2 -v | cut -d ' ' -f 3-`
if [ ! -d "${SFLIBPATH}" ]; then
echo "Cannot find ${SFLIBPATH}"
exit 1
fi
case "`uname -m`" in
"x86_64")
B=64
;;
*)
B=32
;;
esac
dohelp() {
echo "Usage: ragg2-cc [-dabkoscxv] [file.c]"
echo " -d enable debug mode"
echo " -a x86 set arch (x86, arm)"
echo " -b 32 bits (32, 64)"
echo " -k linux set kernel (darwin, linux)"
echo " -o file set output file"
echo " -s generate assembly"
echo " -c generate compiled shellcode"
echo " -x show hexpair bytes"
echo " -v show version"
}
case "`uname`" in
Darwin)
K=darwin
;;
*)
K=linux
;;
esac
X=0
C=""
D=""
O=""
F=""
ASM=0
while : ; do
[ -z "$1" ] && break
F=$1
case "$F" in
-a)
shift
A=$1
[ -z "$A" ] && { echo "Missing argument for -a" ; exit 1; }
;;
-b)
shift
B=$1
[ -z "$B" ] && { echo "Missing argument for -b" ; exit 1; }
;;
-k)
shift
K=$1
[ -z "$K" ] && { echo "Missing argument for -k" ; exit 1; }
;;
-x)
X=1
;;
-c)
C=1
;;
-d)
D=1
;;
-s)
ASM=1
;;
-o)
shift
O=$1
if [ -z "$O" ]; then
echo "Missing argument for -o"
exit 1
fi
;;
-h)
dohelp
exit 0
;;
-v)
ragg2 -v | sed -e 's,2,2-cc,'
exit 0
;;
esac
shift
done
if [ -z "$F" ]; then
dohelp
exit 1
fi
if [ "`uname`" = Darwin ]; then
OBJCOPY=gobjcopy
case "$B" in
32)
CFLAGS="-arch i386 "
LDFLAGS="-arch i386 -shared -c"
ARCH=darwin-x86-32
;;
64)
CFLAGS="-arch x86_64"
LDFLAGS="-arch x86_64 -shared -c"
ARCH=darwin-x86-64
;;
esac
SHDR="
.text
jmp _main"
else
OBJCOPY=objcopy
CFLAGS="-fPIC -fPIE -pie"
SHDR="
.section .text
.globl main
.type main, @function
jmp main
"
case "$B" in
64)
ARCH=linux-x86-64
;;
*)
ARCH=linux-x86-32
;;
esac
fi
[ "$A$K" ] && ARCH="$K-$A-$B"
OPT=-Os
#/usr/include/libr/sflib/
#CFLAGS="-shared -fPIC -fPIE -pie "
#CFLAGS="${CFLAGS} -shared -fPIC -fPIE -pie "
CFLAGS="${CFLAGS} -nostdinc -include ${SFLIBPATH}/${ARCH}/sflib.h"
CFLAGS="${CFLAGS} -fomit-frame-pointer -finline-functions -fno-zero-initialized-in-bss"
LDFLAGS="${LDFLAGS} -nostdlib"
case "$K" in
darwin)
#TEXT="__TEXT.__text"
TEXT="0.__text"
;;
*|linux)
TEXT=".text"
;;
esac
rmtemps() {
[ -z "$D" ] && rm -f $F.tmp $F.text $F.s $F.o
}
fail() {
rmtemps
exit 1
}
if [ "$D" ]; then
echo "==> Compile"
echo "${CC} ${CFLAGS} -o $F.tmp -S ${OPT} $F"
fi
rm -f $F.bin
${CC} ${CFLAGS} -o $F.tmp -S ${OPT} $F || fail
echo "${SHDR}" > $F.s
cat $F.tmp \
| sed -e s,rdata,text, -e s,rodata,text, -e 's,get_pc_thunk.bx,__getesp__,g' \
| grep -v .cstring | grep -v size | grep -v ___main | grep -v section \
| grep -v __alloca | grep -v zero | grep -v cfi >> $F.s
rm -f $F.tmp
if [ $ASM = 1 ]; then
echo $F.s
exit 0
fi
if [ "$D" ]; then
echo "==> Assemble"
echo "${CC} -c ${LDFLAGS} -Os -o $F.o $F.s"
fi
${CC} ${LDFLAGS} ${OPT} -o $F.o $F.s || fail
if [ "$D" ]; then
echo "==> Link"
#echo "${OBJCOPY} -j .text -O binary $F.o $.text"
echo "rabin2 -o '$F.text' -O d/S/${TEXT} $F.o"
fi
rabin2 -o "$F.text" -O d/S/${TEXT} $F.o
if [ "`du $F.text|awk '{print $1}'`" = 0 ]; then
# use objcopy as falback for rabin2
${OBJCOPY} -j .text -O binary $F.o $F.text || fail
fi
if [ "$C" = 1 ]; then
if [ "$O" ]; then
mv $F.text $O
else
O="$F.text"
fi
echo "$O"
exit 0
fi
[ "$X" = 1 ] && exec rax2 -S < $F.text
if [ "$D" ]; then
# hexdump -C $F.text
rax2 -S - < $F.text
ls -l $F.text
fi
[ -z "$O" ] && O=$F.bin
ragg2 -C $F.text -F -o $O || fail
echo $O
rmtemps
exit 0