I am trying to implement a ring0 dll injector driver and implement by APC injection. the code work perfectly on win XP. by on win7, it keeps crashing the target process.
here is the code:
NTSTATUS InjectDll( IN ULONG ulProcessId, HANDLE hEvent, IN TCHAR * pszDllPath ){ NTSTATUS ntStatus; HANDLE hProcess = NULL; OBJECT_ATTRIBUTES ObjectAttributes; CLIENT_ID ClientId; PKEVENT pevtWait; PKPROCESS pPcb = NULL; PVOID pArg = NULL; ULONG ulSize = 0; KAPC_STATE ApcState; PKAPC pApc; PVOID pTcb; PVOID pfnLoadLibrary; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); LARGE_INTEGER nTimeout; nTimeout.QuadPart = (LONGLONG) -300000000; do { InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL) ClientId.UniqueProcess = (HANDLE)ulProcessId; ClientId.UniqueThread = 0; ntStatus = ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS,&ObjectAttributes,&ClientId ); if ( NT_ERROR(ntStatus) ) { DbgPrint("Open process %d failed - error 0x%X\r\n", ulProcessId, ntStatus); break; } ulSize = MAX_FILENAME_LEN * sizeof(WCHAR); ntStatus = ZwAllocateVirtualMemory( hProcess,&pArg, 0,&ulSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); if ( NT_ERROR(ntStatus) ) { DbgPrint("ZwAllocateVirtualMemory failed - error 0x%X\r\n", ntStatus); // thus, make it leak in target process space! break; } ntStatus = ObReferenceObjectByHandle( hProcess, PROCESS_ALL_ACCESS, 0,//should be PsProcessType, PreviousMode, (PVOID*)&pPcb, NULL); if ( NT_ERROR(ntStatus) ) { DbgPrint("ObReferenceObjectByHandle 0x%X failed - error 0x%X\r\n", hProcess, ntStatus); break; } //enter target process space KeStackAttachProcess(pPcb,&ApcState); pfnLoadLibrary = GetLoadLibraryAddress(pPcb); if (!pfnLoadLibrary) { DbgPrint("Failed to get address of LoadLibrary\r\n"); // leave target process space KeUnstackDetachProcess(&ApcState); break; } else { DbgPrint("Get address of LoadLibrary : 0x%X\r\n", pfnLoadLibrary); } RtlCopyMemory( pArg, pszDllPath, MAX_FILENAME_LEN * sizeof(TCHAR)); // leave target process space KeUnstackDetachProcess(&ApcState); // get target thread pTcb = GetThreadByProcess(pPcb); if (!pTcb) { DbgPrint("Get thread failed!\r\n"); ntStatus = STATUS_UNSUCCESSFUL; break; } // start inject pApc = (PKAPC)ExAllocatePoolWithTag(NonPagedPool,sizeof(KAPC),POOL_TAG); if (!pApc) { DbgPrint("Failed to allocate memory for the APC structure\r\n"); ntStatus = STATUS_INSUFFICIENT_RESOURCES; break; } KeInitializeApc( pApc, (PETHREAD)pTcb, OriginalApcEnvironment,&ApcKernelRoutine, NULL, (PKNORMAL_ROUTINE)pfnLoadLibrary, UserMode, pArg); if (!KeInsertQueueApc(pApc,NULL,NULL,0)) { DbgPrint("Failed to insert APC\r\n"); ntStatus = STATUS_UNSUCCESSFUL; ExFreePool(pApc); break; } } while (0); if ( pPcb ) { ObDereferenceObject(pPcb); } if ( hProcess) { ZwClose(hProcess); } DbgPrint("InjectDll end - status = 0x%X\r\n", ntStatus); return ntStatus;}
injectDll is called by DeviceIoControl serivce routine.
DRIVER_DISPATCH InjectorDeviceControl;NTSTATUS NTAPI InjectorDeviceControl( IN PDEVICE_OBJECT pDeviceObject, PIRP pIrp){ PIO_STACK_LOCATION pStack; PINJECT_DLL_PARAM pParam; NTSTATUS ntStatus; DbgPrint("call InjectorDeviceControl...\r\n"); /* Get the stack location and parameters */ pStack = IoGetCurrentIrpStackLocation(pIrp); pParam = (PINJECT_DLL_PARAM)pIrp->AssociatedIrp.SystemBuffer; if (pStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_INJECTDLL) { /* Unsupported command */ ntStatus = STATUS_NOT_IMPLEMENTED; } else { /* Validate the input buffer length */ if (pStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(INJECT_DLL_PARAM)) { /* Invalid buffer */ ntStatus = STATUS_INVALID_PARAMETER; } else { /* Inject dll */ ntStatus = InjectDll(pParam->ulProcessId, pParam->hEvent, pParam->DllName); } } IoCompleteRequest(pIrp, IO_NO_INCREMENT); return ntStatus;}
here is the crash stacktrace of target process.
FAULTING_IP: ntdll!RtlActivateActivationContextUnsafeFast+9c7770f59a 8933 mov dword ptr [ebx],esiEXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff)ExceptionAddress: 7770f59a (ntdll!RtlActivateActivationContextUnsafeFast+0x0000009c) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000NumberParameters: 2 Parameter[0]: 00000001 Parameter[1]: 00000000Attempt to write to address 00000000DEFAULT_BUCKET_ID: NULL_POINTER_WRITEPROCESS_NAME: QQProtect.exeERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%08lxEXCEPTION_CODE: (NTSTATUS) 0xc0000005 - 0x%08lxEXCEPTION_PARAMETER1: 00000001EXCEPTION_PARAMETER2: 00000000WRITE_ADDRESS: 00000000 FOLLOWUP_IP: ntdll!RtlActivateActivationContextUnsafeFast+9c7770f59a 8933 mov dword ptr [ebx],esiNTGLOBALFLAG: 0FAULTING_THREAD: 00000300PRIMARY_PROBLEM_CLASS: NULL_POINTER_WRITEBUGCHECK_STR: APPLICATION_FAULT_NULL_POINTER_WRITELAST_CONTROL_TRANSFER: from 77740baa to 7770f59aSTACK_TEXT: 021df8a0 77740baa 75655a2c 00000000 02790000 ntdll!RtlActivateActivationContextUnsafeFast+0x9c021df91c 77740461 002b5cd0 021dfab8 756559bc ntdll!LdrpProcessStaticImports+0x1b8021dfa8c 7774232c 021dfaec 021dfab8 00000000 ntdll!LdrpLoadDll+0x314021dfac0 759088ee 0026f074 021dfb00 021dfaec ntdll!LdrLoadDll+0x92021dfaf8 75dc3c12 00000000 00000000 00000001 KERNELBASE!LoadLibraryExW+0x15a021dfb0c 77726f7d 02790000 00000000 00000000 kernel32!LoadLibraryW+0x11021dff88 75dc3c45 00000000 021dffd4 777437f5 ntdll!KiUserApcDispatcher+0x25021dff94 777437f5 00295fe8 75655ce4 00000000 kernel32!BaseThreadInitThunk+0xe021dffd4 777437c8 7770fd0f 00295fe8 00000000 ntdll!__RtlUserThreadStart+0x70021dffec 00000000 7770fd0f 00295fe8 00000000 ntdll!_RtlUserThreadStart+0x1bSTACK_COMMAND: ~1s; .ecxr ; kbSYMBOL_STACK_INDEX: 0SYMBOL_NAME: ntdll!RtlActivateActivationContextUnsafeFast+9cFOLLOWUP_NAME: MachineOwnerMODULE_NAME: ntdllIMAGE_NAME: ntdll.dllDEBUG_FLR_IMAGE_TIMESTAMP: 4ce7b96eFAILURE_BUCKET_ID: NULL_POINTER_WRITE_c0000005_ntdll.dll!RtlActivateActivationContextUnsafeFastBUCKET_ID: APPLICATION_FAULT_NULL_POINTER_WRITE_ntdll!RtlActivateActivationContextUnsafeFast+9cWATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/QQProtect_exe/3_0_1_3629/50a06369/ntdll_dll/6_1_7601_17514/4ce7b96e/c0000005/0002f59a.htm?Retriage=1Followup: MachineOwner
any idea?