aboutsummaryrefslogtreecommitdiff
path: root/Exfiltration/mimikatz-1.0/driver/notify_image.c
blob: 6f03fd41aef613b6729acb36a430399f51870fcd (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
#include "notify_image.h"

ULONG * PspLoadImageNotifyRoutineCount			= NULL;
PVOID * PspLoadImageNotifyRoutine				= NULL;

NTSTATUS kListNotifyImages(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining)
{
	NTSTATUS status;
	ULONG i;
	PKIWI_CALLBACK monCallBack;

	*ppszDestEnd = pszDest; *pcbRemaining= cbDest;
	status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"kListNotifyImages\n\n");
	if(NT_SUCCESS(status))
	{
		status = getPspLoadImageNotifyRoutine();
		if(NT_SUCCESS(status))
		{
			for(i = 0; (i < *PspLoadImageNotifyRoutineCount) && NT_SUCCESS(status); i++)
			{
				monCallBack = (PKIWI_CALLBACK) KIWI_mask3bits(PspLoadImageNotifyRoutine[i]);
				if(monCallBack != NULL)
				{
					status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"[%.2u] ", i);
					if(NT_SUCCESS(status))
					{
						status = getModuleFromAddr((ULONG_PTR) monCallBack->callback, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining);
						if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND)
						{
							status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n");
						}
					}
				}
			}
		}
	}
	return status;
}

NTSTATUS getPspLoadImageNotifyRoutine()
{
	NTSTATUS retour = STATUS_NOT_FOUND;
	#ifdef _M_X64
		UCHAR PTRN_WNT5_Image[]	= {0x48, 0x8d, 0x35};
		LONG OFFS_WNT5_Image	= sizeof(PTRN_WNT5_Image);
		UCHAR PTRN_WNT6_Image[]	= {0x48, 0x8d, 0x0d};
		LONG OFFS_WNT6_Image	= sizeof(PTRN_WNT6_Image);

		LONG OFFS_WNT5_Count	= - 0x0c;
		LONG OFFS_WNT6_Count	= sizeof(PVOID) * MAX_NT_PspLoadImageNotifyRoutine;
	#elif defined _M_IX86
		UCHAR PTRN_WNT5_Image[]	= {0x6a, 0x00, 0x53, 0x56};
		UCHAR PTRN_WNO8_Image[]	= {0x6a, 0x00, 0x8b, 0xcb, 0x8b, 0xc6};
		UCHAR PTRN_WIN8_Image[]	= {0x33, 0xff, 0x6a, 0x00, 0x53, 0x8b, 0xc6};
		LONG OFFS_WALL_Image	= -(LONG) sizeof(PVOID);

		LONG OFFS_WNT5_Count	= - 0x18;
		LONG OFFS_WNO8_Count	= sizeof(PVOID) * MAX_NT_PspLoadImageNotifyRoutine;
		LONG OFFS_WIN8_Count	= - 0x20;
	#endif
	
	PUCHAR pointeur = NULL, pattern = NULL, refDebut = (PUCHAR) PsSetLoadImageNotifyRoutine, refFin = refDebut + PAGE_SIZE; SIZE_T taille = 0; LONG offsetTo = 0;
	LONG offsetToCountEx = 0, offsetToCount = 0;
	
	if(PspLoadImageNotifyRoutine && PspLoadImageNotifyRoutineCount)
	{
		retour = STATUS_SUCCESS;
	}
	else
	{
		if(INDEX_OS < INDEX_VISTA)
		{
			pattern			= PTRN_WNT5_Image;
			taille			= sizeof(PTRN_WNT5_Image);
			#ifdef _M_X64
				offsetTo		= OFFS_WNT5_Image;
			#endif
			offsetToCount	= OFFS_WNT5_Count;
		}
		else
		{
			#ifdef _M_X64
				pattern			= PTRN_WNT6_Image;
				taille			= sizeof(PTRN_WNT6_Image);
				offsetTo		= OFFS_WNT6_Image;
				offsetToCount	= OFFS_WNT6_Count;
			#elif defined _M_IX86
				if(INDEX_OS < INDEX_8)
				{
					pattern			= PTRN_WNO8_Image;
					taille			= sizeof(PTRN_WNO8_Image);
					offsetToCount	= OFFS_WNO8_Count;
				}
				else
				{
					pattern			= PTRN_WIN8_Image;
					taille			= sizeof(PTRN_WIN8_Image);
					offsetToCount	= OFFS_WIN8_Count;
				}
			#endif
		}
		#ifdef _M_IX86
			offsetTo		= OFFS_WALL_Image;
		#endif
		
		retour = genericPointerSearch(&pointeur, refDebut, refFin, pattern, taille, offsetTo);
		if(NT_SUCCESS(retour))
		{
			PspLoadImageNotifyRoutine		= (PVOID)	(pointeur);
			PspLoadImageNotifyRoutineCount	= (PULONG)	(pointeur + offsetToCount);

			if(PspLoadImageNotifyRoutine && PspLoadImageNotifyRoutineCount)
				retour = STATUS_SUCCESS;
		}
	}
	return retour;
}