diff options
Diffstat (limited to 'CRT/gen_wrapper.sh')
-rwxr-xr-x | CRT/gen_wrapper.sh | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/CRT/gen_wrapper.sh b/CRT/gen_wrapper.sh new file mode 100755 index 0000000..35e0d43 --- /dev/null +++ b/CRT/gen_wrapper.sh @@ -0,0 +1,174 @@ +#!/usr/bin/env sh + +MYDIR="$(dirname ${0})" +FN_FILE="${1:-${MYDIR}/ntdll_zw_functions.txt}" + +TYPEDEFS="" +STATICS="" +CURLINE=0 +while read -r line; do + CURLINE=$(expr ${CURLINE} + 1) + VALID=1 + SYMBOL_EXISTS=0 + + if [ -z "${line}" ]; then + continue + fi + if [ $(printf '%s\n' "${line}" | grep -oE '^#*') ]; then + continue + fi + + rtype=$(printf '%s\n' "${line}" | grep -oE '(NTSTATUS NTAPI|VOID NTAPI|PVOID NTAPI)') + if [ -z "${rtype}" ]; then + printf '%s\n' "Line ${CURLINE}: Missing return value of either type 'NTSTATUS NTAPI' or 'VOID NTAPI'." >&2 + VALID=0 + fi + + fnname=$(printf '%s\n' "${line}" | grep -oE '(_|)(Zw|Rtl|Ob[^j]|Mm|Io)[^ (]*') + if [ -z "${fnname}" ]; then + printf '%s\n' "Line ${CURLINE}: Missing function name." >&2 + VALID=0 + fi + if [ $(printf '%s\n' "${fnname}" | wc -l) -ne 1 ]; then + printf '%s\n' "Invalid function name '${fnname}'." >&2 + VALID=0 + fi + if [ $(printf '%s\n' "${fnname}" | grep -oE '^_*') ]; then + SYMBOL_EXISTS=1 + fi + + fnsig=$(printf '%s\n' "${line}" | grep -oE '\([^;]*') + if [ -z "${fnsig}" ]; then + printf '%s\n' "Line ${CURLINE}: Missing function signature." >&2 + VALID=0 + fi + + params_without_braces=$(printf '%s\n' "${fnsig}" | tr -d '()') + if [ ! -z "${params_without_braces}" ]; then + param_names=$(printf '%s\n' "${params_without_braces}" | sed 's/\([^,]*\)/\1\n/g' | grep -oE '[^ ]*$') + if [ -z "${param_names}" ]; then + printf '%s\n' "Line ${CURLINE}: Could not parse function parameters." >&2 + VALID=0 + fi + else + param_names="" + fi + params="" + for param in ${param_names}; do + if [ -z "${param}" ]; then + printf '%s\n' "Line ${CURLINE}: Invalid parameter found. Please re-check regex'es used." >&2 + VALID=0 + fi + params="${params}${param}, " + done + params=$(printf '%s\n' "${params}" | sed 's/^\(.*\), $/\1/g') + if [ -z "${params}" -a ! -z "${params_without_braces}" ]; then + printf '%s\n' "Line ${CURLINE}: Parameters empty. Please re-check regex'es used." >&2 + VALID=0 + fi + + if [ ${VALID} -eq 1 ]; then + TYPE="${fnname}_t" + VAR="_${fnname}" + TYPEDEFS="${TYPEDEFS}\ntypedef ${rtype} (*${TYPE}) ${fnsig};" + STATICS="${STATICS}\nstatic ${TYPE} ${VAR} = NULL;" + if [ ${SYMBOL_EXISTS} -eq 1 ]; then + fnname_str=$(printf '%s\n' "${fnname}" | sed 's/^\(.\)\{1\}//g') + else + fnname_str="${fnname}" + fi + INITS=$(cat <<EOF +${INITS} +#ifdef __cplusplus + RtlInitUnicodeString(&fnName, skCrypt(L"${fnname_str}")); +#else + RtlInitUnicodeString(&fnName, L"${fnname_str}"); +#endif + ${VAR} = (${TYPE})MmGetSystemRoutineAddress(&fnName); + if (${VAR} == NULL) + { +#ifdef __cplusplus + DbgPrint(skCrypt("%s\\\n"), skCrypt("System routine ${fnname_str} not found.")); +#else + DbgPrint("%s\\\n", "System routine ${fnname_str} not found."); +#endif + retval++; + } +EOF + ) + WRAPPERS=$(cat <<EOF +${WRAPPERS} + +${rtype} ${fnname} ${fnsig} +{ +EOF + ) + case $rtype in + NTSTATUS*) + WRAPPERS=$(cat <<EOF +${WRAPPERS} + if (${VAR} == NULL) + return STATUS_PROCEDURE_NOT_FOUND; + + return ${VAR} (${params}); +} + +${rtype} Wrapper${fnname_str} ${fnsig} +{ + return ${VAR} (${params}); +} +EOF + ) + ;; + PVOID*) + WRAPPERS=$(cat <<EOF +${WRAPPERS} + return ${VAR} (${params}); +} + +${rtype} Wrapper${fnname} ${fnsig} +{ + return ${VAR} (${params}); +} +EOF + ) + esac + fi +done < "${FN_FILE}" + +cat <<EOF +/* This file was auto generated by $(basename ${0}) */ +#include <ntddk.h> + +#ifdef __cplusplus +#define _KERNEL_MODE 1 +#include "obfuscate.hpp" + +extern "C" { +#endif +EOF +echo "${TYPEDEFS}" +echo "${STATICS}" +cat <<EOF + +int __cdecl $(basename -a -s '.txt' ${FN_FILE}) (void) +{ + int retval = 0; + UNICODE_STRING fnName; +EOF +echo "${INITS}" +cat <<EOF + + return retval; +} +EOF +echo "${WRAPPERS}" + +cat <<EOF + +#ifdef __cplusplus +}; +#endif +EOF + +printf '%s lines parsed\n' "${CURLINE}" >&2 |