-
Notifications
You must be signed in to change notification settings - Fork 69
Expand file tree
/
Copy pathClearVeh.c
More file actions
172 lines (139 loc) · 4.44 KB
/
Copy pathClearVeh.c
File metadata and controls
172 lines (139 loc) · 4.44 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/****************************************************************************************
* ClearVeh.c by @rad9800
* Credit goes to:
* - @peterwintrsmith/@modexpblog (mdsec)
*
* 1. Find the LdrpVectorHandlerList by registering a dummy VEH and walking the doubly
* linked list until we find a pointer in the NTDLL .data section
* 2. We use this as our head of our DLL and save the current VEH (so we can later
* restore them)
* 3. RemoveVectoredExceptionHandler(pointer)
* 4. Do whatever - trigger those patch guards ?? (you may want to add your own VEH)
* 5. Restore the saved exception handlers (stored in an array) with
* AddVectoredExceptionHandler(0, DecodePointer(array[].VectoredHandler)
* 6. Profit??
*
****************************************************************************************/
#include <Windows.h>
#include <winternl.h>
#include <stdio.h> // printf
typedef struct _VECTXCPT_CALLOUT_ENTRY {
LIST_ENTRY Links;
PVOID reserved[2];
PVECTORED_EXCEPTION_HANDLER VectoredHandler;
} VECTXCPT_CALLOUT_ENTRY, * PVECTXCPT_CALLOUT_ENTRY;
LONG WINAPI dummyExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
return 0;
}
BOOL getNtdllSectionVa(PCSTR sectionName, PVOID* sectionVa, DWORD* sectionSz)
{
const LIST_ENTRY* head =
&NtCurrentTeb()->ProcessEnvironmentBlock->Ldr->InMemoryOrderModuleList;
LIST_ENTRY* next = head->Flink;
while (next != head)
{
LDR_DATA_TABLE_ENTRY* entry =
CONTAINING_RECORD(next, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
const UNICODE_STRING* basename = (UNICODE_STRING*)((BYTE*)&entry->FullDllName
+ sizeof(UNICODE_STRING));
if (_wcsicmp(basename->Buffer, L"ntdll.dll") == 0)
{
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((ULONG_PTR)entry->DllBase
+ ((PIMAGE_DOS_HEADER)entry->DllBase)->e_lfanew);
for (int j = 0; j < nt->FileHeader.NumberOfSections; j++) {
const PIMAGE_SECTION_HEADER section =
(PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(nt) +
(DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * j);
if (_stricmp(section->Name, sectionName) == 0) {
*sectionVa = (PVOID)((ULONG_PTR)entry->DllBase
+ section->VirtualAddress);
*sectionSz = section->Misc.VirtualSize;
return TRUE;
}
}
}
next = next->Flink;
}
return FALSE;
}
PVOID findLdrpVectorHandlerList()
{
BOOL found = FALSE;
//
// Register a fake handler
//
PVOID dummyHandler = AddVectoredExceptionHandler(0, &dummyExceptionHandler);
if (dummyHandler == NULL)
return NULL;
PLIST_ENTRY next = ((PLIST_ENTRY)dummyHandler)->Flink;
PVOID sectionVa;
DWORD sectionSz;
//
// LdrpVectorHandlerList will be found in the .data section of NTDLL.dll
//
if (getNtdllSectionVa(".data", §ionVa, §ionSz))
{
while ((PVOID)next != dummyHandler)
{
if ((PVOID)next >= sectionVa &&
(PVOID)next <= (PVOID)((ULONG_PTR)sectionVa + sectionSz))
break;
if ((PVOID)next >= sectionVa &&
(PVOID)next <= (PVOID*)sectionVa + sectionSz)
{
found = TRUE;
break;
}
next = next->Flink;
}
}
//
// Cleanup after ourselves..
//
RemoveVectoredExceptionHandler(dummyHandler);
return found ? next : NULL;
}
int main()
{
PVECTXCPT_CALLOUT_ENTRY vehHandles[64];
PLIST_ENTRY next;
PVOID LdrpVectorHandlerList;
unsigned vehCounter = 0;
LdrpVectorHandlerList = findLdrpVectorHandlerList();
next = ((PLIST_ENTRY)LdrpVectorHandlerList)->Flink;
printf("LdrpVectorHandlerList:\t0x%p\n", LdrpVectorHandlerList);
for (; next != LdrpVectorHandlerList && vehCounter < 64;
vehCounter++, next = next->Flink)
{
printf("Registered Handler:\t0x%p -> ", next);
vehHandles[vehCounter] = (PVECTXCPT_CALLOUT_ENTRY)next;
printf("0x%p\n", DecodePointer(vehHandles[vehCounter]->VectoredHandler));
}
for (unsigned i = 0; i < vehCounter; i++)
{
printf("Removing VEH[%d]:\t0x%p -> ", i, vehHandles[i]);
printf("0x%p\n", DecodePointer(vehHandles[i]->VectoredHandler));
RemoveVectoredExceptionHandler(vehHandles[i]);
}
//
// Re-register the saved exception handlers
//
for (unsigned i = 0; i < vehCounter; i++)
{
printf("Restoring VEH[%d]:\t0x%p\n", i,
DecodePointer(vehHandles[i]->VectoredHandler));
AddVectoredExceptionHandler(0,
DecodePointer(vehHandles[i]->VectoredHandler));
}
//
// Observe our re-registered handlers
//
for (next = ((PLIST_ENTRY)LdrpVectorHandlerList)->Flink;
next != LdrpVectorHandlerList; next = next->Flink)
{
printf("Checking Handler:\t0x%p\n",
DecodePointer(((PVECTXCPT_CALLOUT_ENTRY)next)->VectoredHandler));
}
return 0;
}