4
4
#include " NT.h"
5
5
#include " Utils.h"
6
6
7
- typedef NTSTATUS (*PFN_ORIGINAL_IO_CONTROL )(
7
+ typedef NTSTATUS (*_IO_CONTROL )(
8
8
_In_ PDEVICE_OBJECT DeviceObject,
9
9
_In_ PIRP Irp
10
10
);
11
11
12
- PFN_ORIGINAL_IO_CONTROL OriginalIOControl = NULL ;
12
+ _IO_CONTROL OriginalIOControl = NULL ;
13
13
14
14
NTSTATUS hk_ControlIO (
15
15
_In_ PDEVICE_OBJECT DeviceObject,
@@ -38,7 +38,7 @@ NTSTATUS hk_ControlIO(
38
38
39
39
DBG (" Dumping Memory! Source: 0x%p Destination: 0x%p Size: %d" , Buffer->Source , Buffer->Destination , Buffer->Length );
40
40
41
- NTSTATUS Status = DumpMemoryToDisk (L" KDMapperDumper" , (PVOID)((UINT64) Buffer->Source - 0x400 ) , Buffer->Length + 0x400 );
41
+ NTSTATUS Status = DumpMemoryToDisk (L" KDMapperDumper" , Buffer->Source , Buffer->Length );
42
42
if (NT_SUCCESS (Status) == false )
43
43
{
44
44
DBG (" Failed to dump memory - 0x%X" , Status);
@@ -59,6 +59,10 @@ NTSTATUS hk_ControlIO(
59
59
//
60
60
// Attempt to dump the original driver with the PE header by attaching to the source process
61
61
// and then going back 0x1000 bytes from the mapped driver.
62
+ //
63
+ // This abuses the fact that when KDMapper sends the IOCTL request, it just adjusts
64
+ // the base address of the data it sends to the driver to skip the PE header.
65
+ // This means we can just go back 0x1000 bytes from the base address to get the PE header.
62
66
//
63
67
PVOID Pool = ExAllocatePool2 (POOL_FLAG_NON_PAGED, Buffer->Length + 0x1000 , POOL_TAG2);
64
68
if (Pool == NULL )
@@ -184,7 +188,8 @@ VOID ImageLoadCallback(
184
188
return ;
185
189
186
190
//
187
- // Copy the first 0x1000 bytes of the image to an allocated pool buffer.
191
+ // Copy the first 0x1000 bytes of the image (the PE header) to a pool buffer.
192
+ // If the image size is less than 0x1000 bytes, we will just copy the entire image.
188
193
//
189
194
PVOID ImageBase = ImageInfo->ImageBase ;
190
195
SIZE_T PoolSize = min (ImageInfo->ImageSize , 0x1000 );
@@ -199,7 +204,8 @@ VOID ImageLoadCallback(
199
204
RtlCopyMemory (ImageBuffer, ImageBase, PoolSize);
200
205
201
206
//
202
- // Check the file header timestamp to see if it matches the timestamp of the KDMapper driver.
207
+ // Check the file header timestamp to see if it matches the timestamp of the
208
+ // vulnerable Intel LAN driver that KDMapper uses.
203
209
//
204
210
PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)ImageBuffer;
205
211
if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
@@ -217,11 +223,15 @@ VOID ImageLoadCallback(
217
223
218
224
DBG (" Found Intel LAN driver at: 0x%p" , ImageBase);
219
225
226
+ //
227
+ // Hook IoCreateDevice() so we can redirect all IOCTL requests to
228
+ // our own handler that will dump the memory.
229
+ //
220
230
NTSTATUS Status = HookIATEntry (ImageBase, " ntoskrnl.exe" , " IoCreateDevice" , hk_IoCreateDevice);
221
231
if (NT_SUCCESS (Status) == false )
222
232
{
223
233
DBG (" Failed to hook IoCreateDevice() in Intel LAN Driver! - 0x%X" , Status);
224
234
}
225
235
226
- return ;
236
+ ExFreePoolWithTag (ImageBuffer, POOL_TAG) ;
227
237
}
0 commit comments