понедельник, 21 января 2008 г.

WayBack

Иногда возникает необходимость запустить приложение не в настоящем времени, а в прошлом или будущем. Обычно это нужно для тестирования приложения или для обхода устаревания evaluation license. Достигается это переводом системных часов, либо запуском приложения в vmware - оба этих метода имеют свои очевидные недостатки. К счастью в linux есть такая замечательная вещь как LD_PRELOAD, позволяющяя "переопределить" импортируемые функции приложения. Так, например, если подменить time, gettimeofday и clock_gettime - то программа с большой долей вероятности будет жить в том времени который нам нужен, в то время как вся остальная система будет жить в обычном временном русле. Для этих целей я написал небольшую C'ную библиотеку. Устанавливается библиотека как обычно make install.

Для примера, небольшое тестовое приложение на C:

void main () {
printf ("%lu\n", time(0));
}

Запускаем:

akshaal@...:/tmp% ./test
1200947571

akshaal@...:/tmp% WAYBACK_TODAY=1970.01.01 LD_PRELOAD=libwayback.so.0 /tmp/test
63225

akshaal@...:/tmp% WAYBACK_LOG_LEVEL=3 WAYBACK_TODAY=1970.01.01 LD_PRELOAD=libwayback.so.0 /tmp/test
Delta time: 3094082896
time modified
63257


Библиотека libwayback не возвращает константу. После запуска, она определяет разницу между текущим временем и желаемым и запоминает ее как delta. В дальнейшем все вызовы к функция возвращающим время перехватываются и delta прибваляется к результату. Таким образом время не стоит на месте и в то же время она очень близко к желаемому.

Например приложение на Java и стандартная утилита date:

import java.util.Date;

public class test {
public static void main (String[] args) {
System.out.println (new Date());
}
}

akshaal@...:/tmp% java test
Mon Jan 21 22:39:26 EET 2008

akshaal@...:/tmp% WAYBACK_TODAY=2010.11.27 LD_PRELOAD=libwayback.so.0 java test
Sat Nov 27 20:40:39 EET 2010

akshaal@...:/tmp% date
Mon Jan 21 22:41:20 EET 2008

akshaal@...:/tmp% WAYBACK_TODAY=2010.11.27 LD_PRELOAD=libwayback.so.0 date
Sat Nov 27 20:41:50 EET 2010


К сожалению данный способ может быть использован для обхода устаревания лицензии :) у программ к которым есть evaluation license ограниченная на определенный срок (например JProfiler 5, YourKit Profiler 7, InteliJ Idea и еще много). Я не проверял работает ли (но уверен, что да :) ) ибо предпочитаю опенсоурс софт и вообще это плохо и я против использования библиотеки для этих целей :).

В библиотеке существует опция WAYBACK_RESET, которая определяет сколько секунд будет происходить подмена времени. К сожалению и эта опция может быть использована в целях обмана программ проверяющих срок действия лицензии. К примеру, если программа проверяет лицензию при запуске, то WAYBACK_RESET несознательный человек установит в 5 секунд, и после 5с получит пройденную проверку и программу с актуальным временем.

Библиотека написана за час и не является Абсолютным Решением. Кому надо - юзают на свой страх и риск, а с меня никакого спросу.

P.S. Больше всего напарился с одной вещью. Запускаю свинговое приложение, а оно виснет. Думаю че за нахрен. Копался-копался... оказывается java юзает pthread_condwait и ей в качестве параметра передается не относительное время (время когда ожидание прекращается), а абсолютное! Пришлось и эту функцию переопределить и вычитать дельту. Но как я искал.. strace говорит, что нить висит на futex каком-то.. и только чудом догадался, что futex может быть более нижним лаером под pthread'ом, а там уже полез смотреть как работа с X'ами идет в libawt.

1 комментарий:

  1. Очень интересно, вот бы самому попробовать. Но у вас ссылка на код умерла. Почините пожалуйста.

    ОтветитьУдалить