Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to speed up/slow down application's 'time'

Tags:

time

macos

I guess I am not saying it right in the title. What I intend to do is to hook to some system api,like a time interrupt happens every amount of time (which is how every application in the operating system interprets time) and make an application's call to this api return some bigger/smaller result. So from the point view of an applicaiton, time has been speed up or slow down. I have found some application on windows doing this, can anyone gives me some pointers on how to implement this on Mac OS X?

like image 558
overboming Avatar asked Mar 30 '10 03:03

overboming


2 Answers

Your question has to be split into two parts:

  1. Which is the source of time values that many applications use?
  2. How do I intercept this source?

The answer to 1) is (roughly in the order of importance):

  • The system clock, read by gettimeofday (which, in turn, is used by NSDate, CFAbsoluteTime, ...)
  • An Audio card's clock. Many multimedia applications synchronize visuals to audio and use the audio as the driving source of time.
  • The Video clock (counting vsyncs)
  • Processor tick counters, interrupts, etc.
  • Just the advancement of the program counter (speed of execution).

Edit:

  • The mach timing functions. Thanks, @tc, for pointing that out.

Intercepting gettimeofday is relatively easy: Just build a dynamic library containing a function with the same name and signature as the original gettimeofday (see #include <sys/time.h>). This function should return whatever value you want for the time.

To use this special gettimeofday function in an application, start it on the Terminal as in:

DYLD_INSERT_LIBRARIES=/path/to/myGetTimeOfDay.dylib /Applications/TextEdit.app/Contents/MacOS/TextEdit

Of course your dylib has to match the applications architecture.

like image 95
Nikolai Ruhe Avatar answered Oct 13 '22 00:10

Nikolai Ruhe


I'm not a OS X developer so I can't give you specifics. But I know Windows, and can have a guess at how this might be implemented - you may be able to convert some of the techniques.

For illustration, let's assume most programs that want to follow the abstract passage of time on Windows use GetTickCount. This returns the number of milliseconds since the system was started. (There are other APIs an application could use, but the technique remains the same.)

To change the time as it appears for an application, the values returned from this time function need to be changed. (e.g. multiplied by a factor) so we create a wrapper function to apply the transformation:

  DWORD GetTimeWarpTickCount()
  {
      static double factor = 2.0;
      return (DWORD)(GetTickCount()*factor);
      // simple implementation - you can be more sophisticated than this 
      // to preserve accuracy if necessary
  }

Once you've coded up the function, use hooking to replace the original Win32 function with your own. Hooking can be done on a per-application basis, so you can localize time changes to specific applications.

So, in short, if there is a way of overriding the basic time functions provided to applications by OS X, then you can apply the same procedure.

like image 35
mdma Avatar answered Oct 12 '22 23:10

mdma