aboutsummaryrefslogtreecommitdiff
path: root/CRT/gen_wrapper.sh
blob: 4e261621d5094ccd6f75503f6b149337564674dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/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

    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|Mm|Io)[^ (]*')
    if [ -z "${fnname}" ]; then
        printf '%s\n' "Line ${CURLINE}: Missing function name." >&2
        VALID=0
    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
        TYPEDEFS="${TYPEDEFS}\ntypedef ${rtype} (*${fnname}_t) ${fnsig};"
        STATICS="${STATICS}\nstatic ${fnname}_t _${fnname} = NULL;"
        INITS=$(cat <<EOF
${INITS}
#ifdef __cplusplus
    RtlInitUnicodeString(&fnName, skCrypt(L"${fnname}"));
#else
    RtlInitUnicodeString(&fnName, L"${fnname}");
#endif
    _${fnname} = (${fnname}_t)MmGetSystemRoutineAddress(&fnName);
    if (_${fnname} == NULL)
    {
#ifdef __cplusplus
        DbgPrint(skCrypt("%s\\\n"), skCrypt("System routine ${fnname} not found."));
#else
        DbgPrint("%s\\\n", "System routine ${fnname} not found.");
#endif
        retval++;
    }
EOF
        )
        WRAPPERS=$(cat <<EOF
${WRAPPERS}

${rtype} ${fnname} ${fnsig}
{
EOF
        )
        case $rtype in
        NTSTATUS*)
            WRAPPERS=$(cat <<EOF
${WRAPPERS}
    if (_${fnname} == NULL)
        return STATUS_PROCEDURE_NOT_FOUND;

    return _${fnname} (${params});
}

${rtype} Wrapper${fnname} ${fnsig}
{
    return _${fnname} (${params});
}
EOF
            )
        ;;
        PVOID*)
            WRAPPERS=$(cat <<EOF
${WRAPPERS}
    return _${fnname} (${params});
}

${rtype} Wrapper${fnname} ${fnsig}
{
    return _${fnname} (${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