Skip to content

Commit

Permalink
Added ObOpenObjectByPointer, MmCopyMemory, RtlLookupFunctionEntry, Zw…
Browse files Browse the repository at this point in the history
…ProtectVirtualMemory wrapper.

 * Improved wrapper generator script.

Signed-off-by: Toni Uhlig <[email protected]>
  • Loading branch information
utoni committed Nov 14, 2023
1 parent 649eef7 commit 9ae0188
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 8 deletions.
46 changes: 38 additions & 8 deletions CRT/gen_wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ while read -r line; do
CURLINE=$(expr ${CURLINE} + 1)
VALID=1

rtype=$(printf '%s\n' "${line}" | grep -oE '(NTSTATUS NTAPI|VOID NTAPI)')
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[^ (]*')
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
Expand All @@ -28,10 +28,15 @@ while read -r line; do
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
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
Expand All @@ -42,7 +47,7 @@ while read -r line; do
params="${params}${param}, "
done
params=$(printf '%s\n' "${params}" | sed 's/^\(.*\), $/\1/g')
if [ -z "${params}" ]; then
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
Expand All @@ -66,13 +71,38 @@ ${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}"

Expand Down
105 changes: 105 additions & 0 deletions CRT/ntdll_zw_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,50 @@
#include <ntddk.h>


typedef NTSTATUS NTAPI (*ObOpenObjectByPointer_t) (_In_ PVOID obj, _In_ ULONG HandleAttributes, _In_ PACCESS_STATE PassedAccessState, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_TYPE objType, _In_ KPROCESSOR_MODE AccessMode, _Out_ PHANDLE Handle);
typedef NTSTATUS NTAPI (*MmCopyMemory_t) (_In_ PVOID TargetAddress, _In_ PVOID SourceAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG Flags, _Out_ PSIZE_T NumberOfBytesTransferred);
typedef PVOID NTAPI (*RtlLookupFunctionEntry_t) (_In_ DWORD64 ControlPc, _Out_ PDWORD64 ImageBase, _Out_ PVOID HistoryTable);
typedef NTSTATUS NTAPI (*ZwTraceControl_t) (_In_ ULONG FunctionCode, PVOID InBuffer, _In_ ULONG InBufferLen, PVOID OutBuffer, _In_ ULONG OutBufferLen, _Out_ PULONG ReturnLength);
typedef NTSTATUS NTAPI (*ZwTraceEvent_t) (_In_ HANDLE TraceHandle, _In_ ULONG Flags, _In_ ULONG FieldSize, _In_ PVOID Fields);
typedef NTSTATUS NTAPI (*ZwQueryVirtualMemory_t) (_In_ HANDLE ProcessHandle, _In_ PVOID BaseAddress, _In_ int MemoryInformationClass, _Out_ PVOID MemoryInformation, _In_ SIZE_T MemoryInformationLength, _Out_ PSIZE_T ReturnLength);
typedef NTSTATUS NTAPI (*ZwProtectVirtualMemory_t) (_In_ HANDLE ProcessHandle, _In_ _Out_ PVOID* BaseAddress, _In_ _Out_ PULONG NumberOfBytesToProtect, _In_ ULONG NewAccessProtection, _Out_ PULONG OldAccessProtection);
typedef NTSTATUS NTAPI (*ZwQuerySystemInformation_t) (_In_ int SystemInformationClass, _Inout_ PVOID SystemInformation, _In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength);

static ObOpenObjectByPointer_t _ObOpenObjectByPointer = NULL;
static MmCopyMemory_t _MmCopyMemory = NULL;
static RtlLookupFunctionEntry_t _RtlLookupFunctionEntry = NULL;
static ZwTraceControl_t _ZwTraceControl = NULL;
static ZwTraceEvent_t _ZwTraceEvent = NULL;
static ZwQueryVirtualMemory_t _ZwQueryVirtualMemory = NULL;
static ZwProtectVirtualMemory_t _ZwProtectVirtualMemory = NULL;
static ZwQuerySystemInformation_t _ZwQuerySystemInformation = NULL;

int __cdecl ntdll_zw_functions (void)
{
int retval = 0;
UNICODE_STRING fnName;

RtlInitUnicodeString(&fnName, L"ObOpenObjectByPointer");
_ObOpenObjectByPointer = MmGetSystemRoutineAddress(&fnName);
if (_ObOpenObjectByPointer == NULL)
{
DbgPrint("%s\n", "System routine ObOpenObjectByPointer not found.");
retval++;
}
RtlInitUnicodeString(&fnName, L"MmCopyMemory");
_MmCopyMemory = MmGetSystemRoutineAddress(&fnName);
if (_MmCopyMemory == NULL)
{
DbgPrint("%s\n", "System routine MmCopyMemory not found.");
retval++;
}
RtlInitUnicodeString(&fnName, L"RtlLookupFunctionEntry");
_RtlLookupFunctionEntry = MmGetSystemRoutineAddress(&fnName);
if (_RtlLookupFunctionEntry == NULL)
{
DbgPrint("%s\n", "System routine RtlLookupFunctionEntry not found.");
retval++;
}
RtlInitUnicodeString(&fnName, L"ZwTraceControl");
_ZwTraceControl = MmGetSystemRoutineAddress(&fnName);
if (_ZwTraceControl == NULL)
Expand All @@ -38,6 +67,13 @@ int __cdecl ntdll_zw_functions (void)
DbgPrint("%s\n", "System routine ZwQueryVirtualMemory not found.");
retval++;
}
RtlInitUnicodeString(&fnName, L"ZwProtectVirtualMemory");
_ZwProtectVirtualMemory = MmGetSystemRoutineAddress(&fnName);
if (_ZwProtectVirtualMemory == NULL)
{
DbgPrint("%s\n", "System routine ZwProtectVirtualMemory not found.");
retval++;
}
RtlInitUnicodeString(&fnName, L"ZwQuerySystemInformation");
_ZwQuerySystemInformation = MmGetSystemRoutineAddress(&fnName);
if (_ZwQuerySystemInformation == NULL)
Expand All @@ -50,6 +86,42 @@ int __cdecl ntdll_zw_functions (void)
}


