Initial import of radare2-extras/r2yara

This commit is contained in:
pancake committed 2023-10-04 17:49:13 +02:00
1 parent 55a2bc1241
commit c26da9d069
10 files changed
+1375

No files matched your search

+9
View File
@@ -0,0 +1,9 @@
include config.mk
mrproper: clean
rm -f config.mk
RULESDIR=$(R2PM_USRPLUGIN_DIR)/rules-yara3
all clean user-install install symstall user-uninstall uninstall:
$(MAKE) -C src $<
+4
View File
@@ -2,6 +2,10 @@
r2 and yara, better together!
## License and Author
LGPLv3 - Copyright 2014-2023 - pancake, jvoisin, jfrankowski
## Installation
After running this command:
Executable
+33
View File
@@ -0,0 +1,33 @@
#!/bin/sh
#
# Look for the 'acr' tool here: https://github.com/radare/acr
# Clone last version of ACR from here:
# git clone https://github.com/radare/acr
#
# -- pancake
r2pm -h >/dev/null 2>&1
if [ $? = 0 ]; then
echo "Installing the last version of 'acr'..."
r2pm -i acr > /dev/null
r2pm -r acr -h > /dev/null 2>&1
if [ $? = 0 ]; then
echo "Running 'acr -p'..."
r2pm -r acr -p
else
echo "Cannot find 'acr' in PATH"
fi
else
echo "Running acr..."
acr -p
fi
exit 0
V=`./configure -qV | cut -d - -f -1`
meson rewrite kwargs set project / version "$V"
if [ -n "$1" ]; then
echo "./configure $*"
./configure $*
fi
[ -z "$EDITOR" ] && EDITOR=vim
$EDITOR README.md
+24
View File
@@ -0,0 +1,24 @@
PWD=$(shell pwd)
VERSION=@VERSION@
DESTDIR=
PREFIX=@PREFIX@
HOST_OS=@HOST_OS@
LIBDIR=@LIBDIR@
INSTALL_LIB=@INSTALL_LIB@
R2PM_USRPLUGIN_DIR=$(shell r2 -H R2_USER_PLUGINS)
LIBEXT=$(shell r2 -H R2_LIBEXT)
#LIBYARA_CFLAGS=@LIBYARA_CFLAGS@
#LIBYARA_LDFLAGS=@LIBYARA_LDFLAGS@
LIBYARA_CFLAGS=
LIBYARA_LDFLAGS=-lyara
R2_CFLAGS=@R2_CFLAGS@
R2_LDFLAGS=@R2_LDFLAGS@
YR_CFLAGS=@YR_CFLAGS@
YR_LDFLAGS=@YR_LDFLAGS@
CFLAGS+=${R2_CFLAGS} ${LIBYARA_CFLAGS} ${YR_CFLAGS}
LDFLAGS+=${R2_LDFLAGS} ${LIBYARA_LDFLAGS} ${YR_LDFLAGS}
CFLAGS+=-I. -fPIC
LDFLAGS+=-shared
CFLAGS+=-DR2Y_VERSION=\"$(VERSION)\"
Vendored Executable
+465
View File
@@ -0,0 +1,465 @@
#!/bin/sh
# This script was automatically generated by ACR v2.1.2
# @author: pancake <nopcode.org>
# @url: http://www.nopcode.org
# @repo: git clone https://github.com/radare/acr
[ -z "${AWK}" ] && AWK=awk
do_remove() {
if [ "${ACR_RMFILES}" ]; then
printf "cleaning temporally files... "
rm -f ${ACR_RMFILES}
echo "done"
fi
}
control_c() {
printf "\n\n^C control-c : script execution interrupted.\n"
do_remove
exit 1
}
trap control_c 2
split_host() {
S="$"
while : ; do
ENVWORDS="${ENVWORDS} $1_CPU $1_OS"
STR=`eval "echo ${S}$1"`
SPLIT_CPU="`echo "$STR" | cut -d - -f 1`"
SPLIT_OS="`echo "$STR" | $AWK -F - '{
if ($2=="unknown"){
if (NF<3) { print $2; } else { print $3; }
} else {
if ($2=="linux") { print $2; } else
if (NF<3) { print $2; } else { print $3; }
}
}'`"
eval "$1_CPU=\"$SPLIT_CPU\""
eval "$1_OS=\"$SPLIT_OS\""
shift
[ -z "$1" ] && break
done
}
QUIET=0
be_quiet() {
QUIET=1
}
VPATH=`dirname ${0}`
if [ "${VPATH}" = "." ]; then
WODIS=current
else
if [ "${VPATH}" = "${PWD}" ]; then
VPATH=.
WODIS=current
else
WODIS=crosspath
CURDIR=$PWD
cd $VPATH
VPATH="${PWD}/"
cd $CURDIR
fi
fi
guess_os() {
if [ -e "${VPATH}/config.guess" ]; then
sh ${VPATH}/config.guess
return
fi
CPU="`uname -m|sed -e 's, ,,g'|cut -d - -f 1`"
OS="`uname -s|tr A-Z a-z`"
uname -r | grep -qE "(Microsoft|WSL)" 2>/dev/null && OS="wsl"
GNU="`uname --help 2>&1 | grep gnu`"
[ "${GNU}" ] && OS="${OS}-gnu"
[ "${CPU}" = ppc ] && CPU="powerpc"
echo "${CPU}-unknown-${OS}"
}
SEARCHPATH="/usr /usr/local /usr/pkg /sw"
: ${PREFIX:=/usr/local}
CROSSBUILD=0
BUILD=`guess_os`
HOST="${BUILD}"
TARGET="${HOST}"
ETCDIR="/etc"
SYSCONFDIR=""
DESCRIPTION="yara plugin for radare2"
create_environ() {
: ${EPREFIX:="${PREFIX}"}
: ${SPREFIX:="${PREFIX}"}
: ${BINDIR:="${SPREFIX}/bin"}
: ${SBINDIR:="${PREFIX}/sbin"}
: ${ETCDIR:="${SPREFIX}/etc"}
: ${LIBDIR:="${SPREFIX}/lib"}
: ${PKGCFG_LIBDIR:='${exec_prefix}/lib'}
: ${PKGCFG_INCDIR:='${prefix}/include'}
: ${LIBEXECDIR:="${SPREFIX}/libexec"}
: ${INCLUDEDIR:="${SPREFIX}/include"}
: ${DATADIR:="${SPREFIX}/share"}
: ${INFODIR:="${DATADIR}/info"}
: ${MANDIR:="${DATADIR}/man"}
: ${DOCDIR:="${DATADIR}/doc/r2yara"}
: ${LOCALSTATEDIR:="${SPREFIX}/var"}
for A in `echo ${PATH} | sed -e 's,:, ,g'` ; do
[ -e "$A"/ginstall ] && : ${INSTALL:="$A"/ginstall} && break
[ -e "$A"/install ] && : ${INSTALL:="$A"/install} && break
done
: ${INSTALL_DIR:=${INSTALL} -d}
: ${INSTALL_DATA:=${INSTALL} -m 644}
: ${INSTALL_SCRIPT:=${INSTALL} -m 755}
: ${INSTALL_PROGRAM:=${INSTALL} -m 755}
: ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s}
: ${INSTALL_MAN:=${INSTALL} -m 444}
: ${INSTALL_LIB:=${INSTALL} -m 755 -c}
PKGNAME='r2yara' ; VERSION='1.1.0' ; VERSION_MAJOR=1; VERSION_MINOR=1; VERSION_PATCH=0; VERSION_NUMBER=10100; CONTACT_MAIL="[email protected]" ; CONTACT_NAME="jfrankowski" ; CONTACT="jfrankowski <[email protected]>" ;
}
show_usage() {
cat <<EOF2
'configure' configures r2yara-1.1.0 to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
-r, --report show what libs/programs require to work
-q, --quiet be quiet, less verbose (see ./configure -qV)
-V, --version display version information and exit
Installation directories:
--exec-prefix=EPREFIX install arch-dependent files in EPREFIX [PREFIX]
--prefix=PREFIX install arch-independent files in PREFIX [/usr/local]
--sandbox=SPREFIX sandbox prefix directory: SPREFIX [PREFIX]
Fine tuning of the installation directories:
--bindir=DIR user executables [EPREFIX/bin]
--datadir=DIR read-only architecture-independent data [PREFIX/share]
--docdir=DIR documentation directory [DATADIR/doc/r2yara]
--includedir=DIR C header files [PREFIX/include]
--infodir=DIR info documentation [DATADIR/info]
--libexecdir=DIR program executables [EPREFIX/libexec]
--libdir=DIR object code libraries [EPREFIX/lib]
--libpath=DIR set rpath/libname-path to linker
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--mandir=DIR man documentation [DATADIR/man]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--etcdir=DIR same as --sysconfdir (/etc)
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
System types:
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
--target=TARGET configure for building compilers for TARGET [HOST]
EOF2
printf "
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
headers in a nonstandard directory <include dir>
CPP C preprocessor
"
printf "
Report bugs to: jfrankowski <[email protected]>"
echo ""
exit 0
}
take_environ() {
: ${SH:=/bin/sh}
: ${CPP:=cpp}
: ${CC:=gcc}
: ${PREFIX:=/usr/local/}
}
ochof() {
[ "$QUIET" = 1 ] && return
printf "$*"
}
ocho() {
[ "$QUIET" = 1 ] && return
echo "$*"
}
show_version() {
if [ "$QUIET" = 1 ]; then
echo "1.1.0"
exit 0
fi
echo "r2yara-1.1.0 configuration script done with acr v2.1.2.
The 'Free Software Foundation' message is only for autodetection.
Originally written by pancake <nopcode.org>."
exit 0
}
parse_options() {
flag=`echo $1| cut -d = -f 1`
value=`echo $1| $AWK 'BEGIN{FS="=";}{print $2}'`
flag2=`echo $flag|cut -f2- -d -| sed -e 's,-,_,g' -e 's,^_,,g'|tr '[a-z]' '[A-Z]'`
if [ "${TARGET_OS}" = "darwin" ]; then
LIBPATH=-Wl,-install_name,
else
LIBPATH=-Wl,-R
fi
case $flag in
-h|--help|--hel|--h|--he|-help)
show_usage ; ;;
-qV|-quiet-version|--quiet-version)
be_quiet
show_version ; ;;
-q|-quiet|--quiet)
be_quiet ; ;;
-V|-version|--version)
show_version ; ;;
-r|--r|--report)
echo "PKGNAME: r2yara"
echo "VERSION: 1.1.0"
echo "AUTHOR: jfrankowski"
echo "EMAIL: [email protected]"
echo "DESCRIPTION: yara plugin for radare2"
echo "LANGS: c"
echo "REQUIRED: libyara"
echo "PKGCONFIG: yara r_core"
exit 0
;;
--cache-file)
# ignored: acr have no cache
;;
--build)
BUILD="$value"; split_host BUILD ; ;;
--host)
CROSSBUILD=1 # XXX
HOST="$value"; split_host HOST ; ;;
--target)
TARGET="$value"; split_host TARGET ; ;;
--prefix)
PREFIX="$value"; ;;
--exec-prefix)
EPREFIX="$value"; ;;
--sandbox|--sprefix)
SPREFIX="$value"; ;;
--bindir)
BINDIR="$value"; ;;
--sbindir)
SBINDIR="$value"; ;;
--libexecdir)
LIBEXECDIR="$value"; ;;
--docdir)
DOCDIR="$value"; ;;
--datadir)
DATADIR="$value"; ;;
--sysconfdir)
SYSCONFDIR="$value"
ETCDIR="$value"; ;;
--etcdir)
SYSCONFDIR="$value"
ETCDIR="$value"; ;;
--sharedstatedir)
SHAREDSTATEDIR="$value"; ;;
--localstatedir)
LOCALSTATEDIR="$value"; ;;
--libdir)
LIBDIR="$value"
PKGCFG_LIBDIR="$value"; ;;
--libpath)
LDFLAGS="${LDFLAGS} ${LIBPATH}$value"; ;;
--includedir)
PKGCFG_INCDIR="$value"
INCLUDEDIR="$value"; CFLAGS="${CFLAGS} -I$value"; ;;
--infodir)
INFODIR="$value"; ;;
--mandir)
MANDIR="$value"; ;;
*) if [ "$value" ]; then eval "`echo $flag2=$value`" ;
else echo ; echo "WARNING: Unknown flag '$flag'." >&2 ; echo ; fi ;;
esac
}
# MAIN #
take_environ
split_host BUILD HOST TARGET
[ -z "$ACRHOOK" ] && ACRHOOK=./configure.hook
[ -e "$ACRHOOK" ] && . ${ACRHOOK}
while : ; do
[ -z "$1" ] && break
parse_options "$1"
shift
done
ENVWORDS="MANDIR DESCRIPTION INFODIR LIBDIR INCLUDEDIR LOCALSTATEDIR ETCDIR SYSCONFDIR DATADIR DOCDIR LIBEXECDIR SBINDIR BINDIR EPREFIX PREFIX SPREFIX TARGET HOST BUILD INSTALL INSTALL_LIB INSTALL_MAN INSTALL_PROGRAM INSTALL_PROGRAM_STRIP INSTALL_DIR INSTALL_SCRIPT INSTALL_DATA HOST_OS HOST_CPU BUILD_OS BUILD_CPU TARGET_OS TARGET_CPU VERSION VERSION_MAJOR VERSION_MINOR VERSION_PATCH VERSION_NUMBER PKGCFG_LIBDIR PKGCFG_INCDIR PKGNAME VPATH CONTACT CONTACT_NAME CONTACT_MAIL PKGCONFIG CC CFLAGS CPPFLAGS LDFLAGS HAVE_LANG_C HAVE_LIB_YARA YR_CFLAGS YR_LDFLAGS HAVE_PKGCFG_YARA R2_CFLAGS R2_LDFLAGS HAVE_PKGCFG_R_CORE"
create_environ
ocho "checking build system type... ${BUILD}"
ocho "checking host system type... ${HOST}"
ocho "checking target system type... ${TARGET}"
[ "${CROSSBUILD}" = 1 ] && echo "using crosscompilation mode."
#split_host BUILD HOST TARGET
[ -n "${prefix}" ] && PREFIX="${prefix}"
ocho "checking for working directories... ${WODIS}"
ocho "using prefix '${PREFIX}'"
ACR_RMFILES=" test.c a.out a.exe"
ochof "checking for pkg-config... "
if [ -n "$PKGCONFIG" ]; then
if [ -x "$PKGCONFIG" ]; then
_HAVE_PKGCONFIG="${PKGCONFIG}"
else
ocho "PKGCONFIG env is not executable"
PKGCONFIG=""
fi
else
IFS=:
for A in ${PATH} ; do
if [ -x "${A}/pkg-config" ]; then
PKGCONFIG="${A}/pkg-config"
elif [ -x "${A}/pkgconf" ]; then
PKGCONFIG="${A}/pkgconf"
else
continue
fi
break
done
unset IFS
fi
if [ -n "${PKGCONFIG}" ]; then
ocho ${PKGCONFIG}
else
echo "Cannot find pkg-config or pkgconf in PATH" >&2
exit 1
ocho no; fi
COMPILER=CC
ochof "checking for c compiler... "
HAVE_LANG_C=1
if [ "${CROSSBUILD}" = 1 ]; then
(command -v ${HOST}-${CC} >/dev/null 2>&1)
if [ $? = 0 ]; then CC="${HOST}-${CC}"; fi
fi
echo "int main(int argc, char **argv){return 0;}" > test.c
(exec ${CC} -o a.out ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} test.c >/dev/null 2>&1)
if [ $? = 0 ]; then echo ${CC}; else
echo no ; HAVE_LANG_C=0
do_remove
echo "ERROR: ${CC} cannot create executables" >&2 ;
exit 1 ; fi
check_library() {
VAR=$1
S="$"
_REQUIRED=$3
_CHKLIB_NAME=$2
_CHKLIB_LIBS=$(echo "-l${_CHKLIB_NAME}" | sed 's,+, -l,g')
ochof "checking for lib${_CHKLIB_NAME} ... "
echo "int main(int ac, char **av){return 0;}" > test.c
eval ${S}${COMPILER} ${CFLAGS} ${CPPFLAGS} ${CXXFLAGS} ${LDFLAGS} ${_CHKLIB_LIBS} test.c >/dev/null 2>&1
if [ $? = 0 ]; then
eval ${VAR}=1
echo yes
else
eval ${VAR}=0
echo no
if [ "${_REQUIRED}" = 1 ]; then
echo "this library is required."
do_remove
exit 1
fi
fi
}
check_library HAVE_LIB_YARA yara 1
if [ -z "${PKGCONFIG}" ]; then pkg-config --version >/dev/null 2>&1 ; if [ 0 = 0 ]; then PKGCONFIG=pkg-config ; else PKGCONFIG=pkgconf ; fi; fi
type ${PKGCONFIG} > /dev/null 2>&1 || echo "ERROR: Cannot find valid PKGCONFIG, pkg-config or pkgconf in PATH"
echo 'Using PKGCONFIG: '${PKGCONFIG}
printf 'checking pkg-config flags for yara... '
tmp=`${PKGCONFIG} --cflags yara 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_YARA=0;
YR_CFLAGS='';YR_LDFLAGS='';
echo 'This package is required'
exit 1
else
YR_CFLAGS=$tmp;
tmp=`${PKGCONFIG} --libs yara 2>/dev/null`
if [ $? = 0 ]; then
echo yes; HAVE_PKGCFG_YARA=1;
YR_LDFLAGS=$tmp; fi; fi
if [ -z "${PKGCONFIG}" ]; then pkg-config --version >/dev/null 2>&1 ; if [ 0 = 0 ]; then PKGCONFIG=pkg-config ; else PKGCONFIG=pkgconf ; fi; fi
printf 'checking pkg-config flags for r_core... '
tmp=`${PKGCONFIG} --cflags r_core 2>/dev/null`
if [ $? != 0 ]; then echo no ; HAVE_PKGCFG_R_CORE=0;
R2_CFLAGS='';R2_LDFLAGS='';
echo 'This package is required'
exit 1
else
R2_CFLAGS=$tmp;
tmp=`${PKGCONFIG} --libs r_core 2>/dev/null`
if [ $? = 0 ]; then
echo yes; HAVE_PKGCFG_R_CORE=1;
R2_LDFLAGS=$tmp; fi; fi
SEDFLAGS=" -e '"
COUNT=0
for A in ${ENVWORDS} ; do
[ "${A}" = VPATH ] && continue
[ "${A}" = srcdir ] && continue
eval "VAR=\$${A}"
VAR="`echo ${VAR} | sed -e 's/\,/\\\,/g'`"
[ $COUNT = 10 ] && COUNT=0 && SEDFLAGS="${SEDFLAGS}' -e '"
COUNT=$(($COUNT+1))
SEDFLAGS="${SEDFLAGS}s,@${A}@,${VAR},g;"
done
SEDFLAGS="${SEDFLAGS}'"
for A in . config.mk ; do # SUBDIRS
if [ -f "${VPATH}/${A}.acr" ]; then
SD_TARGET=${A}
else
if [ -d "${VPATH}/${A}" ]; then
SD_TARGET=${A}/Makefile
mkdir -p ${A}
else
echo "ERROR: Cannot find ${VPATH}/${A}.acr" >&2
exit 1
fi
fi
ocho "creating ${SD_TARGET}"
[ "${VPATH}" != '.' ] && mkdir -p $(echo ${A} | sed -e "s,/`basename ${A}`$,,g")
cat ${VPATH}/${SD_TARGET}.acr | \
eval sed -e "s,@VPATH@,${VPATH}/${A},g" ${SEDFLAGS} > ${SD_TARGET}.tmp
for A in ${ENVWORDS}; do
VALUE=`eval echo "$"${A}`
if [ "$VALUE" = 0 ]; then ## FALSE
MARK="##${A}##"
if [ -n "`grep \"${MARK}\" ${SD_TARGET}.tmp`" ]; then
mv ${SD_TARGET}.tmp ${SD_TARGET}.tmp2
cat ${SD_TARGET}.tmp2 | MARK=$MARK $AWK 'BEGIN{a=0;}{if($1==ENVIRON["MARK"]){if(a)a=0;else a=1}else{if(!a)print;}}' > ${SD_TARGET}.tmp
fi
fi
done
mv ${SD_TARGET}.tmp ${SD_TARGET} && rm -f ${SD_TARGET}.tmp2
if [ ! $? = 0 ]; then echo Cannot write target file ; control_c ; fi
done
do_remove
if [ "$QUIET" = 0 ]; then
echo
echo "Final report:"
for A in PREFIX ; do
eval VAL="\$${A}"
[ -z "${VAL}" ] && VAL="\"\""
echo " - ${A} = ${VAL}"
done
fi
+15
View File
@@ -0,0 +1,15 @@
PKGNAME r2yara
VERSION 1.1.0
DESCRIPTION yara plugin for radare2 ;
CONTACT jfrankowski ; [email protected]
REPORT PREFIX ;
USE_PKGCONFIG!
LANG_C!
CHKLIB! yara
PKGCFG! YR_CFLAGS YR_LDFLAGS yara
PKGCFG! R2_CFLAGS R2_LDFLAGS r_core
SUBDIRS . config.mk ;
+187
View File
@@ -0,0 +1,187 @@
/*
Copyright (c) 2014, Colin Childs <[email protected]>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the names of the copyright owners nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
rule BLOWFISH_Constants : crypto {
meta:
author = "phoul (@phoul)"
description = "Look for Blowfish constants"
date = "2014-01"
version = "0.1"
strings:
$c0 = { D1310BA6 }
$c1 = { A60B31D1 }
$c2 = { 98DFB5AC }
$c3 = { ACB5DF98 }
$c4 = { 2FFD72DB }
$c5 = { DB72FD2F }
$c6 = { D01ADFB7 }
$c7 = { B7DF1AD0 }
$c8 = { 4B7A70E9 }
$c9 = { E9707A4B }
$c10 = { F64C261C }
$c11 = { 1C264CF6 }
condition:
6 of them
}
rule MD5_Constants : crypto {
meta:
author = "phoul (@phoul)"
description = "Look for MD5 constants"
date = "2014-01"
version = "0.2"
strings:
// Init constants
$c0 = { 67452301 }
$c1 = { efcdab89 }
$c2 = { 98badcfe }
$c3 = { 10325476 }
$c4 = { 01234567 }
$c5 = { 89ABCDEF }
$c6 = { FEDCBA98 }
$c7 = { 76543210 }
// Round 2
$c8 = { F4D50d87 }
$c9 = { 78A46AD7 }
condition:
5 of them
}
rule RC6_Constants : crypto {
meta:
author = "chort (@chort0)"
description = "Look for RC6 magic constants in binary"
reference = "https://twitter.com/mikko/status/417620511397400576"
reference2 = "https://twitter.com/dyngnosis/status/418105168517804033"
date = "2013-12"
version = "0.2"
strings:
$c1 = { B7E15163 }
$c2 = { 9E3779B9 }
$c3 = { 6351E1B7 }
$c4 = { B979379E }
condition:
2 of them
}rule RIPEMD160_Constants : crypto {
meta:
author = "phoul (@phoul)"
description = "Look for RIPEMD-160 constants"
date = "2014-01"
version = "0.1"
strings:
$c0 = { 67452301 }
$c1 = { EFCDAB89 }
$c2 = { 98BADCFE }
$c3 = { 10325476 }
$c4 = { C3D2E1F0 }
$c5 = { 01234567 }
$c6 = { 89ABCDEF }
$c7 = { FEDCBA98 }
$c8 = { 76543210 }
$c9 = { F0E1D2C3 }
condition:
5 of them
}
rule SHA1_Constants : crypto {
meta:
author = "phoul (@phoul)"
description = "Look for SHA1 constants"
date = "2014-01"
version = "0.1"
strings:
$c0 = { 67452301 }
$c1 = { EFCDAB89 }
$c2 = { 98BADCFE }
$c3 = { 10325476 }
$c4 = { C3D2E1F0 }
$c5 = { 01234567 }
$c6 = { 89ABCDEF }
$c7 = { FEDCBA98 }
$c8 = { 76543210 }
$c9 = { F0E1D2C3 }
condition:
5 of them
}
rule SHA256_Constants : crypto {
meta:
author = "phoul (@phoul)"
description = "Look for SHA224/SHA256 constants"
date = "2014-01"
version = "0.1"
strings:
$c0 = { 428a2f98 }
$c1 = { 982F8A42 }
$c2 = { 71374491 }
$c3 = { 91443771 }
$c4 = { B5C0FBCF }
$c5 = { CFFBC0B5 }
$c6 = { E9B5DBA5 }
$c7 = { A5DBB5E9 }
// Exclude
$e0 = { D728AE22 }
$e1 = { 22AE28D7 }
condition:
4 of ($c0,$c1,$c2,$c3,$c4,$c5,$c6,$c7) and not ($e0 or $e1)
}
rule SHA512_Constants : crypto {
meta:
author = "phoul (@phoul)"
description = "Look for SHA384/SHA512 constants"
date = "2014-01"
version = "0.1"
strings:
$c0 = { 428a2f98 }
$c1 = { 982F8A42 }
$c2 = { 71374491 }
$c3 = { 91443771 }
$c4 = { B5C0FBCF }
$c5 = { CFFBC0B5 }
$c6 = { E9B5DBA5 }
$c7 = { A5DBB5E9 }
$c8 = { D728AE22 }
$c9 = { 22AE28D7 }
condition:
5 of them
}
rule WHIRLPOOL_Constants : crypto {
meta:
author = "phoul (@phoul)"
description = "Look for WhirlPool constants"
date = "2014-02"
version = "0.1"
strings:
$c0 = { 18186018c07830d8 }
$c1 = { d83078c018601818 }
$c2 = { 23238c2305af4626 }
$c3 = { 2646af05238c2323 }
condition:
2 of them
}
+11
View File
@@ -0,0 +1,11 @@
rule HelloWorld : foo {
meta:
author = "pancake"
description = "hello world"
date = "2023-10"
version = "0.1"
strings:
$ = "lib"
condition:
all of them
}
+32
View File
@@ -0,0 +1,32 @@
include ../config.mk
MOD=core_yara
all: $(MOD).$(LIBEXT)
$(MOD).$(LIBEXT): ${MOD}.o
$(CC) -g ${MOD}.o ${CFLAGS} ${LDFLAGS} -o ${MOD}.${LIBEXT}
clean:
rm -f ${MOD}.o ${MOD}.${LIBEXT}
mrproper: clean
rm -f Makefile
RULESDIR=$(R2PM_USRPLUGIN_DIR)/rules-yara3
user-install install:
${INSTALL_LIB} ${MOD}.${LIBEXT} $(R2PM_USRPLUGIN_DIR)/${MOD}.${LIBEXT}
mkdir -p $(RULESDIR)
cp -rf *.gz $(RULESDIR)
symstall:
ln -fs ${PWD}/${MOD}.${LIBEXT} $(R2PM_USRPLUGIN_DIR)/$(MOD).$(LIBEXT)
rm -rf $(R2PM_USRPLUGIN_DIR)/yara
mkdir -p $(RULESDIR)
for a in *.gz ; do ln -fs $(PWD)/$$a $(RULESDIR)/$$a ; done
user-uninstall uninstall:
rm -f ${R2PM_USRPLUGIN_DIR}/$(MOD).$(LIBEXT)
rm -rf $(RULESDIR)
rm -rf ${R2PM_USRPLUGIN_DIR}/yara
+595
View File
@@ -0,0 +1,595 @@
/* radare - LGPLv3 - Copyright 2014-2023 - pancake, jvoisin, jfrankowski */
#include <r_core.h>
#include <yara.h>
// TODO: remove globals!
static R_TH_LOCAL bool initialized = false;
static R_TH_LOCAL bool print_strings = false;
static R_TH_LOCAL unsigned int flagidx = 0;
static R_TH_LOCAL bool io_va = true;
static R_TH_LOCAL RList* rules_list = NULL;
#if YR_MAJOR_VERSION < 4
static int callback(int message, void* rule, void* data);
#else
static int callback(YR_SCAN_CONTEXT* context, int message, void* rule, void* data);
#endif
static int cmd_yara_add(const RCore* core, const char* input);
static int cmd_yara_add_file(const char* rules_path);
static int cmd_yara_call(void *user, const char *input);
static int cmd_yara_clear();
static int cmd_yara_init(void *user, const char *cmd);
static int cmd_yara_help(const RCore* core);
static int cmd_yara_process(const RCore* core, const char* input);
static int cmd_yara_scan(const RCore* core, const char* option);
static int cmd_yara_load_default_rules(const RCore* core);
static const char yara_rule_template[] = "rule RULE_NAME {\n strings:\n\n condition:\n}";
/* Because of how the rules are compiled, we are not allowed to add more
* rules to a compiler once it has compiled. That's why we keep a list
* of those compiled rules.
*/
#if YR_MAJOR_VERSION < 4
static int callback (int message, void *msg_data, void *user_data) {
RCore *core = (RCore *) user_data;
RPrint *print = core->print;
unsigned int ruleidx;
st64 offset = 0;
ut64 n = 0;
YR_RULE* rule = msg_data;
if (message == CALLBACK_MSG_RULE_MATCHING) {
YR_STRING* string;
r_cons_printf ("%s\n", rule->identifier);
ruleidx = 0;
yr_rule_strings_foreach (rule, string) {
YR_MATCH* match;
yr_string_matches_foreach (string, match) {
n = match->base + match->offset;
// Find virtual address if needed
if (io_va) {
RIOMap *map = r_io_map_get_paddr (core->io, n);
if (map) {
offset = r_io_map_begin (map) - map->delta;
}
}
r_strf_var (flag, 256, "%s%d_%s_%d", "yara", flagidx, rule->identifier, ruleidx);
if (print_strings) {
r_cons_printf ("0x%08" PFMT64x ": %s : ", n + offset, flag);
r_print_bytes (print, match->data, match->data_length, "%02x");
}
r_flag_set (core->flags, flag, n + offset, match->data_length);
ruleidx++;
}
}
flagidx++;
}
return CALLBACK_CONTINUE;
}
static void compiler_callback(int error_level, const char* file_name,
int line_number, const char* message, void* user_data) {
// TODO depending on error_level. use R_LOG_WARN, ERROR or INFO
eprintf ("file: %s line_number: %d.\n%s", file_name, line_number, message);
return;
}
#else
static int callback (YR_SCAN_CONTEXT* context, int message, void *msg_data, void *user_data) {
RCore *core = (RCore *) user_data;
RPrint *print = core->print;
unsigned int ruleidx;
st64 offset = 0;
ut64 n = 0;
YR_RULE* rule = msg_data;
if (message == CALLBACK_MSG_RULE_MATCHING) {
YR_STRING* string;
r_cons_printf ("%s\n", rule->identifier);
ruleidx = 0;
yr_rule_strings_foreach (rule, string) {
YR_MATCH* match;
yr_string_matches_foreach (context, string, match) {
n = match->base + match->offset;
// Find virtual address if needed
if (io_va) {
RIOMap *map = r_io_map_get_paddr (core->io, n);
if (map) {
offset = r_io_map_begin (map) - map->delta;
}
}
r_strf_var (flag, 256, "%s%d_%s_%d", "yara", flagidx, rule->identifier, ruleidx);
if (print_strings) {
r_cons_printf ("0x%08" PFMT64x ": %s : ", n + offset, flag);
r_print_bytes (print, match->data, match->data_length, "%02x");
}
r_flag_set (core->flags, flag, n + offset, match->data_length);
ruleidx++;
}
}
flagidx++;
}
return CALLBACK_CONTINUE;
}
static void compiler_callback(int error_level, const char* file_name,
int line_number, const struct YR_RULE *rule, const char* message, void* user_data) {
// TODO depending on error_level. use R_LOG_WARN, ERROR or INFO
eprintf ("file: %s line_number: %d.\n%s", file_name, line_number, message);
return;
}
#endif
static int cmd_yara_scan(const RCore* core, R_NULLABLE const char* option) {
RListIter* rules_it;
YR_RULES* rules;
void* to_scan;
r_flag_space_push (core->flags, "yara");
const unsigned int to_scan_size = r_io_size (core->io);
io_va = r_config_get_b (core->config, "io.va");
if (to_scan_size < 1) {
R_LOG_ERROR ("Invalid file size");
return false;
}
if (option != NULL) {
if (*option == '\0') {
print_strings = false;
} else if (*option == 'S') {
print_strings = true;
} else {
print_strings = false;
R_LOG_ERROR ("Invalid option");
return false;
}
}
to_scan = malloc (to_scan_size);
if (!to_scan) {
R_LOG_ERROR ("Something went wrong during memory allocation");
return false;
}
int result = r_io_pread_at (core->io, 0L, to_scan, to_scan_size);
if (!result) {
R_LOG_ERROR ("Something went wrong during r_io_read_at");
free (to_scan);
return false;
}
r_list_foreach (rules_list, rules_it, rules) {
yr_rules_scan_mem (rules, to_scan, to_scan_size, 0, callback, (void *)core, 0);
}
free (to_scan);
return true;
}
static int cmd_yara_show(const char * name) {
/* List loaded rules containing name */
RListIter* rules_it;
YR_RULES* rules;
YR_RULE* rule;
r_list_foreach (rules_list, rules_it, rules) {
yr_rules_foreach (rules, rule) {
if (r_str_casestr (rule->identifier, name)) {
r_cons_printf ("%s\n", rule->identifier);
}
}
}
return true;
}
static int cmd_yara_tags() {
/* List tags from all the different loaded rules */
RListIter* rules_it;
RListIter *tags_it;
YR_RULES* rules;
YR_RULE* rule;
const char* tag_name;
RList *tag_list = r_list_new();
tag_list->free = free;
r_list_foreach (rules_list, rules_it, rules) {
yr_rules_foreach(rules, rule) {
yr_rule_tags_foreach(rule, tag_name) {
if (! r_list_find (tag_list, tag_name, (RListComparator)strcmp)) {
r_list_add_sorted (tag_list,
strdup (tag_name), (RListComparator)strcmp);
}
}
}
}
r_cons_printf ("[YARA tags]\n");
r_list_foreach (tag_list, tags_it, tag_name) {
r_cons_printf ("%s\n", tag_name);
}
r_list_free (tag_list);
return true;
}
static int cmd_yara_tag(const char * search_tag) {
/* List rules with tag search_tag */
RListIter* rules_it;
YR_RULES* rules;
YR_RULE* rule;
const char* tag_name;
r_list_foreach (rules_list, rules_it, rules) {
yr_rules_foreach (rules, rule) {
yr_rule_tags_foreach(rule, tag_name) {
R_LOG_WARN ("Invalid option");
if (r_str_casestr (tag_name, search_tag)) {
r_cons_printf ("%s\n", rule->identifier);
break;
}
}
}
}
return true;
}
static int cmd_yara_list() {
/* List all loaded rules */
RListIter* rules_it;
YR_RULES* rules;
YR_RULE* rule;
r_list_foreach (rules_list, rules_it, rules) {
yr_rules_foreach (rules, rule) {
r_cons_printf ("%s\n", rule->identifier);
}
}
return true;
}
static int cmd_yara_clear() {
/* Clears all loaded rules */
r_list_free (rules_list);
rules_list = r_list_newf ((RListFree) yr_rules_destroy);
R_LOG_INFO ("Rules cleared");
return true;
}
static void logerr(YR_COMPILER* compiler, R_NULLABLE const char *arg) {
char buf[64];
const char *errmsg = yr_compiler_get_error_message (compiler, buf, sizeof (buf));
if (arg) {
R_LOG_ERROR ("%s %s", errmsg, arg);
} else {
R_LOG_ERROR ("%s", errmsg);
}
}
static int cmd_yara_add(const RCore* core, const char* input) {
if (!input) {
R_LOG_ERROR ("Missing argument");
return false;
}
/* Add a rule with user input */
YR_COMPILER* compiler = NULL;
int result, i, continue_edit;
for (i = 0; input[i]; i++) {
if (input[i] != ' ') {
return cmd_yara_add_file (input + i);
}
}
if (yr_compiler_create (&compiler) != ERROR_SUCCESS) {
logerr (compiler, NULL);
return false;
}
char *old_template = strdup (yara_rule_template);
char *modified_template = NULL;
do {
char *modified_template = r_core_editor (core, NULL, old_template);
R_FREE (old_template);
if (!modified_template) {
R_LOG_ERROR ("Something bad happened with the temp file");
goto err_exit;
}
result = yr_compiler_add_string (compiler, modified_template, NULL);
if (result > 0) {
logerr (compiler, NULL);
continue_edit = r_cons_yesno ('y', "Do you want to continue editing the rule? [y]/n\n");
if (!continue_edit) {
goto err_exit;
}
old_template = modified_template;
modified_template = NULL;
}
} while (result > 0);
free (modified_template);
if (compiler != NULL) {
yr_compiler_destroy (compiler);
}
R_LOG_INFO ("Rule successfully added");
return true;
err_exit:
if (compiler != NULL) {
yr_compiler_destroy (compiler);
}
free (modified_template);
free (old_template);
return false;
}
static int cmd_yara_add_file(const char* rules_path) {
YR_COMPILER* compiler = NULL;
YR_RULES* rules;
if (!rules_path) {
R_LOG_INFO ("Please tell me what am I supposed to load");
return false;
}
FILE* rules_file = r_sandbox_fopen (rules_path, "r");
if (!rules_file) {
R_LOG_ERROR ("Unable to open %s", rules_path);
return false;
}
if (yr_compiler_create (&compiler) != ERROR_SUCCESS) {
logerr (compiler, NULL);
goto err_exit;
}
int result = yr_compiler_add_file (compiler, rules_file, NULL, rules_path);
fclose (rules_file);
rules_file = NULL;
if (result > 0) {
logerr (compiler, rules_path);
goto err_exit;
}
if (yr_compiler_get_rules (compiler, &rules) != ERROR_SUCCESS) {
logerr (compiler, NULL);
goto err_exit;
}
r_list_append (rules_list, rules);
yr_compiler_destroy (compiler);
return true;
err_exit:
if (compiler) {
yr_compiler_destroy (compiler);
}
if (rules_file) {
fclose (rules_file);
}
return false;
}
const char *short_help_message[] = {
"Usage: yr", "[action] [args..]", " load and run yara rules inside r2",
"yr", " [file]", "add yara rules from file",
"yr", "-*", "unload all the rules",
"yr", "?", "show this help (same as 'yara?')",
"yr", "", "list loaded rules",
"yr", "s[S]", "scan the current file, if S option is given it prints matching strings",
"yr", "t", "list tags from the loaded rules",
"yr", "t [tagname]", "list rules with given tag",
"yr", "v", "show version information about r2yara and yara",
NULL
};
const char *long_help_message[] = {
"Usage: yara", " [action] [args..]", " load and run yara rules inside r2",
"yara", " add [file]", "Add yara rules from file, or open $EDITOR with yara rule template",
"yara", " clear", "Clear all rules",
"yara", " help", "Show this help (same as 'yara?')",
"yara", " list", "List all rules",
"yara", " scan[S]", "Scan the current file, if S option is given it prints matching strings",
"yara", " show [name]", "Show rules containing name",
"yara", " tag [name]", "List rules with tag 'name'",
"yara", " tags", "List tags from the loaded rules",
"yara", " version", "Show version information about r2yara and yara",
NULL
};
static int cmd_yara_process(const RCore* core, const char* input) {
char *inp = strdup (input);
char *arg = r_str_after (inp, ' ');
if (arg) {
arg = (char *)r_str_trim_head_ro (arg);
}
int res = -1;
if (r_str_startswith (input, "add")) {
res = cmd_yara_add (core, arg);
} else if (r_str_startswith (inp, "clear")) {
res = cmd_yara_clear ();
} else if (r_str_startswith (inp, "list")) {
res = cmd_yara_list ();
} else if (r_str_startswith (inp, "scanS") || r_str_startswith (inp, "scan S")) {
res = cmd_yara_scan (core, "S");
} else if (r_str_startswith (inp, "scan")) {
res = cmd_yara_scan (core, arg);
} else if (r_str_startswith (inp, "show")) {
res = cmd_yara_show (arg);
} else if (r_str_startswith (inp, "tags")) {
res = cmd_yara_tags ();
} else if (r_str_startswith (input, "tag ")) {
res = cmd_yara_tag (arg);
} else if (r_str_startswith (input, "ver")) {
r_cons_printf ("r2 %s\n", R2_VERSION);
r_cons_printf ("yara %s\n", YR_VERSION);
r_cons_printf ("r2yara %s\n", R2Y_VERSION);
res = 0;
} else {
r_core_cmd_help (core, long_help_message);
}
free (inp);
return res;
}
static int cmd_yr(RCore *core, const char *input) {
char *inp = strdup (input);
char *arg = r_str_after (inp, ' ');
int res = -1;
if (arg) {
arg = (char *)r_str_trim_head_ro (arg);
}
switch (*input) {
case '?': // "yr?"
r_core_cmd_help (core, short_help_message);
break;
case '/': // "yr/" <- imho makes more sense
case 's': // "yrs"
res = cmd_yara_scan (core, arg);
break;
case '+':
case ' ':
cmd_yara_add (core, arg);
break;
case '-':
cmd_yara_clear ();
break;
case 't': // "yrs"
if (input[1]) {
cmd_yara_tag (arg);
} else {
cmd_yara_tags ();
}
break;
case 0:
cmd_yara_list ();
break;
}
free (inp);
return res;
}
static int cmd_yara_call(void *user, const char *input) {
RCore* core = (RCore*) user;
if (r_str_startswith (input, "yr")) {
cmd_yr (core, input + 2);
return true;
}
if (!r_str_startswith (input, "yara")) {
return false;
}
if (!initialized && !cmd_yara_init (core, NULL)) {
return false;
}
const char *args = input[4]? input + 5: input + 4;
cmd_yara_process (core, args);
return true;
}
static int cmd_yara_load_default_rules(const RCore* core) {
RListIter* iter = NULL;
YR_COMPILER* compiler = NULL;
YR_RULES* yr_rules;
char* filename, *complete_path;
char* rules = NULL;
#if R2_VERSION_NUMBER < 50709
char* y3_rule_dir = r_str_newf ("%s%s%s", r_str_home (R2_HOME_PLUGINS), R_SYS_DIR, "rules-yara3");
#else
char* y3_rule_dir = r_xdg_datadir ("plugins/rules-yara3");
#endif
RList* list = r_sys_dir (y3_rule_dir);
if (yr_compiler_create (&compiler) != ERROR_SUCCESS) {
logerr (compiler, NULL);
goto err_exit;
}
yr_compiler_set_callback (compiler, compiler_callback, NULL);
r_list_foreach (list, iter, filename) {
if (filename[0] != '.') { // skip '.', '..' and hidden files
complete_path = r_str_newf ("%s%s%s", y3_rule_dir, R_SYS_DIR, filename);
rules = (char*)r_file_gzslurp (complete_path, NULL, true);
R_FREE (complete_path);
if (yr_compiler_add_string (compiler, rules, NULL) > 0) {
logerr (compiler, NULL);
}
R_FREE (rules);
}
}
r_list_free (list);
if (yr_compiler_get_rules (compiler, &yr_rules) != ERROR_SUCCESS) {
logerr (compiler, NULL);
goto err_exit;
}
r_list_append (rules_list, yr_rules);
if (compiler) {
yr_compiler_destroy (compiler);
}
return true;
err_exit:
free (y3_rule_dir);
if (compiler) {
yr_compiler_destroy (compiler);
}
r_list_free (list);
free (rules);
return false;
}
static int cmd_yara_init(void *user, const char *cmd) {
RCore* core = (RCore *)user;
rules_list = r_list_newf ((RListFree) yr_rules_destroy);
yr_initialize ();
cmd_yara_load_default_rules (core);
initialized = true;
flagidx = 0;
return true;
}
static int cmd_yara_fini() {
if (initialized) {
r_list_free (rules_list);
yr_finalize ();
initialized = false;
}
return true;
}
RCorePlugin r_core_plugin_yara = {
.meta = {
.name = "yara",
.desc = "YARA integration",
.license = "LGPL",
.version = "0.1.2",
},
.call = cmd_yara_call,
.init = cmd_yara_init,
.fini = cmd_yara_fini
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_CORE,
.data = &r_core_plugin_yara,
.version = R2_VERSION
};
#endif