aboutsummaryrefslogtreecommitdiff
path: root/CRT/gen_wrapper.sh
blob: 565859bca1104c3efcf5bb1ed1ee055ab615efbc (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
#!/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)')
    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[^ (]*')
    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

    param_names=$(printf '%s\n' "${fnsig}" | tr -d '()' | 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
    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}" ]; 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}
    RtlInitUnicodeString(&fnName, L"${fnname}");
    _${fnname} = MmGetSystemRoutineAddress(&fnName);
    if (_${fnname} == NULL)
    {
        DbgPrint("%s\\\n", "System routine ${fnname} not found.");
        retval++;
    }
EOF
        )
        WRAPPERS=$(cat <<EOF
${WRAPPERS}

${rtype} ${fnname} ${fnsig}
{
    if (_${fnname} == NULL)
        return STATUS_PROCEDURE_NOT_FOUND;

    return _${fnname} (${params});
}
EOF
        )
    fi
done < "${FN_FILE}"

cat <<EOF
/* This file was auto generated by $(basename ${0}) */
#include <ntddk.h>

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}"