All about Programming

BSOD 0xB8 : ATTEMPTED_SWITCH_FROM_DPC (KeWaitForSingleObject)

민토즈 2019. 6. 19. 17:53
300x250

NTSTATUS KeWaitForSingleObject(
  PVOID                    Object,
  KWAIT_REASON        WaitReason,
  KPROCESSOR_MODE  WaitMode,
  BOOLEAN                Alertable,
  PLARGE_INTEGER       Timeout
);

 

MSDN: Callers of KeWaitForSingleObject must be running at IRQL <= DISPATCH_LEVEL. However, if Timeout = NULL or *Timeout != 0, the caller must be running at IRQL <= APC_LEVEL and in a nonarbitrary thread context. (If Timeout != NULL and *Timeout = 0, the caller must be running at IRQL <= DISPATCH_LEVEL.) 

 

Timeout 값이 0이 아닌 값을 가지면, DISPATCH_LEVEL 보다 낮은 IRQL에서 KeWaitForSingleObject를 호출해야 하지만, DISPATCH_LEVEL에서 KeWaitForSingleObject를 무한 대기 또는 특정 시간 대기를 위해 호출 할 때 BSOD ATTEMPTED_SWITCH_FROM_DPC가 발생.

 

(회피 방법1)

 

//<1> 5초 대기

if(KeReadStateEvent(&Event) == 0)

{

       LARGE_INTEGER Seconds_5;

       Seconds_5.QuadPart = -5 * 10 * 1000 * 1000;

       KeDelayExecutionThread( KernelMode, FALSE, &Seconds_5 );

}

 

//<2> 매 5초 경과 후 이벤트 상태 체크 1분 동안 확인

if(KeReadStateEvent(&Event) == 0)

{

       int  cnts = 0;

 

       do {

            LARGE_INTEGER Seconds_5;

            Seconds_5.QuadPart = -5 * 10 * 1000 * 1000;

            KeDelayExecutionThread( KernelMode, FALSE, &Seconds_5 );

            ++cnts;

       } while(KeReadStateEvent(&Event) == 0 && cnts < 12);

}

     

 

300x250