2

I need to hook any function that tries to retrieve the system time in order to generate "time independent" replays for different applications. Some events like pseudorandom number generation depend on calls to time(), but for example some others call timeGetTime() or _time64().

What is the minimum set of functions that I would need to hook (in Windows) to catch all time retrieving functions. Is it actually possible to hook on these functions? I am trying to do it on time(), but my hook is being ignored. I have had success hooking to other functions (like rand) but my time() hook seems to be ignored.

I am using Detours, but I am open to use any other API interception tool.

cloudraven
  • 2,484
  • 1
  • 24
  • 49

3 Answers3

2

For game 'speedhacks', the 3 APIs which are usually hooked are:

Most of these functions return a time since the system started or something similar. In your hook, you need to decide what you want to do. You could:

  1. Always return a static time
  2. Do the common approach for 'slowing down' or 'speeding up' time:
    • When your DLL is injected, take an initial time (say init_time)
    • Each time the target calls your time function, you can call a trampolined version of the real function which gets you a real_time
    • The value you return would be something like init_time + 0.5*(real_time-init_time) which would slow time down by half for example
Mike Kwan
  • 24,123
  • 12
  • 63
  • 96
0

You probably want to hook the time system call. Ugh, I don't know why I'm even suggesting that. But reverse engineering GetSystemTime in kernel32.dll would detail how that system call is made.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
0

The minimum set of (preferably) kernel APIs that you want to hook are NtQuerySystemTime and NtGetTickCount. Kernel hooks are recommended since there's too many user-land apis to hook and you never know whether the application is directly accessing the time data using those two functions.

Of course you should filter out the process by calling PsGetCurrentProcess() and comparing the *(eprocess->UniqueProcessID) with your target process id.

JosephH
  • 8,465
  • 4
  • 34
  • 62