mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-05 03:56:46 +00:00
254 lines
4.2 KiB
Bash
Executable File
254 lines
4.2 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
|
|
|
|
# Find which compiler is installed
|
|
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
|
|
|
|
# Get path for sflib
|
|
SFLIBPATH=`ragg2 -v | cut -d ' ' -f 3-`
|
|
if [ ! -d "${SFLIBPATH}" ]; then
|
|
echo "Cannot find ${SFLIBPATH}"
|
|
exit 1
|
|
fi
|
|
|
|
# Get local architecture
|
|
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
|
|
A=x86
|
|
while : ; do
|
|
[ -z "$1" ] && break
|
|
F=$1
|
|
case "$F" in
|
|
-a) # architecture (x86, mips, arm)
|
|
shift
|
|
A=$1
|
|
[ -z "$A" ] && { echo "Missing argument for -a" ; exit 1; }
|
|
;;
|
|
-b) # register size (32, 64, ...)
|
|
shift
|
|
B=$1
|
|
[ -z "$B" ] && { echo "Missing argument for -b" ; exit 1; }
|
|
;;
|
|
-k) # kernel
|
|
shift
|
|
K=$1
|
|
[ -z "$K" ] && { echo "Missing argument for -k" ; exit 1; }
|
|
;;
|
|
-x) # execute
|
|
X=1
|
|
;;
|
|
-c) # set configuration option
|
|
C=1
|
|
;;
|
|
-d) # patch dword (4 bytes) at given offset
|
|
D=1
|
|
;;
|
|
-s) # show assembler
|
|
ASM=1
|
|
;;
|
|
-o) # output file
|
|
shift
|
|
O=$1
|
|
if [ -z "$O" ]; then
|
|
echo "Missing argument for -o"
|
|
exit 1
|
|
fi
|
|
;;
|
|
-h) # help
|
|
dohelp
|
|
exit 0
|
|
;;
|
|
-v) # version
|
|
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 -fpic"
|
|
LDFLAGS="-fPIC -fPIE -pie -fpic"
|
|
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
|
|
CFLAGS="${CFLAGS} -nostdinc -include ${SFLIBPATH}/${ARCH}/sflib.h"
|
|
CFLAGS="${CFLAGS} -z execstack"
|
|
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
|
|
# echo ${CC} ${CFLAGS} -o $F.tmp -S ${OPT} $F > /dev/stderr
|
|
${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 -b $B -C $F.text -F -o $O || fail
|
|
echo $O
|
|
rmtemps
|
|
exit 0
|