Time hooking: STATUS_NOT_SUPPORTED + cant get Thread ID for SetExclusiveACL

Aug 27, 2010 at 9:28 AM
Edited Aug 27, 2010 at 9:40 AM

Im writing managed C# application, which contains WebBrowser Component (WebComponent seems to be wrapper to unmanaged IE core).
Now im trying to do LocalHook (not remote) for my own application for these functions:

[DllImport("kernel32.dll")]
static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
static extern int GetTickCount();
[DllImport("Winmm.dll")]
static extern int timeGetTime();
[DllImport("ntdll.dll")]
static extern ulong NtGetTickCount();

Problem:
LocalHook reports STATUS_NOT_SUPPORTED for GetTickCount and timeGetTime,
so i have tried to hook NtGetTickCount but this returns STATUS_NOT_SUPPORTED too.
Notice all these functions don't take any parameter.
Only hooking QueryPerformanceCounter works, but when i hook QueryPerformanceCounter
i get strange behaviour of my application, may be due to desnchronization of threads/components
because some of them use hooked QueryPerformanceCounter and other use unhooked time functions, im not sure yet.

QueryPerformanceCounter hook only works if i use ThreadACL.SetExclusiveACL(new Int32[0]);

If i try to pass ManagedThreadId to SetExclusiveACL, Model Driven Architecture (MDA) throws immediately
"Reentrancy was detected" as soon as the thread with this ManagedThreadId tries to Invoke any Component of my Form.

If i try to use
IntPtr FlashHandle = SearchClassName(Browser.Handle, "MacromediaFlashPlayerActiveX");
int id = LocalHook.GetThreadIdByHandle(FlashHandle);
or
int id = LocalHook.GetThreadIdByHandle(Browser.Handle);
GetThreadIdByHandle throws STATUS_INVALID_PARAMETER_1.

Now i'm stuck and need your help...

Ideally i would like to only hook IE Core wrapped by BrowserComponent, bu i cang get usable ThreadID for that one.


=============================================================
These are significant parts of my code related to this topic:
=============================================================

[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
static extern int GetTickCount();

[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
delegate int DGetTickCount();

public static int StoredTime = 0;
public static int StoredTickCount = 0;
public static double SpeedUp = 2.0;

static int MyGetTickCount()
{
     int TickCount = timeGetTime();
     int RealTime = GetTickCount();

     if (StoredTime == 0) // Initialize
     {
         StoredTime = RealTime;
         StoredTickCount = TickCount;
         File.AppendAllText("Log.txt", "StoredTime: " + StoredTime.ToString() + Environment.NewLine);
     }

     int FakeTime = StoredTime + (int)((RealTime - StoredTime) * SpeedUp);
     return FakeTime;
}

public LocalHook GetTickCountHook = null;

private void Hook_GetTickCount()
{
    GetTickCountHook = LocalHook.Create(
        LocalHook.GetProcAddress("kernel32.dll", "GetTickCount"),
        new DGetTickCount(MyGetTickCount),
        this);
    GetTickCountHook.ThreadACL.SetExclusiveACL(new Int32[0]);
}

private void Hook_GetTickCount(int ThreadID)
{
    GetTickCountHook = LocalHook.Create(
        LocalHook.GetProcAddress("kernel32.dll", "GetTickCount"),
        new DGetTickCount(MyGetTickCount),
        this);
    GetTickCountHook.ThreadACL.SetExclusiveACL(new Int32[] { ThreadID });
}

private void MyButton_Click(object sender, EventArgs e)
{
    Thread T = new Thread(TestHook);
    T.IsBackground = true;
    T.Start();
    int NewThreadManagedID = T.ManagedThreadId;

    IntPtr FlashHandle = SearchClassName(Browser.Handle, "MacromediaFlashPlayerActiveX");
    int FlashThreadID = LocalHook.GetThreadIdByHandle(FlashHandle ); // throws STATUS_INVALID_PARAMETER_1
    // hooking other time funtions in similar way
    Hook_QueryPerformanceCounter(NewThreadManagedID); // Model Driven Architecture (MDA) throws "Reentrancy detected" as soon as thread T invokes Form components.
    Hook_QueryPerformanceCounter(FlashThreadID); // doesn't work, GetThreadIdByHandle cant't get usable ThreadID for this one
    Hook_QueryPerformanceCounter(); // work only for QueryPerformanceCounter and only if i hook all local threads, but unexpected behaivour, still investigating...

    if (QueryPerformanceCounterHook.IsThreadIntercepted(Thread.CurrentThread.ManagedThreadId)) // Model Driven Architecture (MDA) throws "Reentrancy detected"
      log("this thread was intercepted by hook");
}