Almost everyone involved in the reverse engineering knows about the timer checks used for antidebugging. Generally functions such as GetTickCount or KeTickCount are used to detect and prevent any debugging attempts. Recently in the Hackers Reversing Challenge 2007, one of the less known timer checks have been used which makes use of functions QueryPerformanceFrequency & QueryPerformanceCounter.

General idea behind the timer checks is to record the time count at the beginning of important operation and then record at the end of the operation. If the program is being debugged then this time difference will be very much more than the normal execution time. Based on this calculation, it is easy to detect such a debugging activity and terminate or change the behavior of the program.

Here is the sample program which shows how it can be done using functions QueryPerformanceFrequency & QueryPerformanceCounter.

LARGE_INTEGER lpFrequency;
LARGE_INTEGER lpPerfCountOld, lpPerfCountNew;
BOOL isPerfCounterAvailable = FALSE;


// Record the initial performance counter value
if( QueryPerformanceFrequency(&lpFrequency) == TRUE )
if( QueryPerformanceCounter(&lpPerfCountOld) == TRUE )
isPerfCounterAvailable = TRUE;


// Do some important operation
for(int i=0; i<1000; i++)


// Now get the latest performance counter value….
if( isPerfCounterAvailable && QueryPerformanceCounter(&lpPerfCountNew) )
if( (lpPerfCountNew.QuadPart-lpPerfCountOld.QuadPart) > NORMAL_COUNTER_VALUE )
printf(“\n Program is being DEBUGGED”);
printf(“\n No debugging activity is detected”);


As per MSDN, if the installed hardware does not support high-resolution performance counter, then QueryPerformanceFrequency returns FALSE. In that case one has to fall back to traditional GetTickCount function as done in the Hacker challenge program.

Defeating such a trick is not difficult. Patching the QueryPerformanceFrequency function to return FALSE will solve the problem. However there is possibility that program may directly use QueryPerformanceCounter function which can be circumvented by patching it to return zero as shown in the following Ollyscript.

// patch the QueryPerformanceFrequency to return FALSE
gpa “QueryPerformanceFrequency”, “kernel32.dll”
mov [$RESULT], #33C0C20400#

// patch the “QueryPerformanceCounter to return zero
gpa “QueryPerformanceCounter”, “kernel32.dll”
mov [$RESULT], #33C0C20400#


Happy r3v3rsing