Inject-APC(Ring0)

  1 #include "stdafx.h"
  2 #include <iostream>
  3 #include <Windows.h>
  4 #include <WinIoCtl.h>
  5 using namespace std;
  6 
  7 #define CTL_KEINJECTAPC \
  8     CTL_CODE(FILE_DEVICE_UNKNOWN, 0x830, METHOD_BUFFERED, FILE_ANY_ACCESS)
  9 
 10 typedef struct _INJECT_INFO
 11 {
 12     ULONG ProcessId;
 13     wchar_t DllName[1024];
 14 }INJECT_INFO, *PINJECT_INFO;
 15 
 16 int _tmain(int argc, _TCHAR* argv[])
 17 {
 18     HANDLE hFile;
 19     INJECT_INFO InjectInfo;
 20     hFile = CreateFile(L"\\\\.\\DriverLink",
 21         GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
 22         NULL, OPEN_EXISTING, 0, NULL);
 23 
 24     if (hFile == INVALID_HANDLE_VALUE)
 25     {
 26         printf("\nError: Unable to connect to the driver (%d)\n", GetLastError());
 27         return -1;
 28     }
 29     memset(&InjectInfo, 0, sizeof(INJECT_INFO));
 30     scanf("%d", &(InjectInfo.ProcessId));
 31     wscanf(L"%s", InjectInfo.DllName);
 32     DWORD dwReturnSize = 0;
 33     DWORD dwRet = 0;
 34     dwRet = DeviceIoControl(hFile, CTL_KEINJECTAPC,   //
 35         &InjectInfo,
 36         sizeof(INJECT_INFO),
 37         NULL,
 38         NULL,
 39         &dwReturnSize,
 40         NULL);
 41 
 42     CloseHandle(hFile);
 43     return 0;
 44 }
 45 
 46 #include <ntifs.h>
 47 #include <devioctl.h>
 48 #include <ntimage.h>
 49 
 50 #endif    
 51 
 52 #define DEVICE_NAME       L"\\Device\\DriverDevice"
 53 #define LINK_NAME       L"\\DosDevices\\DriverLink"
 54 
 55 #define CTL_KEINJECTAPC \
 56     CTL_CODE(FILE_DEVICE_UNKNOWN, 0x830, METHOD_BUFFERED, FILE_ANY_ACCESS)
 57 
 58 typedef struct _SYSTEM_THREAD_INFORMATION
 59 {
 60     LARGE_INTEGER KernelTime;
 61     LARGE_INTEGER UserTime;
 62     LARGE_INTEGER CreateTime;
 63     ULONG WaitTime;
 64     PVOID StartAddress;
 65     CLIENT_ID ClientId;
 66     KPRIORITY Priority;
 67     LONG BasePriority;
 68     ULONG ContextSwitches;
 69     ULONG ThreadState;
 70     KWAIT_REASON WaitReason;
 71 }SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
 72 
 73 typedef struct _SYSTEM_PROCESS_INFO
 74 {
 75     ULONG NextEntryOffset;
 76     ULONG NumberOfThreads;
 77     LARGE_INTEGER WorkingSetPrivateSize;
 78     ULONG HardFaultCount;
 79     ULONG NumberOfThreadsHighWatermark;
 80     ULONGLONG CycleTime;
 81     LARGE_INTEGER CreateTime;
 82     LARGE_INTEGER UserTime;
 83     LARGE_INTEGER KernelTime;
 84     UNICODE_STRING ImageName;
 85     KPRIORITY BasePriority;
 86     HANDLE UniqueProcessId;
 87     HANDLE InheritedFromUniqueProcessId;
 88     ULONG HandleCount;
 89     ULONG SessionId;
 90     ULONG_PTR UniqueProcessKey;
 91     SIZE_T PeakVirtualSize;
 92     SIZE_T VirtualSize;
 93     ULONG PageFaultCount;
 94     SIZE_T PeakWorkingSetSize;
 95     SIZE_T WorkingSetSize;
 96     SIZE_T QuotaPeakPagedPoolUsage;
 97     SIZE_T QuotaPagedPoolUsage;
 98     SIZE_T QuotaPeakNonPagedPoolUsage;
 99     SIZE_T QuotaNonPagedPoolUsage;
100     SIZE_T PagefileUsage;
101     SIZE_T PeakPagefileUsage;
102     SIZE_T PrivatePageCount;
103     LARGE_INTEGER ReadOperationCount;
104     LARGE_INTEGER WriteOperationCount;
105     LARGE_INTEGER OtherOperationCount;
106     LARGE_INTEGER ReadTransferCount;
107     LARGE_INTEGER WriteTransferCount;
108     LARGE_INTEGER OtherTransferCount;
109     SYSTEM_THREAD_INFORMATION Threads[1];
110 }SYSTEM_PROCESS_INFO, *PSYSTEM_PROCESS_INFO;
111 
112 typedef struct _LDR_DATA_TABLE_ENTRY
113 {
114     LIST_ENTRY InLoadOrderLinks;
115     LIST_ENTRY InMemoryOrderLinks;
116     LIST_ENTRY InInitializationOrderLinks;
117     PVOID DllBase;
118     PVOID EntryPoint;
119     ULONG SizeOfImage;
120     UNICODE_STRING FullDllName;
121     UNICODE_STRING BaseDllName;
122     ULONG Flags;
123     USHORT LoadCount;
124     USHORT TlsIndex;
125 
126     union
127     {
128         LIST_ENTRY HashLinks;
129         struct
130         {
131             PVOID SectionPointer;
132             ULONG CheckSum;
133         };
134     };
135 
136     union
137     {
138         ULONG TimeDateStamp;
139         PVOID LoadedImports;
140     };
141 
142     struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
143     PVOID PatchInformation;
144     LIST_ENTRY ForwarderLinks;
145     LIST_ENTRY ServiceTagLinks;
146     LIST_ENTRY StaticLinks;
147 }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
148 
149 typedef struct _INJECT_INFO
150 {
151     ULONG ProcessId;
152     wchar_t DllName[1024];
153 }INJECT_INFO, *PINJECT_INFO;
154 
155 typedef NTSTATUS(*PLDR_LOAD_DLL)(PWSTR, PULONG, PUNICODE_STRING, PVOID*);
156 
157 typedef struct _KINJECT
158 {
159     UNICODE_STRING DllName;
160     wchar_t Buffer[1024];
161     PLDR_LOAD_DLL LdrLoadDll;
162     PVOID DllBase;
163     ULONG Executed;
164 }KINJECT, *PKINJECT;
165 
166 typedef enum _KAPC_ENVIRONMENT
167 {
168     OriginalApcEnvironment,
169     AttachedApcEnvironment,
170     CurrentApcEnvironment,
171     InsertApcEnvironment
172 }KAPC_ENVIRONMENT, *PKAPC_ENVIRONMENT;
173 
174 typedef VOID(NTAPI *PKNORMAL_ROUTINE)(
175     PVOID NormalContext,
176     PVOID SystemArgument1,
177     PVOID SystemArgument2
178     );
179 
180 typedef VOID KKERNEL_ROUTINE(
181     PRKAPC Apc,
182     PKNORMAL_ROUTINE *NormalRoutine,
183     PVOID *NormalContext,
184     PVOID *SystemArgument1,
185     PVOID *SystemArgument2
186     );
187 
188 typedef KKERNEL_ROUTINE(NTAPI *PKKERNEL_ROUTINE);
189 
190 typedef VOID(NTAPI *PKRUNDOWN_ROUTINE)(
191     PRKAPC Apc
192     );
193 
194 void KeInitializeApc(
195     PRKAPC Apc,
196     PRKTHREAD Thread,
197     KAPC_ENVIRONMENT Environment,
198     PKKERNEL_ROUTINE KernelRoutine,
199     PKRUNDOWN_ROUTINE RundownRoutine,
200     PKNORMAL_ROUTINE NormalRoutine,
201     KPROCESSOR_MODE ProcessorMode,
202     PVOID NormalContext
203     );
204 
205 BOOLEAN KeInsertQueueApc(
206     PRKAPC Apc,
207     PVOID SystemArgument1,
208     PVOID SystemArgument2,
209     KPRIORITY Increment
210     );
211 
212 
213 NTSTATUS ZwQuerySystemInformation(ULONG InfoClass, PVOID Buffer, ULONG Length, PULONG ReturnLength);
214 LPSTR PsGetProcessImageFileName(PEPROCESS Process);
215 
216 NTSTATUS DefaultPassThrough(PDEVICE_OBJECT  DeviceObject, PIRP Irp);
217 void UnloadDriver(PDRIVER_OBJECT DriverObject);
218 NTSTATUS DriverDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp);
219 
220 ULONG ApcStateOffset;
221 PLDR_LOAD_DLL LdrLoadDll;
222 
223 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING pRegistryPath)
224 {
225     NTSTATUS Status;
226     PDEVICE_OBJECT DeviceObject;
227     PEPROCESS Process;
228     PETHREAD Thread;
229     PKAPC_STATE ApcState;
230     PVOID KdVersionBlock, NtdllBase;
231     PULONG ptr, Functions, Names;
232     PUSHORT Ordinals;
233     PLDR_DATA_TABLE_ENTRY MmLoadedUserImageList, ModuleEntry;
234     ULONG i;
235     PIMAGE_DOS_HEADER pIDH;
236     PIMAGE_NT_HEADERS pINH;
237     PIMAGE_EXPORT_DIRECTORY pIED;
238     UNICODE_STRING   uniDeviceName;
239     UNICODE_STRING   uniLinkName;
240     RtlInitUnicodeString(&uniDeviceName, DEVICE_NAME);
241     RtlInitUnicodeString(&uniLinkName, LINK_NAME);
242     for (i = 0; i<IRP_MJ_MAXIMUM_FUNCTION; i++)
243     {
244         DriverObject->MajorFunction[i] = DefaultPassThrough;
245     }
246     DriverObject->DriverUnload = UnloadDriver;
247     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDispatch;
248     //创建设备对象
249     Status = IoCreateDevice(DriverObject, 0, &uniDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
250     if (!NT_SUCCESS(Status))
251     {
252         return Status;
253     }
254     Status = IoCreateSymbolicLink(&uniLinkName, &uniDeviceName);
255     if (!NT_SUCCESS(Status))
256     {
257         IoDeleteDevice(DeviceObject);
258         return Status;
259     }
260 
261     //使当前线程运行在第一个处理器上
262     KeSetSystemAffinityThread(1);
263     KdVersionBlock = (PVOID)__readfsdword(0x34); //得到KdVersionBlock
264     KeRevertToUserAffinityThread();//恢复线程运行的处理器
265     MmLoadedUserImageList = *(PLDR_DATA_TABLE_ENTRY*)((PUCHAR)KdVersionBlock + 0x228); // Get the MmLoadUserImageList
266 
267     /*
268     kd> !pcr
269     KPCR for Processor 0 at 83f3ec00:
270 
271     kd> dt _kpcr 83f3ec00
272     +0x034 KdVersionBlock   : 0x83f3dc00 Void
273 
274     kd> dd 0x83f3dc00+0x228
275     83f3de28  83f5de38 00000000 83e5dfa8 00000000
276     83f3de38  00000000 00000000 83f7d8c0 00000000
277     83f3de48  83f7d560 00000000 83f5d84c 00000000
278 
279     kd> dd 83f5de38
280     83f5de38  8706b1e8 877cb660 00000000 00000000
281     83f5de48  00000000 00000000 00040107 00000000
282     83f5de58  865d0690 865d0690 c0403188 0007ff7e
283 
284     kd> dt _LDR_DATA_TABLE_ENTRY 8706b1e8
285     nt!_LDR_DATA_TABLE_ENTRY
286     +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x8713b4e0 - 0x83f5de38 ]
287     +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
288     +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
289     +0x018 DllBase          : 0x77ce0000 Void
290     +0x01c EntryPoint       : (null)
291     +0x020 SizeOfImage      : 0x13c000
292     +0x024 FullDllName      : _UNICODE_STRING "\Windows\System32\ntdll.dll"
293     +0x02c BaseDllName      : _UNICODE_STRING ""
294     +0x034 Flags            : 0
295     +0x038 LoadCount        : 1
296     +0x03a TlsIndex         : 0
297     +0x03c HashLinks        : _LIST_ENTRY [ 0x0 - 0x1490d9 ]
298     +0x03c SectionPointer   : (null)
299     +0x040 CheckSum         : 0x1490d9
300     +0x044 TimeDateStamp    : 0
301     +0x044 LoadedImports    : (null)
302     +0x048 EntryPointActivationContext : (null)
303     +0x04c PatchInformation : (null)
304     +0x050 ForwarderLinks   : _LIST_ENTRY [ 0x0 - 0x0 ]
305     +0x058 ServiceTagLinks  : _LIST_ENTRY [ 0x0 - 0x57005c ]
306     +0x060 StaticLinks      : _LIST_ENTRY [ 0x6e0069 - 0x6f0064 ]
307     +0x068 ContextInformation : 0x00730077 Void
308     +0x06c OriginalBase     : 0x53005c
309     +0x070 LoadTime         : _LARGE_INTEGER 0x650074`00730079
310     */
311     DbgPrint("KdVersionBlock address: %#x", KdVersionBlock);
312     DbgPrint("MmLoadedUserImageList address: %#x", MmLoadedUserImageList);
313 
314     ModuleEntry = (PLDR_DATA_TABLE_ENTRY)MmLoadedUserImageList->InLoadOrderLinks.Flink; //第一模块
315     NtdllBase = ModuleEntry->DllBase; //ntdll基地址
316 
317     DbgPrint("ntdll base address: %#x", NtdllBase);
318 
319     pIDH = (PIMAGE_DOS_HEADER)NtdllBase;
320     pINH = (PIMAGE_NT_HEADERS)((PUCHAR)NtdllBase + pIDH->e_lfanew);
321     pIED = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)NtdllBase + pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
322 
323     Functions = (PULONG)((PUCHAR)NtdllBase + pIED->AddressOfFunctions);
324     Names = (PULONG)((PUCHAR)NtdllBase + pIED->AddressOfNames);
325 
326     Ordinals = (PUSHORT)((PUCHAR)NtdllBase + pIED->AddressOfNameOrdinals);
327 
328     //搜索LdrLoadDll
329     for (i = 0; i<pIED->NumberOfNames; i++)
330     {
331         if (!strcmp((char*)NtdllBase + Names[i], "LdrLoadDll"))
332         {
333             LdrLoadDll = (PLDR_LOAD_DLL)((PUCHAR)NtdllBase + Functions[Ordinals[i]]);
334             break;
335         }
336     }
337 
338     DbgPrint("LdrLoadDll address: %#x", LdrLoadDll);
339     Process = PsGetCurrentProcess();
340     Thread = PsGetCurrentThread();
341     ptr = (PULONG)Thread;
342     //确定ApcState在EThread中的偏移
343     for (i = 0; i<512; i++)
344     {
345         if (ptr[i] == (ULONG)Process)
346         {
347             ApcState = CONTAINING_RECORD(&ptr[i], KAPC_STATE, Process);
348             ApcStateOffset = (ULONG)ApcState - (ULONG)Thread;
349             break;
350         }
351     }
352     DbgPrint("ApcState offset: %#x", ApcStateOffset);
353     DbgPrint("DLL injection driver loaded.");
354     return STATUS_SUCCESS;
355 }
356 
357 NTSTATUS DefaultPassThrough(PDEVICE_OBJECT  DeviceObject, PIRP Irp)
358 {
359     Irp->IoStatus.Information = 0;
360     Irp->IoStatus.Status = STATUS_SUCCESS;
361     IoCompleteRequest(Irp, IO_NO_INCREMENT);
362     return STATUS_SUCCESS;
363 }
364 
365 void UnloadDriver(PDRIVER_OBJECT DriverObject)
366 {
367     UNICODE_STRING  uniLinkName;
368     PDEVICE_OBJECT  CurrentDeviceObject;
369     PDEVICE_OBJECT  NextDeviceObject;
370     RtlInitUnicodeString(&uniLinkName, LINK_NAME);
371     IoDeleteSymbolicLink(&uniLinkName);
372     if (DriverObject->DeviceObject != NULL)
373     {
374         CurrentDeviceObject = DriverObject->DeviceObject;
375         while (CurrentDeviceObject != NULL)
376         {
377             NextDeviceObject = CurrentDeviceObject->NextDevice;
378             IoDeleteDevice(CurrentDeviceObject);
379             CurrentDeviceObject = NextDeviceObject;
380         }
381     }
382     DbgPrint("UnloadDriver\r\n");
383 }
384 
385 void NTAPI InjectDllApc(PVOID NormalContext, PVOID SystemArgument1, PVOID SystemArgument2)
386 {
387     PKINJECT inject = (PKINJECT)NormalContext;
388     inject->LdrLoadDll(NULL, NULL, &inject->DllName, &inject->DllBase);
389     inject->Executed = TRUE;
390 }
391 
392 void NTAPI KernelRoutine(PKAPC apc, PKNORMAL_ROUTINE* NormalRoutine, PVOID* NormalContext, \
393     PVOID* SystemArgument1, PVOID* SystemArgument2)
394 {
395     ExFreePool(apc);
396 }
397 
398 BOOLEAN InjectDll(PINJECT_INFO InjectInfo)
399 {
400     PEPROCESS Process;
401     PETHREAD Thread;
402     PKINJECT mem;
403     ULONG size;
404     PKAPC_STATE ApcState;
405     PKAPC apc;
406     PVOID buffer;
407     PSYSTEM_PROCESS_INFO pSpi;
408     LARGE_INTEGER delay;
409     buffer = ExAllocatePool(NonPagedPool, 1024 * 1024);
410     if (!buffer)
411     {
412         DbgPrint("Error: Unable to allocate memory for the process thread list.");
413         return FALSE;
414     }
415 
416     //5    SystemProcessInformation,
417     if (!NT_SUCCESS(ZwQuerySystemInformation(5, buffer, 1024 * 1024, NULL)))
418     {
419         DbgPrint("Error: Unable to query process thread list.");
420         ExFreePool(buffer);
421         return FALSE;
422     }
423 
424     pSpi = (PSYSTEM_PROCESS_INFO)buffer;
425 
426     //找到目标进程
427     while (pSpi->NextEntryOffset)
428     {
429         if (pSpi->UniqueProcessId == InjectInfo->ProcessId)
430         {
431             DbgPrint("Target thread found. TID: %d", pSpi->Threads[0].ClientId.UniqueThread);
432             break;
433         }
434         pSpi = (PSYSTEM_PROCESS_INFO)((PUCHAR)pSpi + pSpi->NextEntryOffset);
435     }
436 
437     // 引用目标进程EProcess,
438     if (!NT_SUCCESS(PsLookupProcessByProcessId(InjectInfo->ProcessId, &Process)))
439     {
440         DbgPrint("Error: Unable to reference the target process.");
441         ExFreePool(buffer);
442         return FALSE;
443     }
444 
445     DbgPrint("Process name: %s", PsGetProcessImageFileName(Process));
446     DbgPrint("EPROCESS address: %#x", Process);
447 
448     //目标进程主线程
449     if (!NT_SUCCESS(PsLookupThreadByThreadId(pSpi->Threads[0].ClientId.UniqueThread, &Thread)))
450     {
451         DbgPrint("Error: Unable to reference the target thread.");
452         ObDereferenceObject(Process);
453         ExFreePool(buffer);
454         return FALSE;
455     }
456 
457     DbgPrint("ETHREAD address: %#x", Thread);
458 
459     ExFreePool(buffer);
460     //切入到目标进程
461     KeAttachProcess(Process);
462 
463     mem = NULL;
464     size = 4096;
465 
466     //在目标进程申请内存
467     if (!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&mem, 0, &size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
468     {
469         DbgPrint("Error: Unable to allocate memory in the target process.");
470         KeDetachProcess();
471         ObDereferenceObject(Process);
472         ObDereferenceObject(Thread);
473         return FALSE;
474     }
475 
476     DbgPrint("Memory allocated at %#x", mem);
477     mem->LdrLoadDll = LdrLoadDll;
478     wcscpy(mem->Buffer, InjectInfo->DllName);
479     RtlInitUnicodeString(&mem->DllName, mem->Buffer);
480     ApcState = (PKAPC_STATE)((PUCHAR)Thread + ApcStateOffset);
481     ApcState->UserApcPending = TRUE;
482     memcpy((PKINJECT)(mem + 1), InjectDllApc, (ULONG)KernelRoutine - (ULONG)InjectDllApc);
483     DbgPrint("APC code address: %#x", (PKINJECT)(mem + 1));
484 
485     //申请apc对象
486     apc = (PKAPC)ExAllocatePool(NonPagedPool, sizeof(KAPC));
487 
488     if (!apc)
489     {
490         DbgPrint("Error: Unable to allocate the APC object.");
491         size = 0;
492         ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&mem, &size, MEM_RELEASE);
493         KeDetachProcess();
494         ObDereferenceObject(Process);
495         ObDereferenceObject(Thread);
496         return FALSE;
497     }
498 
499     KeInitializeApc(apc,
500         Thread,    //目标进程主线程
501         OriginalApcEnvironment,   //目标apcz状态
502         KernelRoutine,  //内核apc总入口
503         NULL,       //Rundown Rounine=NULL
504         (PKNORMAL_ROUTINE)((PKINJECT)mem + 1),   //用户空间的总apc
505         UserMode,   //插入到用户apc队列
506         mem); // 自己的apc队列
507 
508     DbgPrint("Inserting APC to target thread");
509 
510     // 插入apc队列
511     if (!KeInsertQueueApc(apc, NULL, NULL, IO_NO_INCREMENT))
512     {
513         DbgPrint("Error: Unable to insert APC to target thread.");
514         size = 0;
515         ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&mem, &size, MEM_RELEASE);
516         KeDetachProcess();
517         ObDereferenceObject(Process);
518         ObDereferenceObject(Thread);
519         ExFreePool(apc);
520         return FALSE;
521     }
522 
523     delay.QuadPart = -100 * 10000;
524     while (!mem->Executed)
525     {
526         KeDelayExecutionThread(KernelMode, FALSE, &delay);  //等待apc执行 
527     }
528     if (!mem->DllBase)
529     {
530         DbgPrint("Error: Unable to inject DLL into target process.");
531         size = 0;
532         ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&mem, &size, MEM_RELEASE);
533         KeDetachProcess();
534         ObDereferenceObject(Process);
535         ObDereferenceObject(Thread);
536         return FALSE;
537     }
538 
539     DbgPrint("DLL injected at %#x", mem->DllBase);
540     size = 0;
541     ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID*)&mem, &size, MEM_RELEASE);
542     ObDereferenceObject(Process);
543     ObDereferenceObject(Thread);
544     return TRUE;
545 }
546 
547 NTSTATUS DriverDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
548 {
549     PIO_STACK_LOCATION io;
550     PINJECT_INFO InjectInfo;
551     NTSTATUS  Status = STATUS_SUCCESS;
552     PIO_STACK_LOCATION   IrpSp;
553     PVOID     InputBuffer = NULL;
554     PVOID     OutputBuffer = NULL;
555     ULONG_PTR InputSize = 0;
556     ULONG_PTR OutputSize = 0;
557     ULONG_PTR IoControlCode = 0;
558 
559     IrpSp = IoGetCurrentIrpStackLocation(Irp);
560     InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer;
561     InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
562     OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
563     IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
564 
565     switch (IoControlCode)
566     {
567     case CTL_KEINJECTAPC:
568 
569         InjectInfo = (PINJECT_INFO)InputBuffer;
570 
571         if (!InjectInfo)
572         {
573             Status = STATUS_INSUFFICIENT_RESOURCES;
574             break;
575         }
576 
577         if (!InjectDll(InjectInfo))
578         {
579             Status = STATUS_UNSUCCESSFUL;
580             break;
581         }
582         Status = STATUS_SUCCESS;
583         Irp->IoStatus.Information = 0;
584         break;
585     default:
586         Status = STATUS_INVALID_DEVICE_REQUEST;
587         break;
588     }
589     Irp->IoStatus.Status = Status;
590     IoCompleteRequest(Irp, IO_NO_INCREMENT);
591     return Status;
592 }

 

posted @ 2017-03-14 18:52  SenberHu  阅读(893)  评论(0编辑  收藏  举报