NTSTATUS NTAPI ObOpenObjectByPointer (_In_ PVOID obj, _In_ ULONG HandleAttributes, _In_ PACCESS_STATE PassedAccessState, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_TYPE objType, _In_ KPROCESSOR_MODE AccessMode, _Out_ PHANDLE Handle)
{
if (_ObOpenObjectByPointer == NULL)
return STATUS_PROCEDURE_NOT_FOUND;

return _ObOpenObjectByPointer (obj, HandleAttributes, PassedAccessState, DesiredAccess, objType, AccessMode, Handle);
}

NTSTATUS NTAPI WrapperObOpenObjectByPointer (_In_ PVOID obj, _In_ ULONG HandleAttributes, _In_ PACCESS_STATE PassedAccessState, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_TYPE objType, _In_ KPROCESSOR_MODE AccessMode, _Out_ PHANDLE Handle)
{
return _ObOpenObjectByPointer (obj, HandleAttributes, PassedAccessState, DesiredAccess, objType, AccessMode, Handle);
}

NTSTATUS NTAPI MmCopyMemory (_In_ PVOID TargetAddress, _In_ PVOID SourceAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG Flags, _Out_ PSIZE_T NumberOfBytesTransferred)
{
if (_MmCopyMemory == NULL)
return STATUS_PROCEDURE_NOT_FOUND;

return _MmCopyMemory (TargetAddress, SourceAddress, NumberOfBytes, Flags, NumberOfBytesTransferred);
}

