NTSTATUS DllInject(HANDLE hProcessID, PEPROCESS pepProcess, PKTHREAD pktThread) { HANDLE hProcess; OBJECT_ATTRIBUTES oaAttributes={sizeof(OBJECT_ATTRIBUTES)}; CLIENT_ID cidProcess; PVOID pvMemory = 0; DWORD dwSize = 0x1000; cidProcess.UniqueProcess = hProcessID; cidProcess.UniqueThread = 0; if (NT_SUCCESS(ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &oaAttributes, &cidProcess))) { if (NT_SUCCESS(ZwAllocateVirtualMemory(hProcess, &pvMemory, 0, &dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE))) { KAPC_STATE kasState; PKAPC pkaApc; PVOID FunctionAddress; KeStackAttachProcess((PKPROCESS)pepProcess, &kasState); FunctionAddress = GetProcAddressInModule(L"kernel32.dll", "LoadLibraryExW"); if (!FunctionAddress) DbgPrint("GetProcAddressInModule error\n"); wcscpy((PWCHAR)pvMemory, g_wcDllName); KeUnstackDetachProcess(&kasState); pkaApc = (PKAPC)ExAllocatePool(NonPagedPool, sizeof(KAPC)); if (pkaApc) { KeInitializeApc(pkaApc, pktThread, 0, APCKernelRoutine, 0, (PKNORMAL_ROUTINE)FunctionAddress, UserMode, pvMemory); KeInsertQueueApc(pkaApc, 0, 0, IO_NO_INCREMENT); return STATUS_SUCCESS; } } else { DbgPrint("ZwAllocateVirtualMemory error\n"); } ZwClose(hProcess); } else { DbgPrint("ZwOpenProcess error\n"); } return STATUS_NO_MEMORY; }
/******************************************************************************* * * 函 数 名 : CreateProcessNotifyRoutine * 功能描述 : 判断创建的进程是否为拒绝运行程序,是的话结束 * 参数列表 : * 说 明 : 通过PID取得EPROCESS对象,再从里面取名字判断是否为拒绝运行的 * 程序,是的话再通过PID打开进程,结束进程 * 返回结果 : 无 * *******************************************************************************/ VOID CreateProcessNotifyRoutine (IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create ) { PEPROCESS pEProcess = NULL ; OBJECT_ATTRIBUTES ObjectAttributes; CLIENT_ID clientid; HANDLE handle ; return ; // 进程创建 if (Create) { if (0 != ProcessId) { if(NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &pEProcess))) { ObDereferenceObject(pEProcess) ; // 这里可以再比一下进程名 InitializeObjectAttributes(&ObjectAttributes, 0 ,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0); clientid.UniqueProcess = (HANDLE)ParentId; clientid.UniqueThread=0; if(NT_SUCCESS(ZwOpenProcess(&handle, PROCESS_ALL_ACCESS, &ObjectAttributes, &clientid))) { ZwTerminateProcess(handle, 0) ; } } } } // 程序退出 else { } }
NTSTATUS OpenProcess(HANDLE ProcessId, PHANDLE hProcess) { CLIENT_ID ClientId; ClientId.UniqueProcess = ProcessId; ClientId.UniqueThread = 0; OBJECT_ATTRIBUTES ObjectAttributes; InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); return ZwOpenProcess(hProcess, PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId); }
// Open a process handle. A caller must free a returned handle with ZwClose() _Use_decl_annotations_ static HANDLE EopmonpOpenProcess(HANDLE pid) { PAGED_CODE(); OBJECT_ATTRIBUTES oa = {}; InitializeObjectAttributes( &oa, nullptr, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, nullptr, nullptr); CLIENT_ID client_id = {pid, 0}; HANDLE process_handle = nullptr; auto status = ZwOpenProcess(&process_handle, PROCESS_ALL_ACCESS, &oa, &client_id); if (!NT_SUCCESS(status)) { return nullptr; } return process_handle; }
void fasttrap_winsig(pid_t pid, uintptr_t addr) { CLIENT_ID cid1 = {(HANDLE) pid, 0}; OBJECT_ATTRIBUTES attr; HANDLE hProcess = 0; NTSTATUS status; UNREFERENCED_PARAMETER(addr); InitializeObjectAttributes(&attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &attr, &cid1); if (status == STATUS_SUCCESS) { status = ZwTerminateProcess(hProcess, 0); ZwClose(hProcess); } }
// //InteceptProcess is callback notify routine that be set by //PsSetLoadImageNotifyRoutine kernel function // VOID InterceptProcess( IN PUNICODE_STRING FullImageName, IN HANDLE ProcessId, // where image is mapped IN PIMAGE_INFO ImageInfo ) { NTSTATUS ntStatus; OBJECT_ATTRIBUTES objAttr; CLIENT_ID ClientId = {0}; HANDLE hCurProcess; ClientId.UniqueProcess = ProcessId; InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL); ntStatus = ZwOpenProcess(&hCurProcess, PROCESS_ALL_ACCESS, &objAttr, &ClientId); if (NT_SUCCESS(ntStatus)) { PROCESS_BASIC_INFORMATION PBICurProc = {0}; ULONG ulRtn; // NtQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcInfo, sizeof (ProcInfo), &ulRtn); ntStatus = NtQueryInformationProcess(hCurProcess, ProcessBasicInformation, &PBICurProc, sizeof (PBICurProc), &ulRtn); KdPrint(("LoadImageNotify: NtQueryInformation ERROR CODE: 0x%08x\n", ntStatus)); if (NT_SUCCESS(ntStatus)) { PEPROCESS pEParent; KdPrint(("LoadImageNotify: NtQueryInformationProcess Successfully!\n")); ntStatus = PsLookupProcessByProcessId((HANDLE)PBICurProc.InheritedFromUniqueProcessId, &pEParent); if (NT_SUCCESS(ntStatus)) { if (IsInterceptionProcess(pEParent)) { KdPrint(("This Process's parent process is TENCENT IM\n")); ZwTerminateProcess(hCurProcess, 0); } ObDereferenceObject(pEParent); } } ZwClose(hCurProcess); } }
// get ptr to an EPROCESS struct from the name (i.m.weasel) NTSTATUS GetEProcessByName(WCHAR *processname, PEPROCESS *proc) { NTSTATUS status; PSYSTEM_PROCESS_INFORMATION info, curr; ULONG info_size = PAGE_SIZE, result_size; ULONG ProcessId = 0; CLIENT_ID ClientId; OBJECT_ATTRIBUTES ObjectAttributes; PVOID Object; ULONG length; HANDLE Services_process; *proc = NULL; while(TRUE) { info = ExAllocatePool (NonPagedPool, info_size); if (info == NULL) return STATUS_NO_MEMORY; status = ZwQuerySystemInformation ( 5, // process request info, info_size, &result_size); if( NT_SUCCESS(status) ) break; ExFreePool(info); if( status != STATUS_INFO_LENGTH_MISMATCH ) return STATUS_NO_MEMORY; // otherwise, we need to allocate more memory info = NULL; info_size += PAGE_SIZE; } length = wcslen(processname); curr = info; do { if((curr->ProcessName.Length == (length * sizeof (WCHAR))) && !memcmp(processname, curr->ProcessName.Buffer, curr->ProcessName.Length)) { // it's our services.exe ProcessId = curr->ProcessId; break; } if(curr->NextEntryDelta) (PBYTE)curr += (curr->NextEntryDelta); } while(curr->NextEntryDelta); ExFreePool(info); if (!ProcessId) return STATUS_NOT_FOUND; InitializeObjectAttributes( &ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0); ClientId.UniqueProcess = (HANDLE)ProcessId; ClientId.UniqueThread = 0; status = ZwOpenProcess( &Services_process, PROCESS_ALL_ACCESS, &ObjectAttributes, &ClientId); if ( !NT_SUCCESS(status) ) return status; status = ObReferenceObjectByHandle ( Services_process, PROCESS_ALL_ACCESS, NULL, KernelMode, &Object, NULL); ZwClose (Services_process); if (!NT_SUCCESS(status)) return status; *proc = (PEPROCESS)Object; return STATUS_SUCCESS; }
/////////////////////////////////////////////////////////////////////////////////// // // 功能实现:枚举Csrss.exe进程PID // 输入参数:无 // 输出参数:返回Csrss.exe进程的PID // /////////////////////////////////////////////////////////////////////////////////// HANDLE GetCsrssPid() { NTSTATUS ntStatus; HANDLE hProc, hObject; HANDLE CsrssPid = (HANDLE)0; OBJECT_ATTRIBUTES objAttr; CLIENT_ID cid; int i; UNICODE_STRING ApiPortName; POBJECT_NAME_INFORMATION ObjName; PSYSTEM_HANDLE_INFORMATION_EX Handles; RtlInitUnicodeString( &ApiPortName, L"\\Windows\\ApiPort" ); //获取句柄信息 Handles = GetInfoTable( SystemHandleInformation ); if( Handles == NULL ) { DbgPrint("[GetCsrssPid]->GetInfoTable() Error\n"); return 0; } ObjName = ExAllocatePool( PagedPool, 0x2000 ); for( i = 0; i != Handles->NumberOfHandles; i++ ) { if ( Handles->Information[i].ObjectTypeNumber == 21 ) //Port object,Win2kSP1下找不到21端口 { InitializeObjectAttributes( &objAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL ); cid.UniqueProcess = (HANDLE)Handles->Information[i].ProcessId; cid.UniqueThread = 0; //打开进程 ntStatus = ZwOpenProcess( &hProc, PROCESS_DUP_HANDLE, &objAttr, &cid ); if( NT_SUCCESS(ntStatus) ) { //复制句柄 ntStatus = ZwDuplicateObject( hProc, (HANDLE)Handles->Information[i].Handle, NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS ); if( NT_SUCCESS(ntStatus) ) { //查询对象 ntStatus = ZwQueryObject( hObject, ObjectNameInformation, ObjName, 0x2000, NULL); if( NT_SUCCESS(ntStatus) ) { if (ObjName->Name.Buffer != NULL) { if ( wcsncmp( ApiPortName.Buffer, ObjName->Name.Buffer, 20 ) == 0 ) { //获取Csrss.exe进程Pid CsrssPid = (HANDLE)Handles->Information[i].ProcessId; ZwClose( hProc ); ZwClose( hObject ); IxExFreePool( Handles ); IxExFreePool( ObjName ); return CsrssPid; } } } else DbgPrint("Error in Query Object\n"); ZwClose(hObject); } else DbgPrint("Error on duplicating object\n"); ZwClose(hProc); } else DbgPrint("Could not open process\n"); } } IxExFreePool( Handles ); IxExFreePool( ObjName ); return 0; }
BOOLEAN SepRmCommandServerThreadInit( VOID ) /*++ Routine Description: This function performs initialization of the Reference Monitor Server thread. The following steps are performed. o Wait on the LSA signalling the event. When the event is signalled, the LSA has already created the LSA Command Server LPC Port o Close the LSA Init Event Handle. The event is not used again. o Listen for the LSA to connect to the Port o Accept the connection. o Connect to the LSA Command Server LPC Port Arguments: None. Return Value: --*/ { NTSTATUS Status; UNICODE_STRING LsaCommandPortName; PORT_MESSAGE ConnectionRequest; SECURITY_QUALITY_OF_SERVICE DynamicQos; OBJECT_ATTRIBUTES ObjectAttributes; PORT_VIEW ClientView; REMOTE_PORT_VIEW LsaClientView; BOOLEAN BooleanStatus = TRUE; PAGED_CODE(); // // Save a pointer to our process so we can get back into this process // to send commands to the LSA (using a handle to an LPC port created // below). // SepRmLsaCallProcess = PsGetCurrentProcess(); ObReferenceObject(SepRmLsaCallProcess); // // Wait on the LSA signalling the event. This means that the LSA // has created its command port, not that LSA initialization is // complete. // Status = ZwWaitForSingleObject( SepRmState.LsaInitEventHandle, FALSE, NULL); if ( !NT_SUCCESS(Status) ) { KdPrint(("Security Rm Init: Waiting for LSA Init Event failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Close the LSA Init Event Handle. The event is not used again. // ZwClose(SepRmState.LsaInitEventHandle); // // Listen for a connection to be made by the LSA to the Reference Monitor // Command Port. This connection will be made by the LSA process. // ConnectionRequest.u1.s1.TotalLength = sizeof(ConnectionRequest); ConnectionRequest.u1.s1.DataLength = (CSHORT)0; Status = ZwListenPort( SepRmState.RmCommandPortHandle, &ConnectionRequest ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Listen to Command Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Obtain a handle to the LSA process for use when auditing. // InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL ); Status = ZwOpenProcess( &SepLsaHandle, PROCESS_VM_OPERATION | PROCESS_VM_WRITE, &ObjectAttributes, &ConnectionRequest.ClientId ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Open Listen to Command Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Accept the connection made by the LSA process. // LsaClientView.Length = sizeof(LsaClientView); Status = ZwAcceptConnectPort( &SepRmState.RmCommandPortHandle, NULL, &ConnectionRequest, TRUE, NULL, &LsaClientView ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Accept Connect to Command Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Complete the connection. // Status = ZwCompleteConnectPort(SepRmState.RmCommandPortHandle); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Complete Connect to Command Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Set up the security quality of service parameters to use over the // Lsa Command LPC port. Use the most efficient (least overhead) - which // is dynamic rather than static tracking. // DynamicQos.ImpersonationLevel = SecurityImpersonation; DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; DynamicQos.EffectiveOnly = TRUE; // // Create the section to be used as unnamed shared memory for // communication between the RM and LSA. // SepRmState.LsaCommandPortSectionSize.LowPart = PAGE_SIZE; SepRmState.LsaCommandPortSectionSize.HighPart = 0; Status = ZwCreateSection( &SepRmState.LsaCommandPortSectionHandle, SECTION_ALL_ACCESS, NULL, // ObjectAttributes &SepRmState.LsaCommandPortSectionSize, PAGE_READWRITE, SEC_COMMIT, NULL // FileHandle ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Create Memory Section for LSA port failed: %X\n", Status)); goto RmCommandServerThreadInitError; } // // Set up for a call to NtConnectPort and connect to the LSA port. // This setup includes a description of the port memory section so that // the LPC connection logic can make the section visible to both the // client and server processes. // ClientView.Length = sizeof(ClientView); ClientView.SectionHandle = SepRmState.LsaCommandPortSectionHandle; ClientView.SectionOffset = 0; ClientView.ViewSize = SepRmState.LsaCommandPortSectionSize.LowPart; ClientView.ViewBase = 0; ClientView.ViewRemoteBase = 0; // // Set up the security quality of service parameters to use over the // port. Use dynamic tracking so that XACTSRV will impersonate the // user that we are impersonating when we call NtRequestWaitReplyPort. // If we used static tracking, XACTSRV would impersonate the context // when the connection is made. // DynamicQos.ImpersonationLevel = SecurityImpersonation; DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; DynamicQos.EffectiveOnly = TRUE; // // Connect to the Lsa Command LPC Port. This port is used to send // commands from the RM to the LSA. // RtlInitUnicodeString( &LsaCommandPortName, L"\\SeLsaCommandPort" ); Status = ZwConnectPort( &SepRmState.LsaCommandPortHandle, &LsaCommandPortName, &DynamicQos, &ClientView, NULL, // ServerView NULL, // MaxMessageLength NULL, // ConnectionInformation NULL // ConnectionInformationLength ); if (!NT_SUCCESS(Status)) { KdPrint(("Security Rm Init: Connect to LSA Port failed 0x%lx\n", Status)); goto RmCommandServerThreadInitError; } // // Store information about the section so that we can create pointers // meaningful to LSA. // SepRmState.RmViewPortMemory = ClientView.ViewBase; SepRmState.LsaCommandPortMemoryDelta = (LONG)((ULONG_PTR)ClientView.ViewRemoteBase - (ULONG_PTR) ClientView.ViewBase ); SepRmState.LsaViewPortMemory = ClientView.ViewRemoteBase; /* BugWarning - ScottBi - probably don't need the resource // // Create the resource serializing access to the port. This // resource prevents the port and the shared memory from being // deleted while worker threads are processing requests. // if ( !SepRmState.LsaCommandPortResourceInitialized ) { ExInitializeResource( &SepRmState.LsaCommandPortResource ); SepRmState.LsaCommandPortResourceInitialized = TRUE; } SepRmState.LsaCommandPortActive = TRUE; */ RmCommandServerThreadInitFinish: // // Dont need this section handle any more, even if returning // success. // if ( SepRmState.LsaCommandPortSectionHandle != NULL ) { NtClose( SepRmState.LsaCommandPortSectionHandle ); SepRmState.LsaCommandPortSectionHandle = NULL; } // // The Reference Monitor Thread has successfully initialized. // return BooleanStatus; RmCommandServerThreadInitError: if ( SepRmState.LsaCommandPortHandle != NULL ) { NtClose( SepRmState.LsaCommandPortHandle ); SepRmState.LsaCommandPortHandle = NULL; } BooleanStatus = FALSE; goto RmCommandServerThreadInitFinish; }
NTSTATUS ZwCreateSectionHook(HANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle) { if (/*(DesiredAccess & SECTION_MAP_EXECUTE) && */(AllocationAttributes & SEC_IMAGE) && (SectionPageProtection & PAGE_EXECUTE)) { PEPROCESS pEParent = NULL; PROCESS_BASIC_INFORMATION ProcInfo = {0}; NTSTATUS ntStatus = 0; ULONG ulRtn; HANDLE hProcess; CLIENT_ID ProcID = {0}; OBJECT_ATTRIBUTES objAttr; ProcID.UniqueProcess = PsGetCurrentProcessId(); InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL); ntStatus = ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &objAttr, &ProcID); if (NT_SUCCESS(ntStatus)) ntStatus = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcInfo, sizeof (ProcInfo), &ulRtn); if (NT_SUCCESS(ntStatus)) { if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)ProcInfo.InheritedFromUniqueProcessId, &pEParent))) { if (IsInterceptionProcess(pEParent)) { //_asm int 3; //KdPrint(("ZwCreateSection Found!!!\n")); // //Update information of pwsCrtProcessEvent // if (pwsCrtProcessEvent == NULL) { pwsCrtProcessEvent = ExAllocatePoolWithTag(PagedPool, (MAX_PATH + 1) * sizeof (wchar_t), 'CP'); if (pwsCrtProcessEvent) { PEPROCESS pEProcess = PsGetCurrentProcess(); PSTR pchParentName = (PSTR)((ULONG_PTR)pEParent + ulProcNameOffset), pchProcessName = (PSTR)((ULONG_PTR)pEProcess + ulProcNameOffset); ANSI_STRING AnsiParentName, AnsiProcessName; UNICODE_STRING uniParentName, uniProcessName; ULONG ulPos = 0; //_asm int 3; RtlZeroMemory(pwsCrtProcessEvent, (MAX_PATH + 1) * sizeof (wchar_t)); RtlInitAnsiString(&AnsiParentName, pchParentName); RtlInitAnsiString(&AnsiProcessName, pchProcessName); RtlAnsiStringToUnicodeString(&uniParentName, &AnsiParentName, TRUE); RtlAnsiStringToUnicodeString(&uniProcessName, &AnsiProcessName, TRUE); RtlStringCchPrintfW(pwsCrtProcessEvent, MAX_PATH, L"%ws;CP;%ws[PID: %ld];TRUE;", uniParentName.Buffer, uniProcessName.Buffer, (ULONG)PsGetCurrentProcessId()); RtlFreeUnicodeString(&uniProcessName); RtlFreeUnicodeString(&uniParentName); if (pKEvtSync[QD_SYNC_EVENTNAME_CRTPROC]) { KeSetEvent(pKEvtSync[QD_SYNC_EVENTNAME_CRTPROC], IO_NO_INCREMENT, FALSE); } KdPrint(("%S\n", pwsCrtProcessEvent)); } } ObDereferenceObject(pEParent); ZwTerminateProcess(hProcess, 0); ZwClose(hProcess); //KdPrint(("ZwCreateSection Found return.\n")); return(0); } ObDereferenceObject(pEParent); } } ZwClose(hProcess); } return(ZwCreateSectionReal(SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle)); }
DualErr DuplicateProcessToken(PGPUInt32 procId, PHANDLE pDupedToken) { CLIENT_ID clientId; DualErr derr; HANDLE procHandle, token; NTSTATUS status; OBJECT_ATTRIBUTES objAttribs; PGPBoolean openedProcess, openedToken; openedProcess = openedToken = FALSE; pgpAssertAddrValid(pDupedToken, HANDLE); InitializeObjectAttributes(&objAttribs, NULL, 0, NULL, NULL); clientId.UniqueThread = NULL; clientId.UniqueProcess = (PVOID) procId; // Open a handle to the process. status = ZwOpenProcess(&procHandle, PROCESS_ALL_ACCESS, &objAttribs, &clientId); if (!NT_SUCCESS(status)) { derr = DualErr(kPGDMinorError_ZwOpenProcessFailed, status); } openedProcess = derr.IsntError(); // Open a handle to the process token. if (derr.IsntError()) { status = ZwOpenProcessToken(procHandle, TOKEN_ALL_ACCESS, &token); if (!NT_SUCCESS(status)) { derr = DualErr(kPGDMinorError_ZwOpenProcessTokenFailed, status); } openedToken = derr.IsntError(); } // Duplicate the token. if (derr.IsntError()) { SECURITY_QUALITY_OF_SERVICE SQOS; SQOS.Length = sizeof(SQOS); SQOS.ImpersonationLevel = SecurityImpersonation; SQOS.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SQOS.EffectiveOnly = FALSE; objAttribs.SecurityQualityOfService = (PVOID) &SQOS; status = ZwDuplicateToken(token, TOKEN_QUERY | TOKEN_IMPERSONATE, &objAttribs, SecurityAnonymous, TokenImpersonation, pDupedToken); if (!NT_SUCCESS(status)) { derr = DualErr(kPGDMinorError_ZwDuplicateTokenFailed, status); } } if (openedToken) ZwClose(token); if (openedProcess) ZwClose(procHandle); return derr; }
//获取csrss.exe进程 NTSTATUS GetCsrssPid(HANDLE *CsrssPid) { NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; HANDLE Process, hObject; ULONG CsrId = 0; OBJECT_ATTRIBUTES obj; CLIENT_ID cid; POBJECT_NAME_INFORMATION ObjName; UNICODE_STRING ApiPortName; PSYSTEM_HANDLE_INFORMATION_EX Handles; ULONG i; PAGED_CODE(); RtlInitUnicodeString(&ApiPortName, L"\\Windows\\ApiPort"); Handles = (PSYSTEM_HANDLE_INFORMATION_EX)GetInfoTable( SystemHandleInformation ); if( Handles == NULL ) { return STATUS_INSUFFICIENT_RESOURCES; } ObjName = (POBJECT_NAME_INFORMATION)ExAllocatePoolWithTag( PagedPool, 0x2000, INFO_MEM_TAG); KdPrint(("SYS: Number of handles %d\n", Handles->NumberOfHandles)); for(i = 0; i < Handles->NumberOfHandles; i++) { //打开的对象的类型是否为21 Port object if (Handles->Information[i].ObjectTypeNumber == 21) { InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); cid.UniqueProcess = (HANDLE)Handles->Information[i].ProcessId; cid.UniqueThread = 0; ntStatus = ZwOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid); if(NT_SUCCESS(ntStatus)) { ntStatus = ZwDuplicateObject( Process, (HANDLE)Handles->Information[i].Handle, NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS); if(NT_SUCCESS(ntStatus)){ ntStatus = ZwQueryObject(hObject, (OBJECT_INFORMATION_CLASS)ObjectNameInformation, ObjName, 0x2000, NULL); if(NT_SUCCESS(ntStatus)) { if (ObjName->Name.Buffer != NULL) { if (RtlCompareUnicodeString(&ApiPortName, &ObjName->Name, TRUE) == 0) { KdPrint(("SYS: Csrss PID:%d\n", Handles->Information[i].ProcessId)); KdPrint(("SYS: Csrss Port - %wZ\n", &ObjName->Name)); CsrId = Handles->Information[i].ProcessId; } } } else { KdPrint(("SYS: Error in Query Object\n")); } ZwClose(hObject); } else { KdPrint(("SYS: Error on duplicating object\n")); } ZwClose(Process); } else { KdPrint(("SYS: Could not open process\n")); } } } ExFreePoolWithTag( Handles, INFO_MEM_TAG); ExFreePoolWithTag(ObjName, INFO_MEM_TAG); *CsrssPid = (HANDLE)CsrId; return ntStatus; }
DWORD ShareLockKImp::Lock(DWORD dwMilliseconds) { switch(m_LockType) { case LockTypeMutex: { LARGE_INTEGER li; li.QuadPart = dwMilliseconds; return KeWaitForSingleObject(&m_LockObject.m_Mutex.m_Mutex, Executive, KernelMode, FALSE, &li); } break; case LockTypeEvent: { LARGE_INTEGER li; li.QuadPart = dwMilliseconds; return KeWaitForSingleObject(&m_LockObject.m_Event.m_Event, Executive, KernelMode, FALSE, &li); } break; case LockTypeSemaphore: { LARGE_INTEGER li; li.QuadPart = dwMilliseconds; return KeWaitForSingleObject(&m_LockObject.m_Semaphore.m_Semaphore, Executive, KernelMode, FALSE, &li); } break; case LockTypeSpinlock: break; case LockTypeNamedSpinlock: { if (m_LockObject.m_NamedSpinlock.m_lpHeader) { LONG err; err = 0; while(1) { LONG pid; pid = m_LockObject.m_NamedSpinlock.m_lpHeader->m_LockProcId; if (pid) { err++; if (err > MAX_ERR) { err = 0; NTSTATUS status; HANDLE proc; OBJECT_ATTRIBUTES objattr; InitializeObjectAttributes(&objattr, NULL, 0, NULL, NULL); CLIENT_ID cid; cid.UniqueProcess = (HANDLE)pid; cid.UniqueThread = NULL; status = ZwOpenProcess(&proc, SYNCHRONIZE, &objattr, &cid); if (status != STATUS_SUCCESS) { if (InterlockedCompareExchange(&m_LockObject.m_NamedSpinlock.m_lpHeader->m_LockProcId, (LONG)PsGetCurrentProcessId(), pid) == pid) break; } else ZwClose(proc); } _mm_pause(); } else if (InterlockedCompareExchange(&m_LockObject.m_NamedSpinlock.m_lpHeader->m_LockProcId, (LONG)PsGetCurrentProcessId(), pid) == pid) break; } return STATUS_SUCCESS; } } break; default: break; } return (DWORD)STATUS_UNSUCCESSFUL; }