mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 21:29:49 +00:00
258 lines
4.4 KiB
Bash
Executable File
258 lines
4.4 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
|
|
# 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
|
|
if [ -z "${SFLIBPATH}" ]; then
|
|
SFLIBPATH="$(r2 -hh | grep INCDIR | awk '{print $2}')"/sflib
|
|
fi
|
|
if [ ! -d "${SFLIBPATH}" ]; then
|
|
echo "Cannot find ${SFLIBPATH}"
|
|
echo "Define SFLIBPATH env var or fix the r2 installation"
|
|
exit 1
|
|
fi
|
|
|
|
# Get local architecture
|
|
case "$(uname -m)" in
|
|
"x86_64")
|
|
B=64
|
|
;;
|
|
*)
|
|
B=32
|
|
;;
|
|
esac
|
|
|
|
dohelp() {
|
|
cat<<EOF
|
|
Usage: ragg2-cc [-cdsvx] [-a arch] [-b bits] [-k kernel] [-o output] [file.c]
|
|
-a x86 set arch (x86, arm)
|
|
-b 32 bits (32, 64)
|
|
-c generate compiled shellcode
|
|
-d enable debug mode
|
|
-k linux set kernel (darwin, linux)
|
|
-o file set output file
|
|
-s generate assembly
|
|
-v show version
|
|
-x show hexpair bytes
|
|
EOF
|
|
}
|
|
|
|
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
|
|
SHDR="
|
|
.section .text
|
|
.globl main
|
|
.type main, @function
|
|
jmp main
|
|
"
|
|
case "$B" in
|
|
64)
|
|
CFLAGS="-fPIC -fPIE -pie -fpic -m64"
|
|
LDFLAGS="-fPIC -fPIE -pie -fpic -m64"
|
|
ARCH=linux-x86-64
|
|
;;
|
|
*)
|
|
CFLAGS="-fPIC -fPIE -pie -fpic -m32"
|
|
LDFLAGS="-fPIC -fPIE -pie -fpic -m32"
|
|
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"
|
|
${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} ${LDFLAGS} ${OPT} -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
|