NTSTATUS NTAPI WrapperMmCopyMemory (_In_ PVOID TargetAddress, _In_ PVOID SourceAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG Flags, _Out_ PSIZE_T NumberOfBytesTransferred)
{
return _MmCopyMemory (TargetAddress, SourceAddress, NumberOfBytes, Flags, NumberOfBytesTransferred);
}

PVOID NTAPI RtlLookupFunctionEntry (_In_ DWORD64 ControlPc, _Out_ PDWORD64 ImageBase, _Out_ PVOID HistoryTable)
{
return _RtlLookupFunctionEntry (ControlPc, ImageBase, HistoryTable);
}

PVOID NTAPI WrapperRtlLookupFunctionEntry (_In_ DWORD64 ControlPc, _Out_ PDWORD64 ImageBase, _Out_ PVOID HistoryTable)
{
return _RtlLookupFunctionEntry (ControlPc, ImageBase, HistoryTable);
}

NTSTATUS NTAPI ZwTraceControl (_In_ ULONG FunctionCode, PVOID InBuffer, _In_ ULONG InBufferLen, PVOID OutBuffer, _In_ ULONG OutBufferLen, _Out_ PULONG ReturnLength)
{
if (_ZwTraceControl == NULL)
Expand All @@ -58,6 +130,11 @@ NTSTATUS NTAPI ZwTraceControl (_In_ ULONG FunctionCode, PVOID InBuffer, _In_ ULO
return _ZwTraceControl (FunctionCode, InBuffer, InBufferLen, OutBuffer, OutBufferLen, ReturnLength);
}

NTSTATUS NTAPI WrapperZwTraceControl (_In_ ULONG FunctionCode, PVOID InBuffer, _In_ ULONG InBufferLen, PVOID OutBuffer, _In_ ULONG OutBufferLen, _Out_ PULONG ReturnLength)
{
return _ZwTraceControl (FunctionCode, InBuffer, InBufferLen, OutBuffer, OutBufferLen, ReturnLength);
}

NTSTATUS NTAPI ZwTraceEvent (_In_ HANDLE TraceHandle, _In_ ULONG Flags, _In_ ULONG FieldSize, _In_ PVOID Fields)
{
if (_ZwTraceEvent == NULL)
Expand All @@ -66,6 +143,11 @@ NTSTATUS NTAPI ZwTraceEvent (_In_ HANDLE TraceHandle, _In_ ULONG Flags, _In_ ULO
return _ZwTraceEvent (TraceHandle, Flags, FieldSize, Fields);
}

NTSTATUS NTAPI WrapperZwTraceEvent (_In_ HANDLE TraceHandle, _In_ ULONG Flags, _In_ ULONG FieldSize, _In_ PVOID Fields)
{
return _ZwTraceEvent (TraceHandle, Flags, FieldSize, Fields);
}

NTSTATUS NTAPI ZwQueryVirtualMemory (_In_ HANDLE ProcessHandle, _In_ PVOID BaseAddress, _In_ int MemoryInformationClass, _Out_ PVOID MemoryInformation, _In_ SIZE_T MemoryInformationLength, _Out_ PSIZE_T ReturnLength)
{
if (_ZwQueryVirtualMemory == NULL)
Expand All @@ -74,10 +156,33 @@ NTSTATUS NTAPI ZwQueryVirtualMemory (_In_ HANDLE ProcessHandle, _In_ PVOID BaseA
return _ZwQueryVirtualMemory (ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation, MemoryInformationLength, ReturnLength);
}

NTSTATUS NTAPI WrapperZwQueryVirtualMemory (_In_ HANDLE ProcessHandle, _In_ PVOID BaseAddress, _In_ int MemoryInformationClass, _Out_ PVOID MemoryInformation, _In_ SIZE_T MemoryInformationLength, _Out_ PSIZE_T ReturnLength)
{
return _ZwQueryVirtualMemory (ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation, MemoryInformationLength, ReturnLength);
}

NTSTATUS NTAPI ZwProtectVirtualMemory (_In_ HANDLE ProcessHandle, _In_ _Out_ PVOID* BaseAddress, _In_ _Out_ PULONG NumberOfBytesToProtect, _In_ ULONG NewAccessProtection, _Out_ PULONG OldAccessProtection)
{
if (_ZwProtectVirtualMemory == NULL)
return STATUS_PROCEDURE_NOT_FOUND;

return _ZwProtectVirtualMemory (ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection);
}

NTSTATUS NTAPI WrapperZwProtectVirtualMemory (_In_ HANDLE ProcessHandle, _In_ _Out_ PVOID* BaseAddress, _In_ _Out_ PULONG NumberOfBytesToProtect, _In_ ULONG NewAccessProtection, _Out_ PULONG OldAccessProtection)
{
return _ZwProtectVirtualMemory (ProcessHandle, BaseAddress, NumberOfBytesToProtect, NewAccessProtection, OldAccessProtection);
}

NTSTATUS NTAPI ZwQuerySystemInformation (_In_ int SystemInformationClass, _Inout_ PVOID SystemInformation, _In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength)
{
if (_ZwQuerySystemInformation == NULL)
return STATUS_PROCEDURE_NOT_FOUND;

return _ZwQuerySystemInformation (SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
}

NTSTATUS NTAPI WrapperZwQuerySystemInformation (_In_ int SystemInformationClass, _Inout_ PVOID SystemInformation, _In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength)
{
return _ZwQuerySystemInformation (SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
}
4 changes: 4 additions & 0 deletions CRT/ntdll_zw_functions.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
NTSTATUS NTAPI ObOpenObjectByPointer (_In_ PVOID obj, _In_ ULONG HandleAttributes, _In_ PACCESS_STATE PassedAccessState, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_TYPE objType, _In_ KPROCESSOR_MODE AccessMode, _Out_ PHANDLE Handle);
NTSTATUS NTAPI MmCopyMemory (_In_ PVOID TargetAddress, _In_ PVOID SourceAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG Flags, _Out_ PSIZE_T NumberOfBytesTransferred);
NTSYSAPI PVOID NTAPI RtlLookupFunctionEntry (_In_ DWORD64 ControlPc, _Out_ PDWORD64 ImageBase, _Out_ PVOID HistoryTable);
NTSYSCALLAPI NTSTATUS NTAPI ZwTraceControl (_In_ ULONG FunctionCode, PVOID InBuffer, _In_ ULONG InBufferLen, PVOID OutBuffer, _In_ ULONG OutBufferLen, _Out_ PULONG ReturnLength)
NTSYSCALLAPI NTSTATUS NTAPI ZwTraceEvent (_In_ HANDLE TraceHandle, _In_ ULONG Flags, _In_ ULONG FieldSize, _In_ PVOID Fields)
NTSYSCALLAPI NTSTATUS NTAPI ZwQueryVirtualMemory(_In_ HANDLE ProcessHandle, _In_ PVOID BaseAddress, _In_ int MemoryInformationClass, _Out_ PVOID MemoryInformation, _In_ SIZE_T MemoryInformationLength, _Out_ PSIZE_T ReturnLength);
NTSYSCALLAPI NTSTATUS NTAPI ZwProtectVirtualMemory(_In_ HANDLE ProcessHandle, _In_ _Out_ PVOID* BaseAddress, _In_ _Out_ PULONG NumberOfBytesToProtect, _In_ ULONG NewAccessProtection, _Out_ PULONG OldAccessProtection);
NTSYSCALLAPI NTSTATUS NTAPI ZwQuerySystemInformation(_In_ int SystemInformationClass, _Inout_ PVOID SystemInformation, _In_ ULONG SystemInformationLength, _Out_opt_ PULONG ReturnLength);

0 comments on commit 9ae0188

Please sign in to comment.