Как я решил проблему 2038 года на Windows с Sandboxie

от автора

Здравствуйте, господа. Милостиво прошу вас извинить меня, если я позволил себе допустить какие-либо недочёты, это моя первая проба пера.

Вы уже наверняка слышали о проблеме 2000 года, также известной как Y2K.

Для тех, кто не в курсе — раньше год часто выводился так:

printf("19%02d год",year);

Что в 2000 году выдало бы «19100 год». Проблема 2038 года несколько серьёзней.

19 января 2038 года время примет отрицательное значение из-за переполнения 32-битного числа, уходя в прошлое. Из-за этого, многие купленные программы лишатся лицензии.

Однако, мне удалось обойти это через параметр Sandboxie, InjectDll. Инъектор Sandboxie замечателен тем, что патчит все процессы браузера, в отличие от аналогичных программ, и не требует лончеров.

Следующий код работает как на x86, так и на x64.

#include <windows.h> #include <stdlib.h> #include <string.h> /*сдвиг изначально ставится в 0, чтобы измерить размер*/ ULONGLONG shift=0; /*эта функция используется только для замера*/ ULONGLONG ft2i(LPFILETIME d){     ULONGLONG t=d->dwHighDateTime;     t<<=32;     t+=(unsigned)d->dwLowDateTime;     return t; } /*Не совместимо с XP без обновлений и более ранними Можно убрать суффикс 64 для совместимости, но тогда через какое-то время будет глюк*/ ULONGLONG gett(){     ULONGLONG t=GetTickCount64();     return t*10000+shift; } /*MS обещали удалить эту функцию. Патчим, только если она есть*/ int WINAPI fake_NtQuerySystemTime( PLARGE_INTEGER t){     t->QuadPart=gett();     return 0; } /*работает так же, как и NtQuerySystemTime я проверил*/ void WINAPI fake_GetSystemTimeAsFileTime( LPFILETIME d){     ULONGLONG t=gett();     d->dwLowDateTime=(int)t;     d->dwHighDateTime=t>>32; } void WINAPI fake_GetSystemTime( LPSYSTEMTIME t){     FILETIME ft;     fake_GetSystemTimeAsFileTime(&ft);     FileTimeToSystemTime(&ft,t); } void*ptr_NtQuerySystemTime=fake_NtQuerySystemTime; void*ptr_GetSystemTimeAsFileTime=fake_GetSystemTimeAsFileTime; void*ptr_GetSystemTime=fake_GetSystemTime; void _hook(char*d,LONGLONG*f){     DWORD old;     VirtualProtect(d,14,PAGE_EXECUTE_READWRITE,&old);     /*на всякий случай сначала ставим int3*/     d[0]=0xcc; #ifdef _WIN64     *(int*)(d+2)=0;     *(LONGLONG*)(d+6)=*f; #else     *(int*)(d+2)=(int)f; #endif     d[1]=0x25;     d[0]=0xff;     /*MS очень не любят принимать NULL*/     VirtualProtect(d,14,old,&old); } #define hook(d,f) _hook((void*)(d),(void*)(&f)) void patch(char const*s){     void*d;     HMODULE m=LoadLibraryA(s);     if(!m)return;     d=GetProcAddress(m,"NtQuerySystemTime");     if(d)hook(d,ptr_NtQuerySystemTime);     d=GetProcAddress(m,"GetSystemTimeAsFileTime");     if(d)hook(d,ptr_GetSystemTimeAsFileTime);     d=GetProcAddress(m,"GetSystemTimePreciseAsFileTime");     if(d)hook(d,ptr_GetSystemTimeAsFileTime);     d=GetProcAddress(m,"GetSystemTime");     if(d)hook(d,ptr_GetSystemTime);     d=GetProcAddress(m,"GetLocalTime");     if(d)hook(d,ptr_GetSystemTime); } BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved){     char*a;     FILETIME t;     switch(fdwReason){      case DLL_PROCESS_ATTACH:         GetSystemTimeAsFileTime(&t);         shift=ft2i(&t)-gett();         a=getenv("Y38ADJ");/*единица - 4 года,         таким образом, високосный год не сдвигается         секундой в 100 лет можно пока пренебречь*/         if(a)shift+=(atoll(a)*10000000)*126230400;         patch("kernel32.dll");         patch("kernelbase.dll");         patch("ntdll.dll");         break;     }     return TRUE; }

Только последняя версия Sandboxie ещё работает с текущими браузерами. Я возьму для примера браузер Catsxp — он всё ещё работает с Windows 7. Ниже уже ничего не годится, к сожалению.

Пропущу создание самой песочницы, установку браузера…

В новых версиях Windows трудно открыть панель задач. Проще всего нажать Win-R и ввести sysdm.cpl.

Дополнительно — Переменные среды. Я создаю системную переменную Y38ADJ со значением 2.

Это переведёт время в патченых программах на 8 лет вперёд. Теперь я переведу системное время на 8 лет назад.

Теперь сам патч. В Sandboxie Опции-Редактировать Sandboxie.ini.

Нахожу строку [GlobalSettings].

Добавляю ниже ещё две строки, указывающие, куда я положил dll файлы. Теперь это выглядит так:

[GlobalSettings] InjectDll=c:\adjtim\adjtim32.dll InjectDll64=c:\adjtim\adjtim64.dll

И Catsxp работает, хотя система думает, что сейчас 2016 год. Это позволяет переводить время назад каждые 4 года, сохраняя функциональность протокола SSL.

Правда, не очень хорошо работает с DDOS защитой. И всё же Windows 7, 8 и 10 можут прожить ещё немного.

Ну как?


ссылка на оригинал статьи https://habr.com/ru/articles/823678/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *