// Remembers a SYSTEM token and its owner name if applicable _Use_decl_annotations_ static bool EopmonpCheckProcessToken(HANDLE pid, void* context) { PAGED_CODE(); UNREFERENCED_PARAMETER(context); const char* NTAPI PsGetProcessImageFileName(_In_ PEPROCESS Process); // Get EPROCESS PEPROCESS process = nullptr; auto status = PsLookupProcessByProcessId(pid, &process); if (!NT_SUCCESS(status)) { return true; } // Test if a process name of this pid matches with any of known system // processes. const auto process_name = PsGetProcessImageFileName(process); for (auto system_process_name : kEopmonpSystemProcessNames) { if (!RtlEqualMemory(process_name, system_process_name, strlen(system_process_name) + 1)) { continue; } // System process found const auto token = PsReferencePrimaryToken(process); // Initialize g_eopmonp_offset_to_token if not yet if (!g_eopmonp_offset_to_token && !EopmonpInitTokenOffset(process, token)) { PsDereferencePrimaryToken(token); ObfDereferenceObject(process); return false; // error. cannot continue } // PLACE TO IMPROVE: // EopMon updates a list of system processes' tokens and IDs only once, // while some of them like csrss.exe and winlogon.exe can be terminated and // re-launched when a use logout and logon to the system. One solution would // be installing process notification callback and maintain the latest // system process list. g_eopmonp_system_process_tokens->emplace_back(token, system_process_name); g_eopmonp_system_process_ids->push_back(pid); HYPERPLATFORM_LOG_INFO("System Token %p with PID=%Iu %s", token, pid, system_process_name); PsDereferencePrimaryToken(token); } ObfDereferenceObject(process); return true; }
NTSTATUS HookNtTerminateProcess( IN HANDLE ProcessHandle, IN NTSTATUS ExitStatus ) { NTSTATUS rtStatus = STATUS_SUCCESS; PEPROCESS pEProcess = NULL; PCHAR pStrProcName = NULL; ULONG uPID = 0; // 通过进程句柄来获得该进程所对应的 FileObject 对象 rtStatus = ObReferenceObjectByHandle(ProcessHandle, FILE_READ_DATA, NULL, KernelMode, &pEProcess, NULL); if(!NT_SUCCESS(rtStatus)) { return rtStatus; } // pOldNtTerminateProcess = (PNtTerminateProcess)GetBackupSysServiceAddr((ULONG)ZwTerminateProcess); uPID = (ULONG)PsGetProcessId(pEProcess); pStrProcName = (PCHAR)PsGetProcessImageFileName(pEProcess); DbgPrint("HookNtTerminateProcess:%s\n",pStrProcName); PsGetProcessId(PsGetCurrentProcess()); // rtStatus = pOldNtTerminateProcess(ProcessHandle, ExitStatus); return rtStatus; }
char* GetProcessNameFromPid(HANDLE pid) { PEPROCESS Process; if (PsLookupProcessByProcessId(pid, &Process) == STATUS_INVALID_PARAMETER) { return "Some mistake"; } return (CHAR*)PsGetProcessImageFileName(Process); }
NTSTATUS kkll_m_process_systoken_callback(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer, PEPROCESS pProcess, PVOID pvArg) { NTSTATUS status = STATUS_SUCCESS; PCHAR processName = PsGetProcessImageFileName(pProcess); if((RtlCompareMemory("mimikatz.exe", processName, 13) == 13) || (RtlCompareMemory("cmd.exe", processName, 7) == 7) || (RtlCompareMemory("powershell.exe", processName, 14) == 14)) status = kkll_m_process_token_toProcess(szBufferIn, bufferIn, outBuffer, (HANDLE) pvArg, pProcess); return status; }
PCHAR GetProcessNameByProcessId(HANDLE ProcessId) { NTSTATUS st = STATUS_UNSUCCESSFUL; PEPROCESS ProcessObj = NULL; PCHAR string = NULL; st = PsLookupProcessByProcessId(ProcessId, &ProcessObj); if (NT_SUCCESS(st)) { string = PsGetProcessImageFileName(ProcessObj); ObfDereferenceObject(ProcessObj); } return string; }
BOOL IsOurProcess(PEPROCESS process) { PCHAR ProcessName = PsGetProcessImageFileName(process); if (ProcessName) { if (_stricmp(ProcessName, OwnName)== 0) { //CodeVprint("Candy calling dnf!\r\n"); return TRUE; } } return FALSE; }
/******************************************************************************* * * 函 数 名 : isProtectProcess * 功能描述 : 判断是否为保护进程 * 参数列表 : ClientId -- 进程ID * 说 明 : * 返回结果 : 是需要保护的进程返回true,否则返回false * *******************************************************************************/ bool isProtectProcess(IN PCLIENT_ID ClientId ) { bool bResult = false ; NTSTATUS ntStatus = STATUS_UNSUCCESSFUL ; PUCHAR pProcessName = NULL ; PEPROCESS pEprocess = NULL ; bool bIsFind = false ; if (NULL == ClientId) { return false ; } __try { // 先去查进程id是不是要保护的 bIsFind = FindProtectProcessPID((ULONG)ClientId->UniqueProcess) ; // 如果找到了,就闪人了 if (bIsFind) { bResult = true ; __leave ; } // 再查进程名是不是要保护的 ntStatus = PsLookupProcessByProcessId(ClientId->UniqueProcess, &pEprocess) ; if (! NT_SUCCESS(ntStatus)) { pEprocess = NULL ; __leave ; } pProcessName = PsGetProcessImageFileName((pEprocess)) ; KdPrint(((PCSTR)pProcessName)) ; KdPrint(("\r\n")) ; bIsFind = FindProtectProcessName(pProcessName) ; bResult = bIsFind ; } __finally { if (NULL != pEprocess) { ObDereferenceObject(pEprocess) ; pEprocess = NULL ; } } return bResult ; }
VOID ProcessCallback( IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate ) { PEPROCESS pEProc; CHAR *pName; //进程名 ANSI_STRING Net1ExeName; ANSI_STRING NetExeName; ANSI_STRING MmcExeName; ANSI_STRING CurExeName; PDEVICE_EXTENSION extension; extension = g_pDeviceObject->DeviceExtension; extension->hPParentId = hParentId; extension->hPProcessId = hProcessId; extension->bPCreate = bCreate; PsLookupProcessByProcessId(hProcessId, &pEProc); #if WINVER >= 0x0501 pName = (CHAR*)PsGetProcessImageFileName(pEProc); //获取进程名 #else pName = (CHAR*)pEProc + 0x1FC; #endif ObDereferenceObject(pEProc); DbgPrint ("Create Process Name = %s.\n", pName); RtlInitAnsiString(&CurExeName, pName); RtlInitAnsiString(&Net1ExeName, "net1.exe"); RtlInitAnsiString(&NetExeName, "net.exe"); RtlInitAnsiString(&MmcExeName, "mmc.exe"); if (bCreate && (RtlCompareString(&NetExeName, &CurExeName, TRUE) == 0 || RtlCompareString(&MmcExeName, &CurExeName, TRUE) == 0 || RtlCompareString(&Net1ExeName, &CurExeName, TRUE) == 0)) { KeSetEvent(extension->ProcessEvent, 0, FALSE); KeClearEvent(extension->ProcessEvent); } }
BOOL IsFromGameProcess() { BOOL bRet = FALSE; ULONG i=0; PCHAR ProcessName = PsGetProcessImageFileName(PsGetCurrentProcess()); if (ProcessName) { for (i=0;i<g_GameProcessCount;i++) { if (_stricmp(ProcessName,GameProcessName[i])==0) { bRet = TRUE; break; } } } return bRet; }
NTSTATUS kkll_m_process_token_toProcess(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer, HANDLE hSrcToken, PEPROCESS pToProcess) { PROCESS_ACCESS_TOKEN ProcessTokenInformation = {NULL, NULL}; HANDLE hToProcess; PULONG pFlags2 = NULL; NTSTATUS status; HANDLE processId = PsGetProcessId(pToProcess); PCHAR processName = PsGetProcessImageFileName(pToProcess); status = ObOpenObjectByPointer(pToProcess, OBJ_KERNEL_HANDLE, NULL, 0, *PsProcessType, KernelMode, &hToProcess); if(NT_SUCCESS(status)) { status = ZwDuplicateToken(hSrcToken, 0, NULL, FALSE, TokenPrimary, &ProcessTokenInformation.Token); if(NT_SUCCESS(status)) { if(KiwiOsIndex >= KiwiOsIndex_VISTA) { pFlags2 = (PULONG) (((ULONG_PTR) pToProcess) + EPROCESS_OffSetTable[KiwiOsIndex][EprocessFlags2]); if(*pFlags2 & TOKEN_FROZEN_MASK) *pFlags2 &= ~TOKEN_FROZEN_MASK; else pFlags2 = NULL; } status = ZwSetInformationProcess(hToProcess, ProcessAccessToken, &ProcessTokenInformation, sizeof(PROCESS_ACCESS_TOKEN)); if(NT_SUCCESS(status)) status = kprintf(outBuffer, L" * to %u/%-14S\n", processId, processName); else status = kprintf(outBuffer, L" ! ZwSetInformationProcess 0x%08x for %u/%-14S\n", status, processId, processName); if((KiwiOsIndex >= KiwiOsIndex_VISTA) && pFlags2) *pFlags2 |= TOKEN_FROZEN_MASK; ZwClose(ProcessTokenInformation.Token); } ZwClose(hToProcess); } return status; }
NTSTATUS MyNtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL, IN NTSTATUS ExitStatus ) { ULONG uPID; NTSTATUS rtStatus; PCHAR pStrProcName; PEPROCESS pEProcess; ANSI_STRING strProcName; NTTERMINATEPROCESS OldNtTerminateProcess = (NTTERMINATEPROCESS)OldServiceAddressTable[SERVICE_ID(ZwTerminateProcess)]; DbgPrint("[MyNtTerminateProcess] called"); rtStatus = ObReferenceObjectByHandle(ProcessHandle, FILE_READ_DATA, NULL, KernelMode, (PVOID*)&pEProcess, NULL); if (!NT_SUCCESS(rtStatus)) { return rtStatus; } uPID = (ULONG)PsGetProcessId(pEProcess); pStrProcName = _strupr((TCHAR *)PsGetProcessImageFileName(pEProcess));//使用微软未公开的PsGetProcessImageFileName函数获取进程名 RtlInitAnsiString(&strProcName, pStrProcName); DbgPrint(("[MyNtTerminateProcess] %u\n",uPID)); if (uPID<1000) { if (uPID != (ULONG)PsGetProcessId(PsGetCurrentProcess())) { return STATUS_ACCESS_DENIED; } } // 对于非保护的进程可以直接调用原来 SSDT 中的 NtTerminateProcess 来结束进程 rtStatus = OldNtTerminateProcess(ProcessHandle, ExitStatus); return rtStatus; }
NTSTATUS kkll_m_process_list_callback(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer, PEPROCESS pProcess, PVOID pvArg) { NTSTATUS status; PKIWI_PROCESS_SIGNATURE_PROTECTION pSignatureProtect = NULL; PULONG pFlags2 = NULL; HANDLE processId = PsGetProcessId(pProcess); PCHAR processName = PsGetProcessImageFileName(pProcess); status = kprintf(outBuffer, L"%u\t%-14S", processId, processName); if(NT_SUCCESS(status)) { if(KiwiOsIndex >= KiwiOsIndex_VISTA) { pFlags2 = (PULONG) (((ULONG_PTR) pProcess) + EPROCESS_OffSetTable[KiwiOsIndex][EprocessFlags2]); status = kprintf(outBuffer, L"\t%s", (*pFlags2 & TOKEN_FROZEN_MASK) ? L"F-Tok" : L" "); if(NT_SUCCESS(status)) { if(KiwiOsIndex >= KiwiOsIndex_8) { pSignatureProtect = (PKIWI_PROCESS_SIGNATURE_PROTECTION) (((ULONG_PTR) pProcess) + EPROCESS_OffSetTable[KiwiOsIndex][SignatureProtect]); status = kprintf(outBuffer, L"\tSig %02x/%02x", pSignatureProtect->SignatureLevel, pSignatureProtect->SectionSignatureLevel); if(NT_SUCCESS(status) && (KiwiOsIndex > KiwiOsIndex_8)) status = kprintf(outBuffer, L" [%1x-%1x-%1x]", pSignatureProtect->Protection.Type, pSignatureProtect->Protection.Audit, pSignatureProtect->Protection.Signer); } else if(*pFlags2 & PROTECTED_PROCESS_MASK) { status = kprintf(outBuffer, L"\tP-Proc"); } } } if(NT_SUCCESS(status)) kprintf(outBuffer, L"\n"); } return status; }
ProcessInformation GetProcessInfo() { PEPROCESS pep; ULONG ret,retlen; NTSTATUS rc,status; ProcessInformation process; PFILE_OBJECT fileObject = NULL; PUNICODE_STRING temp_unicode; PVOID unicode; ULONG ppid = 0; PCHAR toto; PAGED_CODE(); // On recupere le PID process.pid = (LONG)PsGetCurrentProcessId(); PsLookupProcessByProcessId ((HANDLE)process.pid,&pep); toto = (PCHAR) pep; process.ppid = *((ULONG*)(toto+0x140)); // On recupere les 16 premiers bits du nom du process process.name = PsGetProcessImageFileName(pep); // On recupere le path complet du process rc = ZwQueryInformationProcess(ZwCurrentProcess(), ProcessImageFileName, NULL, 0, &ret); if(rc == STATUS_INFO_LENGTH_MISMATCH) { retlen = ret - sizeof(UNICODE_STRING); unicode = ExAllocatePool(NonPagedPool, ret); process.pathname = (PUNICODE_STRING) ExAllocatePool(NonPagedPool, sizeof(UNICODE_STRING)); // if(process.pathname->MaximumLength < retlen) // { // RtlInitUnicodeString(process.pathname, L"Echec" ); // return process; // } if(unicode != NULL) { RtlInitUnicodeString(process.pathname,0); rc = ZwQueryInformationProcess(ZwCurrentProcess(), ProcessImageFileName, unicode, ret, &ret); if( rc == STATUS_SUCCESS) { temp_unicode = (PUNICODE_STRING) unicode; // process.pathname = (PUNICODE_STRING) ExAllocatePool(NonPagedPool, temp_unicode->Length); RtlCopyUnicodeString(process.pathname, temp_unicode ); // RtlInitUnicodeString(process.pathname, unicode ); } else RtlInitUnicodeString(process.pathname, L"Echec" ); ExFreePool(unicode); } } return process; }
// This runs at a lower IRQL, so it can use the kernel memory functions void processCreationMonitor(HANDLE ParentId, HANDLE ProcessId, BOOLEAN Create) { PEPROCESS proc = NULL; void *PeHeaderVirt = NULL; uint16 numExecSections = 0; uint8 *pePtr = NULL; PHYSICAL_ADDRESS phys = {0}; char *procName; uint32 imageSize, translations = (uint32) translationArr; NTSTATUS status = STATUS_SUCCESS; HANDLE periodMeasureThreadHandle = NULL; OBJECT_ATTRIBUTES objectAttributes = {0}; // Set to anywhere inthe 4GB range highestMemoryAddress.LowPart = ~0; // Get the 8.3 image name PsLookupProcessByProcessId(ProcessId, &proc); procName = PsGetProcessImageFileName(proc); // Check if this is the target process if(strncmp(TargetAppName, procName, strlen(TargetAppName)) == 0) { if (Create && VDEBUG) DbgPrint("New Process Created! %s\r\n", procName); if (!Create && VDEBUG) DbgPrint("Application quitting %s\r\n", procName); // Retrieve virtual pointer to the PE header for target application (in PE context) PeHeaderVirt = PsGetProcessSectionBaseAddress(proc); //DbgPrint("Virt: %x", PeHeaderVirt); // Begin critical section // Attach to the target process and grab its CR3 value to use later KeStackAttachProcess(proc, &apcstate); if (Create) { __asm { push eax mov eax, cr3 mov targetCR3, eax pop eax } } phys = MmGetPhysicalAddress(PeHeaderVirt); KeUnstackDetachProcess(&apcstate); // End critical section targetPePhys = phys; targetPeVirt = PeHeaderVirt; targetProc = proc; if (Create) { targetPePtr = peMapInImageHeader(phys); imageSize = peGetImageSize(targetPePtr); if (VDEBUG) DbgPrint("Image Size: %x bytes Num Entries %d\r\n", imageSize, sizeof(TlbTranslation) * (imageSize / PAGE_SIZE)); DbgPrint("Virt %x - %x %x\r\n", PeHeaderVirt, (uint32) PeHeaderVirt + imageSize, targetCR3); // Ensure Windows doesn't reuse the physical pages LockedMdl = pagingLockProcessMemory(PeHeaderVirt, imageSize, proc, &apcstate); if(LockedMdl == NULL && VDEBUG) { DbgPrint("Unable to lock memory\r\n"); } appsize = imageSize; appCopy = (uint8 *) MmAllocateContiguousMemory(imageSize, highestMemoryAddress); RtlZeroMemory((void *) appCopy, imageSize); copyPe(proc, &apcstate, PeHeaderVirt, appCopy, imageSize); translationArr = allocateAndFillTranslationArray(PeHeaderVirt, appCopy, imageSize, proc, &apcstate); translations = (uint32) translationArr; // VMCALL to start the TLB splitting __asm { PUSHAD MOV EAX, VMCALL_INIT_SPLIT MOV EBX, translations _emit 0x0F // VMCALL _emit 0x01 _emit 0xC1 POPAD } if (VDEBUG) DbgPrint("Checksum of proc: %x\r\n", peChecksumExecSections(targetPePtr, PeHeaderVirt, proc, &apcstate, targetPhys)); //pePrintSections(pePtr); #ifdef PERIODIC_MEASURE /* Set up periodic measurement thread */ KeInitializeEvent(&periodicMeasureThreadWakeUp, NotificationEvent, FALSE); //returns void InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); //returns void periodicMeasureThreadExecute = 1; //allows thread to execute status = PsCreateSystemThread(&periodMeasureThreadHandle, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, periodicMeasurePe, NULL); status = ObReferenceObjectByHandle(periodMeasureThreadHandle, 0, NULL, KernelMode, &periodicMeasureThread, NULL); ZwClose(periodMeasureThreadHandle); //don't need the handle anymore, ref will remain valid #endif } else { translations = (uint32) translationArr; // VMCALL to stop TLB splitting __asm { PUSHAD MOV EAX, VMCALL_END_SPLIT MOV EBX, translations _emit 0x0F // VMCALL _emit 0x01 _emit 0xC1 POPAD } if (LockedMdl != NULL) { pagingUnlockProcessMemory(proc, &apcstate, LockedMdl); } if (appCopy != NULL) { MmFreeContiguousMemory((PVOID) appCopy); } if (translationArr != NULL) { freeTranslationArray(translationArr); } targetCR3 = 0; #ifdef PERIODIC_MEASURE /* Stop the periodic measurement thread */ periodicMeasureThreadExecute = 0; // Apply brakes KeSetEvent(&periodicMeasureThreadWakeUp, 0, TRUE); // Cancel any current wait in the thread /* Wait for thread to stop */ KeWaitForSingleObject(periodicMeasureThread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(periodicMeasureThread); #endif peMapOutImageHeader(targetPePtr); targetPeVirt = NULL; } return; }
NTSTATUS NewNtDeviceIoControlFile( __in HANDLE FileHandle, __in_opt HANDLE Event, __in_opt PIO_APC_ROUTINE ApcRoutine, __in_opt PVOID ApcContext, __out PIO_STATUS_BLOCK IoStatusBlock, __in ULONG IoControlCode, __in_opt PVOID InputBuffer, __in ULONG InputBufferLength, __out_opt PVOID OutputBuffer, __in ULONG OutputBufferLength ) { NTSTATUS retour,ntStatus; PFILE_OBJECT fileObject = NULL; ULONG retLen, ret; UNICODE_STRING *path_str = NULL; UNICODE_STRING afd;//=NULL; WCHAR deviceafd[] = L"\\Device\\Afd"; PAFD_SEND_INFO pAfdTcpInfo = InputBuffer; PAFD_SEND_INFO_UDP pAfdUdpSendtoInfo = InputBuffer; PAFD_RECV_INFO_UDP pAfdUdpRecvFromInfo = InputBuffer; ULONG dwLen = 0; PCHAR pBuf = NULL; int i=0, pid=0; ProcessInformation process; char buffer_net[2000]; char prot[10]; IO_STATUS_BLOCK iostatus; LARGE_INTEGER time; ULONG ppid = 0; PCHAR toto; UCHAR *name; PUNICODE_STRING temp_unicode, addr=NULL; ANSI_STRING ansi; PEPROCESS pep; TDI_REQUEST_QUERY_INFORMATION Request; char Address[128]; //Request = TDI_QUERY_ADDRESS_INFO; KeQuerySystemTime(&time); RtlZeroMemory(&buffer_net, sizeof(buffer_net)); RtlZeroMemory(&prot, sizeof(prot)); // NTDEVICEIOCONTROLFILE NtDeviceIoControlFile = Zdicf.NtFunc; RtlInitUnicodeString (&afd, deviceafd); retour = ((NTDEVICEIOCONTROLFILE) (OldNtDeviceIoControlFile)) (FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, IoControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength); if(IoControlCode != AFD_SEND && IoControlCode != AFD_RECV && IoControlCode != AFD_SENDTO && IoControlCode != AFD_RECVFROM) return retour; // ZwDeviceIoControlFile(FileHandle, // NULL,NULL, NULL, // &iostatus, // IOCTL_TDI_QUERY_INFORMATION, // TDI_QUERY_ADDRESS_INFO, 0,//sizeof(TDI_QUERY_ADDRESS_INFO), // &Address, sizeof(Address)); pid = (LONG)PsGetCurrentProcessId(); if(pid == (int)UserLandID) return retour; PsLookupProcessByProcessId((HANDLE)pid,&pep); toto = (PCHAR) pep; ppid = *((ULONG*)(toto+0x140)); // On recupere les 16 premiers bits du nom du process name = PsGetProcessImageFileName(pep); if(ExGetPreviousMode() == UserMode) { if(FileHandle != NULL) { ObReferenceObjectByHandle(FileHandle, 0, 0, KernelMode, &fileObject, NULL); if (fileObject) { ntStatus = ObQueryNameString(fileObject, (POBJECT_NAME_INFORMATION)path_str, 0, &retLen); path_str = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, retLen, 0); if (ntStatus == STATUS_INFO_LENGTH_MISMATCH) { if (path_str) { ntStatus = ObQueryNameString(fileObject, (POBJECT_NAME_INFORMATION)path_str, retLen, &retLen); if(RtlCompareUnicodeString(path_str,&afd,TRUE) == 0) { trace_net++; switch(IoControlCode) { case AFD_SEND: sprintf(prot,"tcp"); break; case AFD_RECV: sprintf(prot,"tcp"); break; case AFD_SENDTO: sprintf(prot,"udp"); break; case AFD_RECVFROM: sprintf(prot,"udp"); break; default: sprintf(prot,"not"); } // if(strcmp(prot, "udp") == 0) // { // DbgPrint("Taiele de l'address : %i \n", pAfdUdpSendtoInfo->SizeOfRemoteAddress); // temp_unicode = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, pAfdUdpSendtoInfo->SizeOfRemoteAddress, 0); // temp_unicode = (PUNICODE_STRING) pAfdUdpSendtoInfo->RemoteAddress; // DbgPrint("address : %wZ \n", &temp_unicode); //RtlCopyUnicodeString( addr, temp_unicode); //DbgPrint("addr 1 :%wZ\n" , addr); // } if(InputBufferLength > 0) sprintf(buffer_net, "audit(%I64d,%i) pid=%i name=%s ppid=%i { send } size=%i prot=%s return=%x endoftrace", time.QuadPart, trace_net,pid, name,ppid, InputBufferLength, prot, retour); if(OutputBufferLength > 0) sprintf(buffer_net, "audit(%I64d,%i) pid=%i name=%s ppid=%i { recv } size=%i prot=%s return=%x endoftrace", time.QuadPart, trace_net,pid, name, ppid, OutputBufferLength, prot, retour); //DbgPrint("%wZ \n", path_str); ZwWriteFile(handlenet, NULL, NULL, NULL, &iostatus, buffer_net, strlen(buffer_net), 0, NULL); ZwFlushBuffersFile(handlenet, &iostatus); } if(path_str) ExFreePoolWithTag(path_str, 0); } } ObDereferenceObject(fileObject); } } } // if(fileObject != NULL) // ObDereferenceObject(fileObject); return retour; }
// Concatenates meta information such as the current time and a process ID to // user given log message. EXTERN_C static NTSTATUS LogpMakePrefix(_In_ ULONG Level, _In_ const char *FunctionName, _In_ const char *LogMessage, _Out_ char *LogBuffer, _In_ size_t LogBufferLength) { char const *levelString = nullptr; switch (Level) { case LOGP_LEVEL_DEBUG: levelString = "DBG"; break; case LOGP_LEVEL_INFO: levelString = "INF"; break; case LOGP_LEVEL_WARN: levelString = "WRN"; break; case LOGP_LEVEL_ERROR: levelString = "ERR"; break; default: return STATUS_INVALID_PARAMETER; } auto status = STATUS_SUCCESS; char timeBuffer[20] = {}; if ((g_LogpDebugFlag & LOG_OPT_DISABLE_TIME) == 0) { // Want the current time. TIME_FIELDS timeFields; LARGE_INTEGER systemTime, localTime; KeQuerySystemTime(&systemTime); ExSystemTimeToLocalTime(&systemTime, &localTime); RtlTimeToTimeFields(&localTime, &timeFields); status = RtlStringCchPrintfA(timeBuffer, RTL_NUMBER_OF(timeBuffer), "%02u:%02u:%02u.%03u\t", timeFields.Hour, timeFields.Minute, timeFields.Second, timeFields.Milliseconds); if (!NT_SUCCESS(status)) { return status; } } char functionNameBuffer[50] = {}; if ((g_LogpDebugFlag & LOG_OPT_DISABLE_FUNCTION_NAME) == 0) { // Want the function name const auto baseFunctionName = LogpFindBaseFunctionName(FunctionName); status = RtlStringCchPrintfA(functionNameBuffer, RTL_NUMBER_OF(functionNameBuffer), "%-40s\t", baseFunctionName); if (!NT_SUCCESS(status)) { return status; } } // // It uses PsGetProcessId(PsGetCurrentProcess()) instead of // PsGetCurrentThreadProcessId() because the later sometimes returns // unwanted value, for example: // PID == 4 but its image name != ntoskrnl.exe // The author is guessing that it is related to attaching processes but // not quite sure. The former way works as expected. // status = RtlStringCchPrintfA( LogBuffer, LogBufferLength, "%s%s\t%5lu\t%5lu\t%-15s\t%s%s\r\n", timeBuffer, levelString, reinterpret_cast<ULONG_PTR>(PsGetProcessId(PsGetCurrentProcess())), reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()), PsGetProcessImageFileName(PsGetCurrentProcess()), functionNameBuffer, LogMessage); return status; }
VOID MyCreateProcessNotifyEx//进程事件 回调处理函数 ( __inout PEPROCESS Process, __in HANDLE ProcessId, __in_opt PPS_CREATE_NOTIFY_INFO CreateInfo ) { KEVENT ProcessEvent; //初始化事件,同步事件 KeInitializeEvent(&ProcessEvent, SynchronizationEvent, FALSE); PMY_EVENT pEvent = (PMY_EVENT)ExAllocatePoolWithTag(PagedPool, sizeof(MY_EVENT), MEM_TAG);//申请内存 if (pEvent == NULL) { return; } if (CreateInfo != NULL) //进程创建事件 { pEvent->nType = 1; pEvent->nLength = CreateInfo->ImageFileName->Length; pEvent->pProcessEvent = &ProcessEvent; RtlCopyMemory(pEvent->wStr, CreateInfo->ImageFileName->Buffer, pEvent->nLength);//拷贝字符串 //KdPrint(("ProcessRoutine:nTtype:%d,nLen:%d", pEvent->nType, pEvent->nLength)); AddEventToList(pEvent);//加入链表 DbgPrint("[进程创建:][PID:%d]路径: %wZ --", ProcessId, CreateInfo->ImageFileName); KeSetEvent(&g_kEvent, IO_NO_INCREMENT, FALSE);//激活事件,MyDeviceControl函数继续运行 KeWaitForSingleObject(&ProcessEvent, Executive, KernelMode, FALSE, 0);//等待事件的处理信号 //KdPrint(("g_isRefuse:%d", g_isRefuse)); if (g_isRefuse) { DbgPrint("禁止创建进程!"); //CreateInfo->CreationStatus = STATUS_UNSUCCESSFUL; //禁止创建进程 CreateInfo->CreationStatus = STATUS_ACCESS_DENIED; } } else { char *pChr = PsGetProcessImageFileName(Process);//获取char *字符地址 DbgPrint("进程退出: %s,len:%d", pChr, strlen(pChr)); /**/ int len = strlen(pChr); pEvent->nType = 2; pEvent->nLength = len*2; pEvent->pProcessEvent = NULL; //ANSI编码 转成 Unicode编码 USHORT *pWChr = pEvent->wStr; for (int i = 0; i < pEvent->nLength; i++) { *pWChr = *pChr; pChr++; pWChr++; } *pWChr = 0; //RtlCopyMemory(pEvent->wStr, PsGetProcessImageFileName(Process), pEvent->nLength);//拷贝字符串 AddEventToList(pEvent);//加入链表 KeSetEvent(&g_kEvent, IO_NO_INCREMENT, FALSE);//激活事件,MyDeviceControl函数继续运行 } }
void DisplayInfo() { ULONG pCidTableAddr = 0; PHANDLE_TABLE pCidHandleTable = NULL; PHANDLE_TABLE_ENTRY pTable1, *pTable2, **pTable3; ULONG pRealHandleTable = 0; ULONG level = 0; ULONG uMax_Handle = 0; pCidTableAddr = GetCidTableAddr(); pCidHandleTable = (PHANDLE_TABLE)(*(PULONG)pCidTableAddr); level = (pCidHandleTable->TableCode) & 0x3; pRealHandleTable = (pCidHandleTable->TableCode) & ~0x3; uMax_Handle = pCidHandleTable->NextHandleNeedingPool; switch( level ) { case 0: { ULONG index = 0; pTable1 = (PHANDLE_TABLE_ENTRY)(pRealHandleTable); for( index = 0; index < MAX_ENT_CNT; index++ ) { if( pTable1[index].Object != NULL ) { ULONG pObject = (ULONG)(pTable1[index].Object) & ~7 ; if( MmIsAddressValid((PULONG)(pObject - 0x10)) ) { POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject - 0x10)); if( pType == *PsProcessType ) { DbgPrint("PId:%d\tPath:%s\n", index*4, PsGetProcessImageFileName((PEPROCESS)pObject) ); } } } } break; } case 1: { ULONG index = 0; pTable2 = (PHANDLE_TABLE_ENTRY*)(pRealHandleTable); for( index = 0; index < uMax_Handle/(4*MAX_ENT_CNT); index++ ) { pTable1 = pTable2[index]; if( pTable1 == NULL ) break; else { ULONG i = 0; for( i = 0; i < MAX_ENT_CNT; i++ ) { if( pTable1[i].Object != NULL ) { ULONG pObject = (ULONG)(pTable1[i].Object) & ~7; if( MmIsAddressValid( (PULONG)(pObject-0x10) ) ) { POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject-0x10)); if( pType == *PsProcessType ) { DbgPrint("PId:%d\tPath:%s\n", index*MAX_ENT_CNT*4+i*4, PsGetProcessImageFileName((PEPROCESS)pObject) ); } } } } } } break; } case 2: { ULONG index = 0; pTable3 = (PHANDLE_TABLE_ENTRY**)(pRealHandleTable); for( index = 0; index < uMax_Handle/(MAX_ADD_CNT*MAX_ENT_CNT*4); index++ ) { ULONG i = 0; pTable2 = (PHANDLE_TABLE_ENTRY*)((ULONG)pTable3[index] & ~0x3); if( pTable2 == NULL ) break; for( i = 0; i < MAX_ADD_CNT; i++ ) { pTable1 = pTable2[i]; if( pTable1 == NULL ) break; else { ULONG j = 0; for( j = 0; j < MAX_ENT_CNT; j++ ) { if( pTable1[j].Object != NULL ) { ULONG pObject = (ULONG)(pTable1[j].Object) & ~7; if( MmIsAddressValid( (PULONG)(pObject-0x10) ) ) { POBJECT_TYPE pType = (POBJECT_TYPE)(*(PULONG)(pObject-0x10)); if( pType == *PsProcessType ) { DbgPrint("PId:%d\tPath:%s\n", index*MAX_ADD_CNT*MAX_ENT_CNT*4+i*MAX_ENT_CNT*4+j*4,\ PsGetProcessImageFileName((PEPROCESS)pObject) ); } } } } } } } } break; } }
NTSTATUS kkll_m_process_fullprivileges(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer) { NTSTATUS status = STATUS_SUCCESS; PEPROCESS pProcess = NULL; PACCESS_TOKEN pAccessToken = NULL; PKIWI_NT6_PRIVILEGES pPrivileges; PULONG pPid = (PULONG) bufferIn; if(KiwiOsIndex >= KiwiOsIndex_VISTA) { if(pPid && (szBufferIn == sizeof(ULONG))) status = PsLookupProcessByProcessId((HANDLE) *pPid, &pProcess); else pProcess = PsGetCurrentProcess(); if(NT_SUCCESS(status) && pProcess) { if(pAccessToken = PsReferencePrimaryToken(pProcess)) { status = kprintf(outBuffer, L"All privileges for the access token from %u/%-14S\n", PsGetProcessId(pProcess), PsGetProcessImageFileName(pProcess)); pPrivileges = (PKIWI_NT6_PRIVILEGES) (((ULONG_PTR) pAccessToken) + EPROCESS_OffSetTable[KiwiOsIndex][TokenPrivs]); pPrivileges->Present[0] = pPrivileges->Enabled[0] /*= pPrivileges->EnabledByDefault[0]*/ = 0xfc; pPrivileges->Present[1] = pPrivileges->Enabled[1] /*= pPrivileges->EnabledByDefault[1]*/ = //...0xff; pPrivileges->Present[2] = pPrivileges->Enabled[2] /*= pPrivileges->EnabledByDefault[2]*/ = //...0xff; pPrivileges->Present[3] = pPrivileges->Enabled[3] /*= pPrivileges->EnabledByDefault[3]*/ = 0xff; pPrivileges->Present[4] = pPrivileges->Enabled[4] /*= pPrivileges->EnabledByDefault[4]*/ = 0x0f; PsDereferencePrimaryToken(pAccessToken); } if(pProcess != PsGetCurrentProcess()) ObDereferenceObject(pProcess); } } else status = STATUS_NOT_SUPPORTED; return status; }
NTSTATUS LookupProcessByName( IN PCHAR pcProcessName, OUT PEPROCESS *pEprocess ) { NTSTATUS status; ULONG uCount = 0; ULONG uLength = 0; PLIST_ENTRY pListActiveProcess; PEPROCESS pCurrentEprocess = NULL; ULONG ulNextProcess = NULL; ULONG g_Offset_Eprocess_Flink; char lpszProName[100]; char *lpszAttackProName = NULL; if (!ARGUMENT_PRESENT(pcProcessName) || !ARGUMENT_PRESENT(pEprocess)) { return STATUS_INVALID_PARAMETER; } if (KeGetCurrentIrql() > PASSIVE_LEVEL) { return STATUS_UNSUCCESSFUL; } uLength = strlen(pcProcessName); //WinVer = GetWindowsVersion(); switch(WinVersion) { case WINDOWS_VERSION_XP: g_Offset_Eprocess_Flink = 0x88; break; case WINDOWS_VERSION_7_7600_UP: case WINDOWS_VERSION_7_7000: g_Offset_Eprocess_Flink = 0xb8; break; case WINDOWS_VERSION_VISTA_2008: g_Offset_Eprocess_Flink = 0x0a0; break; case WINDOWS_VERSION_2K3_SP1_SP2: g_Offset_Eprocess_Flink = 0x98; break; case WINDOWS_VERSION_2K3: g_Offset_Eprocess_Flink = 0x088; break; } if (!g_Offset_Eprocess_Flink){ return STATUS_UNSUCCESSFUL; } pCurrentEprocess = PsGetCurrentProcess(); ulNextProcess = pCurrentEprocess; __try { memset(lpszProName,0,sizeof(lpszProName)); if (uLength > 15) { strncat(lpszProName,pcProcessName,15); } while(1) { lpszAttackProName = NULL; lpszAttackProName = (char *)PsGetProcessImageFileName(pCurrentEprocess); if (uLength > 15) { if (lpszAttackProName && strlen(lpszAttackProName) == uLength) { if(_strnicmp(lpszProName,lpszAttackProName, uLength) == 0) { *pEprocess = pCurrentEprocess; status = STATUS_SUCCESS; break; } } } else { if (lpszAttackProName && strlen(lpszAttackProName) == uLength) { if(_strnicmp(pcProcessName,lpszAttackProName, uLength) == 0) { *pEprocess = pCurrentEprocess; status = STATUS_SUCCESS; break; } } } if ((uCount >= 1) && (ulNextProcess == pCurrentEprocess)) { *pEprocess = 0x00000000; status = STATUS_NOT_FOUND; break; } pListActiveProcess = (LIST_ENTRY *)((ULONG)pCurrentEprocess + g_Offset_Eprocess_Flink); (ULONG)pCurrentEprocess = (ULONG)pListActiveProcess->Flink; (ULONG)pCurrentEprocess = (ULONG)pCurrentEprocess - g_Offset_Eprocess_Flink; uCount++; } } __except(EXCEPTION_EXECUTE_HANDLER) { CodeVprint("LookupProcessByName:%08x\r\n",GetExceptionCode()); status = STATUS_NOT_FOUND; } return status; }
// Concatenates meta information such as the current time and a process ID to // user given log message. _Use_decl_annotations_ static NTSTATUS LogpMakePrefix( ULONG level, const char *function_name, const char *log_message, char *log_buffer, SIZE_T log_buffer_length) { char const *level_string = nullptr; switch (level) { case kLogpLevelDebug: level_string = "DBG\t"; break; case kLogpLevelInfo: level_string = "INF\t"; break; case kLogpLevelWarn: level_string = "WRN\t"; break; case kLogpLevelError: level_string = "ERR\t"; break; default: return STATUS_INVALID_PARAMETER; } auto status = STATUS_SUCCESS; char time_buffer[20] = {}; if ((g_logp_debug_flag & kLogOptDisableTime) == 0) { // Want the current time. TIME_FIELDS time_fields; LARGE_INTEGER system_time, local_time; KeQuerySystemTime(&system_time); ExSystemTimeToLocalTime(&system_time, &local_time); RtlTimeToTimeFields(&local_time, &time_fields); status = RtlStringCchPrintfA(time_buffer, RTL_NUMBER_OF(time_buffer), "%02u:%02u:%02u.%03u\t", time_fields.Hour, time_fields.Minute, time_fields.Second, time_fields.Milliseconds); if (!NT_SUCCESS(status)) { return status; } } // Want the function name char function_name_buffer[50] = {}; if ((g_logp_debug_flag & kLogOptDisableFunctionName) == 0) { const auto base_function_name = LogpFindBaseFunctionName(function_name); status = RtlStringCchPrintfA(function_name_buffer, RTL_NUMBER_OF(function_name_buffer), "%-40s\t", base_function_name); if (!NT_SUCCESS(status)) { return status; } } // Want the processor number char processro_number[10] = {}; if ((g_logp_debug_flag & kLogOptDisableProcessorNumber) == 0) { status = RtlStringCchPrintfA(processro_number, RTL_NUMBER_OF(processro_number), "#%lu\t", KeGetCurrentProcessorNumberEx(nullptr)); if (!NT_SUCCESS(status)) { return status; } } // It uses PsGetProcessId(PsGetCurrentProcess()) instead of // PsGetCurrentThreadProcessId() because the later sometimes returns // unwanted value, for example: // PID == 4 but its image name != ntoskrnl.exe // The author is guessing that it is related to attaching processes but // not quite sure. The former way works as expected. status = RtlStringCchPrintfA( log_buffer, log_buffer_length, "%s%s%s%5Iu\t%5Iu\t%-15s\t%s%s\r\n", time_buffer, level_string, processro_number, reinterpret_cast<ULONG_PTR>(PsGetProcessId(PsGetCurrentProcess())), reinterpret_cast<ULONG_PTR>(PsGetCurrentThreadId()), PsGetProcessImageFileName(PsGetCurrentProcess()), function_name_buffer, log_message); return status; }
BOOLEAN InjectDll(PINJECT_INFO InjectInfo) { PEPROCESS Process; PETHREAD Thread; PKINJECT mem; ULONG size; PKAPC_STATE ApcState; PKAPC apc; PVOID buffer; PSYSTEM_PROCESS_INFO pSpi; LARGE_INTEGER delay; buffer=ExAllocatePool(NonPagedPool,1024*1024); // Allocate memory for the system information if(!buffer) { DbgPrint("Error: Unable to allocate memory for the process thread list."); return FALSE; } // Get the process thread list if(!NT_SUCCESS(ZwQuerySystemInformation(5,buffer,1024*1024,NULL))) { DbgPrint("Error: Unable to query process thread list."); ExFreePool(buffer); return FALSE; } pSpi=(PSYSTEM_PROCESS_INFO)buffer; // Find a target thread while(pSpi->NextEntryOffset) { if(pSpi->UniqueProcessId==InjectInfo->ProcessId) { DbgPrint("Target thread found. TID: %d",pSpi->Threads[0].ClientId.UniqueThread); break; } pSpi=(PSYSTEM_PROCESS_INFO)((PUCHAR)pSpi+pSpi->NextEntryOffset); } // Reference the target process if(!NT_SUCCESS(PsLookupProcessByProcessId(InjectInfo->ProcessId,&Process))) { DbgPrint("Error: Unable to reference the target process."); ExFreePool(buffer); return FALSE; } DbgPrint("Process name: %s",PsGetProcessImageFileName(Process)); DbgPrint("EPROCESS address: %#x",Process); // Reference the target thread if(!NT_SUCCESS(PsLookupThreadByThreadId(pSpi->Threads[0].ClientId.UniqueThread,&Thread))) { DbgPrint("Error: Unable to reference the target thread."); ObDereferenceObject(Process); // Dereference the target process ExFreePool(buffer); // Free the allocated memory return FALSE; } DbgPrint("ETHREAD address: %#x",Thread); ExFreePool(buffer); // Free the allocated memory KeAttachProcess(Process); // Attach to target process's address space mem=NULL; size=4096; // Allocate memory in the target process if(!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,0,&size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE))) { DbgPrint("Error: Unable to allocate memory in the target process."); KeDetachProcess(); // Detach from target process's address space ObDereferenceObject(Process); // Dereference the target process ObDereferenceObject(Thread); // Dereference the target thread return FALSE; } DbgPrint("Memory allocated at %#x",mem); mem->LdrLoadDll=LdrLoadDll; // Write the address of LdrLoadDll to target process wcscpy(mem->Buffer,InjectInfo->DllName); // Write the DLL name to target process RtlInitUnicodeString(&mem->DllName,mem->Buffer); // Initialize the UNICODE_STRING structure ApcState=(PKAPC_STATE)((PUCHAR)Thread+ApcStateOffset); // Calculate the address of the ApcState structure ApcState->UserApcPending=TRUE; // Force the target thread to execute APC memcpy((PKINJECT)(mem+1),InjectDllApc,(ULONG)KernelRoutine-(ULONG)InjectDllApc); // Copy the APC code to target process DbgPrint("APC code address: %#x",(PKINJECT)(mem+1)); apc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC)); // Allocate the APC object if(!apc) { DbgPrint("Error: Unable to allocate the APC object."); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory KeDetachProcess(); // Detach from target process's address space ObDereferenceObject(Process); // Dereference the target process ObDereferenceObject(Thread); // Dereference the target thread return FALSE; } KeInitializeApc(apc,Thread,OriginalApcEnvironment,KernelRoutine,NULL,(PKNORMAL_ROUTINE)((PKINJECT)mem+1),UserMode,mem); // Initialize the APC DbgPrint("Inserting APC to target thread"); // Insert the APC to the target thread if(!KeInsertQueueApc(apc,NULL,NULL,IO_NO_INCREMENT)) { DbgPrint("Error: Unable to insert APC to target thread."); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory KeDetachProcess(); // Detach from target process's address space ObDereferenceObject(Process); // Dereference the target process ObDereferenceObject(Thread); // Dereference the target thread ExFreePool(apc); // Free the APC object return FALSE; } delay.QuadPart=-100*10000; while(!mem->Executed) { KeDelayExecutionThread(KernelMode,FALSE,&delay); // Wait for the injection to complete } if(!mem->DllBase) { DbgPrint("Error: Unable to inject DLL into target process."); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); KeDetachProcess(); ObDereferenceObject(Process); ObDereferenceObject(Thread); return FALSE; } DbgPrint("DLL injected at %#x",mem->DllBase); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory KeDetachProcess(); // Detach from target process's address space ObDereferenceObject(Process); // Dereference the target process ObDereferenceObject(Thread); // Dereference the target thread return TRUE; }
BOOLEAN InjectDll(PINJECT_INFO InjectInfo) { PEPROCESS Process; PETHREAD Thread; PKINJECT mem; ULONG size; PKAPC_STATE ApcState; PKAPC apc; PVOID buffer; PSYSTEM_PROCESS_INFO pSpi; LARGE_INTEGER delay; buffer=ExAllocatePool(NonPagedPool,1024*1024); if(!buffer) { DbgPrint("Error: Unable to allocate memory for the process thread list."); return FALSE; } //5 SystemProcessInformation, if(!NT_SUCCESS(ZwQuerySystemInformation(5,buffer,1024*1024,NULL))) { DbgPrint("Error: Unable to query process thread list."); ExFreePool(buffer); return FALSE; } pSpi=(PSYSTEM_PROCESS_INFO)buffer; //找到目标进程 while(pSpi->NextEntryOffset) { if(pSpi->UniqueProcessId==InjectInfo->ProcessId) { DbgPrint("Target thread found. TID: %d",pSpi->Threads[0].ClientId.UniqueThread); break; } pSpi=(PSYSTEM_PROCESS_INFO)((PUCHAR)pSpi+pSpi->NextEntryOffset); } // 引用目标进程EProcess, if(!NT_SUCCESS(PsLookupProcessByProcessId(InjectInfo->ProcessId,&Process))) { DbgPrint("Error: Unable to reference the target process."); ExFreePool(buffer); return FALSE; } DbgPrint("Process name: %s",PsGetProcessImageFileName(Process)); DbgPrint("EPROCESS address: %#x",Process); //目标进程主线程 if(!NT_SUCCESS(PsLookupThreadByThreadId(pSpi->Threads[0].ClientId.UniqueThread,&Thread))) { DbgPrint("Error: Unable to reference the target thread."); ObDereferenceObject(Process); ExFreePool(buffer); return FALSE; } DbgPrint("ETHREAD address: %#x",Thread); ExFreePool(buffer); //切入到目标进程 KeAttachProcess(Process); mem=NULL; size=4096; //在目标进程申请内存 if(!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,0,&size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE))) { DbgPrint("Error: Unable to allocate memory in the target process."); KeDetachProcess(); ObDereferenceObject(Process); ObDereferenceObject(Thread); return FALSE; } DbgPrint("Memory allocated at %#x",mem); mem->LdrLoadDll=LdrLoadDll; wcscpy(mem->Buffer,InjectInfo->DllName); RtlInitUnicodeString(&mem->DllName,mem->Buffer); ApcState=(PKAPC_STATE)((PUCHAR)Thread+ApcStateOffset); ApcState->UserApcPending=TRUE; memcpy((PKINJECT)(mem+1),InjectDllApc,(ULONG)KernelRoutine-(ULONG)InjectDllApc); DbgPrint("APC code address: %#x",(PKINJECT)(mem+1)); //申请apc对象 apc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC)); if(!apc) { DbgPrint("Error: Unable to allocate the APC object."); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); KeDetachProcess(); ObDereferenceObject(Process); ObDereferenceObject(Thread); return FALSE; } KeInitializeApc(apc, Thread, //目标进程主线程 OriginalApcEnvironment, //目标apcz状态 KernelRoutine, //内核apc总入口 NULL, //Rundown Rounine=NULL (PKNORMAL_ROUTINE)((PKINJECT)mem+1), //用户空间的总apc UserMode, //插入到用户apc队列 mem); // 自己的apc队列 DbgPrint("Inserting APC to target thread"); // 插入apc队列 if(!KeInsertQueueApc(apc,NULL,NULL,IO_NO_INCREMENT)) { DbgPrint("Error: Unable to insert APC to target thread."); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); KeDetachProcess(); ObDereferenceObject(Process); ObDereferenceObject(Thread); ExFreePool(apc); return FALSE; } delay.QuadPart=-100*10000; while(!mem->Executed) { KeDelayExecutionThread(KernelMode,FALSE,&delay); //等待apc执行 } if(!mem->DllBase) { DbgPrint("Error: Unable to inject DLL into target process."); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); KeDetachProcess(); ObDereferenceObject(Process); ObDereferenceObject(Thread); return FALSE; } DbgPrint("DLL injected at %#x",mem->DllBase); size=0; ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); ObDereferenceObject(Process); ObDereferenceObject(Thread); return TRUE; }
NTSTATUS kkll_m_process_token(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer) { NTSTATUS status = STATUS_SUCCESS; PMIMIDRV_PROCESS_TOKEN_FROM_TO pTokenFromTo = (PMIMIDRV_PROCESS_TOKEN_FROM_TO) bufferIn; ULONG fromProcessId, toProcessId; HANDLE hFromProcess, hFromProcessToken; PEPROCESS pFromProcess = PsInitialSystemProcess, pToProcess = NULL; if(pTokenFromTo && (szBufferIn == sizeof(MIMIDRV_PROCESS_TOKEN_FROM_TO))) { if(pTokenFromTo->fromProcessId) status = PsLookupProcessByProcessId((HANDLE) pTokenFromTo->fromProcessId, &pFromProcess); if(NT_SUCCESS(status) && pTokenFromTo->toProcessId) status = PsLookupProcessByProcessId((HANDLE) pTokenFromTo->toProcessId, &pToProcess); } if(NT_SUCCESS(status)) { status = ObOpenObjectByPointer(pFromProcess, OBJ_KERNEL_HANDLE, NULL, 0, *PsProcessType, KernelMode, &hFromProcess); if(NT_SUCCESS(status)) { status = ZwOpenProcessTokenEx(hFromProcess, 0, OBJ_KERNEL_HANDLE, &hFromProcessToken); if(NT_SUCCESS(status)) { status = kprintf(outBuffer, L"Token from %u/%-14S\n", PsGetProcessId(pFromProcess), PsGetProcessImageFileName(pFromProcess)); if(NT_SUCCESS(status)) { if(pToProcess) status = kkll_m_process_token_toProcess(szBufferIn, bufferIn, outBuffer, hFromProcessToken, pToProcess); else status = kkll_m_process_enum(szBufferIn, bufferIn, outBuffer, kkll_m_process_systoken_callback, hFromProcessToken); } ZwClose(hFromProcessToken); } ZwClose(hFromProcess); } } if(pToProcess) ObDereferenceObject(pToProcess); if(pFromProcess && (pFromProcess != PsInitialSystemProcess)) ObDereferenceObject(pFromProcess); return status; }