[Disclaim: It’s evil, don’t use it unless you are fighting with some even more evil software.]

Short Intro. [Skip it if you don’t know much about OS or aren’t interested in the technical detail ]

As you might know, every program on Linux system runs on the kernel instead of directly contacting with actual machine. For modern operation systems like Linux, BSD(Mac) and Windows, a mechanism called system call is used to request the system resources via operation system so that operation system has the full control of all programs. In brief, when user program need call a function in library, e.g. print in stdlib, library function forwards (usually library function is a light-weighed wrap of the system call) the request to operation system. Since the system is highly hierarchical and user program is built on the top of libraries and OS kernel, it’s possible to insert some layers in between program and OS to intercept the request. Don’t panic about the nerdy name. Actually this strategy is commonly used on Window platform in anti-virus software as well, because anti-virus software want to monitor every system resource usage for any program and prevent the malicious resource requests.

Here, we simply want to intercept a system call named “TIME” so that every time a program request the current time (so that it can verify whether the licence has expired), we feed the program with a fixed (fake) time. By fooling the program around, you can literally use a program forever. God, doesn’t this mean I can use all software forever? The bad news is for some OSs like Windows, it’s very hard to do system call interception as all the APIs are undocumented and software might have other ways to prevent this. The good news is lots of software on Linux and Mac are simply reading system time. Actually, only top developers and Microsoft partners know how to do system interception. However, for Linux, since the system itself is open source from bottom up, there is no way to prevent such kind of interception (Now you know why some software companies don’t like Linux :).

Approach 

On Linux, tons of methods are around. Here I just introduce three of them briefly under the assumption that you don’t have the source code of that software. [Otherwise you can just modify the source code]

**

Method 1: Intercept library call in linking time.**

Sometimes you have a library (A) that can be used as a part of your program and you want to intercept the library call of that library (A). The best way and the easiest way is to write a fake function and link it in the compile time. This method is totally harmless to your system and very neat. If you can do some modification in makefile, then this procedure is totally transparent to both developer and user.

**

Method 2: Intercept system call in the run time**

If you’ve already got a execute program, then there is no way to intercept the system call in compiling time. To intercept the system call in the run time, there are two ways. The first approach is putting the target program in a designed container. Typically, a container fork/create/call the target program as child process. Since in OS, parent process has accessibility to the child process, it can intercept syscalls easily via ptrace toolset. The second method is to hack the kernel, namely, to tell the Linux kernel to response syscall in a certain way. Since now Linux supports kernel module, a very convenience approach is to compile a program as kernel module and install it on the fly. However, this method is less flexible then the previous method as now all the syscall are intercepted, even for system calls from other programs. [Sure, you can restrict the module only applicable to a certain process via a pid comparison, but then you need to feed the kernel module with PID, it’s awkward ]

In my implementation, I use ptrace/container method. I’ve tried kernel module method but failed as there were not so much well-formed documents on Linux 2.6 kernel.

Here is my code, it’s self-explanatory, have fun with hacking. [Download the C file]

/* Faketime wraps a user program and feed it with user-specified fake system time
   so that it can be used forever without any "licence expired" problem
	 
    Copyright (C) 2007 Eric You XU, Washington University ( youxu [@T] wustl.edu ) 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

*/

#include <sys/ptrace.h>
#include <asm/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <linux/user.h>

/*
Register layout defined linux/user.h, but actually in 
 asm-$(arch)/user.h
struct user_regs_struct {
        long ebx, ecx, edx, esi, edi, ebp, eax;
        unsigned short ds, __ds, es, __es;
        unsigned short fs, __fs, gs, __gs;
        long orig_eax, eip;
        unsigned short cs, __cs;
        long eflags, esp;
        unsigned short ss, __ss;
};
*/

/* Note that EAX now is RAX in x86-64
 	we can also find the actural offset for any register
 	from <asm-$(arch)/ptrace-abi.h>
#define RAX 24
*/

#define ORIG_RAX 44
/* ORIG_RAX stores the number of syscall */

#define SYS_TIME 13
/* Machine specific syscall number is defined in 
	unistd.h */

#define back_to_future 1175737392

/* Time is stored as a long interger in C, you can get 
	current time via time(NULL). Thus, it's very easy to 
	get a long integer denoting some time in the past. 
	
	Python/Java can also be helpful in figuring this out 
	
	If you don't know how, just keep in mind that 
	Dec. 1, 2007 is about 1196476452. 
	One day interval = 60*60*24 = 86400 [Time flies fast]
*/

char* host_program = "your program name here";
char* arglist = "your program fake list here";
/* Make modifications for these two lines, then 
	compile it via
		gcc faketime.c -o faketime
	use it via 
		./faketime
*/

int main()
{   pid_t child;
    long orig_rax, eax;

	 struct user_regs_struct regs;
	 int status;
    int insyscall = ;
    child = fork();
    if(child == ) {
        ptrace(PTRACE_TRACEME, , NULL, NULL);
        execl(host_program, arglist, NULL);
          }
    else {
       while(1) {
          wait(&status);
          if(WIFEXITED(status))
              break;
          orig_rax = ptrace(PTRACE_PEEKUSER,
                     child, ORIG_RAX, NULL);

          if(orig_rax == SYS_TIME ) { /* Intercept SYS_TIME syscall */
             if(insyscall == ) { /* Syscall entry */
                insyscall = 1;
             			  }
         	 else { /* Syscall exit */
					ptrace(PTRACE_GETREGS, child, , &regs);
				   	/* We can also use ptrace(PTRACE_SETREGS, child ,RAX, &back_to_future); 
						but it doesn't work. There might be some tricky here */
					regs.eax = back_to_future;
					ptrace(PTRACE_SETREGS, child, , &regs);
            	                 }
          } // End if with SYS_TIME 
       ptrace(PTRACE_SYSCALL, child, NULL, NULL);
        }
    }
    return ;
}