Skip to content

Instantly share code, notes, and snippets.

@p4yl0ad
Created January 31, 2022 13:27
Show Gist options
  • Save p4yl0ad/8684ddc6dcc513ddaee4f61fbae3737d to your computer and use it in GitHub Desktop.
Save p4yl0ad/8684ddc6dcc513ddaee4f61fbae3737d to your computer and use it in GitHub Desktop.
Snippet which uses LdrLoadDll to force load a DLL and use handle returned to get a pointer to a function.
#include <windows.h>
#pragma comment(lib, "ntdll.lib")
//#pragma comment(lib, "ntdllp.lib")
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
/*
* Author : p4yl0ad
* Date : 31/01/2022
*
* Resources:
* https://github.com/Paolo-Maffei/OpenNT/search?p=1&q=PCREATE_REMOTE_THREAD&type=Code
* Matti [Public|Secret] Club Discord, Very Very wise person
* Lima X [Public|Secret] Club Discord, Very objective and straight to the point
*/
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
_Field_size_bytes_part_(MaximumLength, Length) PWCH Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
typedef struct _STRING
{
USHORT Length;
USHORT MaximumLength;
_Field_size_bytes_part_opt_(MaximumLength, Length) PCHAR Buffer;
} STRING, * PSTRING, ANSI_STRING, * PANSI_STRING, OEM_STRING, * POEM_STRING;
typedef const STRING* PCSTRING;
EXTERN_C NTSYSAPI NTSTATUS NTAPI RtlInitUnicodeString(
PUNICODE_STRING DestinationString, // OUT
PCWSTR SourceString
);
EXTERN_C NTSYSAPI NTSTATUS NTAPI LdrLoadDll(
/*_In_opt_ */ PWSTR DllPath,
/*_In_opt_ */ PULONG DllCharacteristics,
/*_In_ */ PUNICODE_STRING DllName,
/*_Out_ */ PVOID* DllHandle
);
EXTERN_C NTSYSAPI VOID NTAPI
RtlInitString(
_Out_ PSTRING DestinationString,
_In_opt_ PCSTR SourceString
);
EXTERN_C NTSYSAPI NTSTATUS NTAPI LdrGetProcedureAddress(
/*_In_ */ PVOID DllHandle,
/*_In_opt_ */ PANSI_STRING ProcedureName,
/*_In_opt_ */ ULONG ProcedureNumber,
/*_Out_ */ PVOID* ProcedureAddress
);
EXTERN_C NTSYSAPI ULONG NTAPI DbgPrint(
PCSTR Format, // [in]
...
);
void main(void)
{
NTSTATUS Status;
PVOID ModuleHandle;
UNICODE_STRING ModuleNameString_U;
void * VirtualAllocRoutine;
VirtualAllocRoutine = NULL;
/* encode string in order to be used wth LdrLoadDll*/
RtlInitUnicodeString(
&ModuleNameString_U,
L"kernelbase"
);
/* UNDOCUMENTED , UNICODE_NULL = #define UNICODE_NULL ((WCHAR)0) */
Status = LdrLoadDll(
UNICODE_NULL,
NULL,
&ModuleNameString_U,
&ModuleHandle
);
if (NT_SUCCESS(Status))
{
typedef LPVOID(*PVIRTUA_ALLLOC_ROUTINE)(
/* [in, optional] */ LPVOID lpAddress,
/* [in] */ SIZE_T dwSize,
/* [in] */ DWORD flAllocationType,
/* [in] */ DWORD flProtect
);
PVIRTUA_ALLLOC_ROUTINE VirtualAllocRoutine;
STRING ProcedureNameString;
RtlInitString(
&ProcedureNameString,
"VirtualAlloc"
);
Status = LdrGetProcedureAddress(
ModuleHandle,
&ProcedureNameString,
(ULONG)NULL,
(PVOID*)&VirtualAllocRoutine
);
if (NT_SUCCESS(Status))
{
// We have a pointer to the function
DbgPrint("Pointer to kernelbase.dll:VirtualAlloc(); ( 0x%p )", VirtualAllocRoutine);
printf("Pointer to kernelbase.dll:VirtualAlloc(); ( 0x%p )", VirtualAllocRoutine);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment