Возможно можно заюзать ZwSetSystemInformation с классом SystemTimeAdjustment, установив отрицательные значение (хотя вряд ли это возможно), но в два раза быстрее, наверное, можно сделать чтоб тикало Вот ещё по теме. Может кому пригодится... Что-то форум в 2010 году меня не признает. Пришлось назад вернуться Код (Text): .386 .model flat, stdcall option casemap:none ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; I N C L U D E F I L E S ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: include \masm32\include\kernel32.inc include \masm32\include\user32.inc include \masm32\include\w2k\ntdll.inc include \masm32\include\w2k\ntddk.inc include \masm32\include\w2k\ntstatus.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib includelib \masm32\lib\w2k\ntdll.lib include \masm32\macros\Strings.mac ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; E Q U A T E S ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: MB_OK equ 0 MB_YESNO equ 4 IDYES equ 6 MB_DEFBUTTON2 equ 100h SystemTimePrivilege equ 12 ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; C O D E ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: .code ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; start ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: start proc local liSystemTime:LARGE_INTEGER local liLocalTime:LARGE_INTEGER local tf:TIME_FIELDS local buffer[512]:CHAR push ecx invoke RtlAdjustPrivilege, SystemTimePrivilege, \ TRUE, \ ; Enable FALSE, \ ; Use client's token esp ; WasEnabled pop ecx ; Get time invoke ZwQuerySystemTime, addr liSystemTime invoke RtlSystemTimeToLocalTime, addr liSystemTime, addr liLocalTime invoke RtlTimeToTimeFields, addr liLocalTime, addr tf CTA "Year:\t\t%d\n", g_szFmt CTA "Month:\t\t%d\n" CTA "Day:\t\t%d\n" CTA "Hour:\t\t%d\n" CTA "Minute:\t\t%d\n" CTA "Second:\t\t%d\n" CTA "Milliseconds:\t%d\n" CTA "Weekday:\t%d\n\n" CTA0 "Would you like to change it to 01 Januar 2010?" xor eax, eax mov ax, tf.Weekday push eax mov ax, tf.Milliseconds push eax mov ax, tf.Second push eax mov ax, tf.Minute push eax mov ax, tf.Hour push eax mov ax, tf.Day push eax mov ax, tf.Month push eax mov ax, tf.Year push eax lea eax, g_szFmt push eax lea eax, buffer push eax call wsprintf add esp, 10 * sizeof DWORD invoke MessageBox, NULL, addr buffer, $CTA0("Your current time"), MB_YESNO + MB_DEFBUTTON2 .if eax == IDYES ; Set time mov tf.Year, 2010 mov tf.Month, 01 mov tf.Day, 01 mov tf.Hour, 00 mov tf.Minute, 00 mov tf.Second, 00 mov tf.Milliseconds, 000 ; tf.Weekday ignored invoke RtlTimeFieldsToTime, addr tf, addr liLocalTime invoke RtlLocalTimeToSystemTime, addr liLocalTime, addr liSystemTime invoke ZwSetSystemTime, addr liSystemTime, NULL invoke MessageBox, NULL, $CTA0("Happy New Year ;\}"), $CTA0("Time changed"), MB_OK .endif invoke ExitProcess, 0 ret start endp ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: end start 1876123355__ZwSetSystemTime.rar
Ну что? Так никто и не попробовал со временем поиграться? А я вот попробовал - работает Единственно, недопёр я с полем TimeSynchronization. Когда изначально Query делаешь, оно равно TRUE. Когда делаешь Set, то он делается только если TimeSynchronization установить в FALSE. Но потом его назад уже не вернуть. Вобщем, надоело играться. Пример заcтавляет часики тикать в 4 раза быстрее. Замедлить тоже можно. Как говорится: "Use it at your own risk!". Код (Text): .386 .model flat, stdcall option casemap:none ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; I N C L U D E F I L E S ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: include \masm32\include\kernel32.inc include \masm32\include\user32.inc include \masm32\include\w2k\ntdll.inc include \masm32\include\w2k\ntddk.inc include \masm32\include\w2k\ntstatus.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib includelib \masm32\lib\w2k\ntdll.lib include \masm32\Macros\Strings.mac ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; E Q U A T E S ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: MB_OK equ 0 MB_YESNO equ 4 IDYES equ 6 MB_DEFBUTTON2 equ 100h SystemTimeAdjustment equ 28 SYSTEM_QUERY_TIME_ADJUSTMENT STRUCT ; Information Class 28 TimeAdjustment DWORD ? MaximumIncrement DWORD ? TimeSynchronization BOOLEAN ? db 3 dup(?) ; padding SYSTEM_QUERY_TIME_ADJUSTMENT ENDS PSYSTEM_QUERY_TIME_ADJUSTMENT typedef ptr SYSTEM_QUERY_TIME_ADJUSTMENT SYSTEM_SET_TIME_ADJUSTMENT STRUCT ; Information Class 28 TimeAdjustment DWORD ? TimeSynchronization BOOLEAN ? db 3 dup(?) ; padding SYSTEM_SET_TIME_ADJUSTMENT ENDS PSYSTEM_SET_TIME_ADJUSTMENT typedef ptr SYSTEM_SET_TIME_ADJUSTMENT SystemTimePrivilege equ 12 ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; C O D E ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: .code ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; start ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: start proc uses esi edi ebx local sqta:SYSTEM_QUERY_TIME_ADJUSTMENT local ssta:SYSTEM_SET_TIME_ADJUSTMENT invoke ZwQuerySystemInformation, SystemTimeAdjustment, \ addr sqta, sizeof SYSTEM_QUERY_TIME_ADJUSTMENT, NULL .if eax == STATUS_SUCCESS; && sqta.TimeSynchronization != FALSE CTA "Would you like to adjust the time to move faster 4 times?\n\n", g_szMessage CTA0 "It will be reverted back after this application exits." invoke MessageBox, NULL, addr g_szMessage, \ $CTA0("Time adjustment confirmation"), MB_YESNO + MB_DEFBUTTON2 .if eax == IDYES push ecx invoke RtlAdjustPrivilege, SystemTimePrivilege, \ TRUE, \ ; Enable FALSE, \ ; Use client's token esp ; WasEnabled pop ecx mov eax, sqta.TimeAdjustment shl eax, 2 mov ssta.TimeAdjustment, eax mov ssta.TimeSynchronization, FALSE invoke ZwSetSystemInformation, SystemTimeAdjustment, \ addr ssta, sizeof SYSTEM_SET_TIME_ADJUSTMENT .if eax == STATUS_SUCCESS invoke MessageBox, NULL, \ $CTA0("Now you are living faster 4 times?\n\nPress OK to revert back."), \ $CTA0("Time adjustment changed"), MB_OK ; Revert all back mov eax, sqta.TimeAdjustment mov ssta.TimeAdjustment, eax mov ssta.TimeSynchronization, FALSE invoke ZwSetSystemInformation, SystemTimeAdjustment, \ addr ssta, sizeof SYSTEM_SET_TIME_ADJUSTMENT .else invoke MessageBox, NULL, $CTA0("Sorry, time adjustment failed."), NULL, MB_OK .endif .endif .endif invoke ExitProcess, 0 ret start endp ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: ; ;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::: end start 782614906__SystemTimeAdjustment.rar
Если достаточно остановить время внутри одного процесса - то 1. пропатчить нахрен ядро прямо в памяти или 2. найти прогу "Hall of the Mountain king" - она сама время остановит, где попросишь
найти код, который порты 70h и 71h юзает, да и порезать его, как то я задавался таким вопросом уже давно, нашёл это дело в ядре, резал. Всё было как надо. Ну, правда метод туповат.
Тут неожиданно возник смежный вопрос.. Откуда функция GetTickCount берет инфу, по ходу видно что из какой-то ячейки памяти с атрибутом READONLY, что это за структура, и можно ли как-то повлиять на нее из юзера, т.е. нужно чтоб GetTickCount возвращала либо одно и то же либо то что нужно.
Из "последней" страницы юзер памяти процесса (на w2ksp4 например 0x7FFE0000), видимо она динамически проецируется из памяти ядра, к тому же постоянно изменяется ядром, и записать в неё скорее неполучится, там кстати таких страниц несколько, когда-то мы говорили, что в одной из них спроецированы "все окна", которые были созданы с момента загрузки ОС
GetLocalTime тоже оттуда берет, можно его результат подменять плагином для лоадера Rustem'а , или ты это для своего плагина ?
Asterix т.е. нужно чтоб GetTickCount возвращала либо одно и то же либо то что нужно. Я такое делал - опять же для одного процесса. Дизассемблировал, потом GetProcAddress и пропатчил ядро нахрен в памяти.
CyberManiac Т.е. ты предлагаешь поставить хук на GetTickCount и вернуть то что мне нужно, или пропатчить саму эту API, но она ведь может даже не использоваться в явном виде, например протектор скопирует ее код куда-нибудь в выделенную память и выполнит :-( Скоро протекторы начнут сбрасывать мои хуки нахрен А драйвер здесь может помочь? bogrus > или ты это для своего плагина ? Да
Кое что нашёл: Код (Text): ZwGetTickCount retrieves the number of milliseconds that have elapsed since the system booted. NTSYSAPI ULONG NTAPI ZwGetTickCount( VOID ); [b]Parameters[/b] None. [b]Return Value[/b] Returns the number of milliseconds that have elapsed since the system was booted. [b]Related Win32 Functions[/b] None. [b]Remarks[/b] GetTickCount reads from the KUSER_SHARED_DATA page.This page is mapped read-only into the user mode range of the virtual address and read-write in the kernel range. The system clock tick updates the system tick count, which is stored in this page directly. Reading the tick count from this page is faster than calling ZwGetTickCount. The KUSER_SHARED_DATA structure is defined in the Windows 2000 versions of ntddk.h.
Сам себя цитирую Драйверы режима ядра. Часть 9 : Базовая техника: Работа с памятью. Разделяемая память "Т.о. раз в секунду драйвер помещает на разделяемую страницу текущее время, обращаясь при этом по виртуальному адресу в системном адресном пространстве, а программа управления, также раз в секунду, забирает эту информацию, обращаясь при этом по виртуальному адресу в пользовательском адресном пространстве. Но физически разделяется одна страница памяти. Т.о. часы "тикают" каждую секунду. Кстати, функция KeQuerySystemTime получает текущее время также обращаясь к разделяемой между ядром и режимом пользователя странице, которая в режиме ядра спроецирована по адресу 0FFDF0000h, а в режиме пользователя по адресу 7FFE0000h (пользовательская функция GetSystemTime читает те же самые байты что и функция ядра KeQuerySystemTime) и описывается структурой KUSER_SHARED_DATA (см. ntddk.inc). Даже по названию этой структуры видно, что она разделяется ядром и режимом пользователя." Код (Text): ; ; Define data shared between kernel and user mode. ; ; N.B. User mode has read only access to this data ; KUSER_SHARED_DATA STRUCT ; sizeof = 02D8h ; Current low 32-bit of tick count and tick count multiplier. ; ; N.B. The tick count is updated each time the clock ticks. TickCountLow DWORD ? ; 0000h TickCountMultiplier DWORD ? ; 0004h . . . KUSER_SHARED_DATA ENDS PKUSER_SHARED_DATA typedef ptr KUSER_SHARED_DATA
Four-F Это прочитал, и сам тутор прочитал, вот только не понял что делать чтоб справиться с ситуацией %)
Asterix Т.е. ты предлагаешь поставить хук на GetTickCount Хук нужен только чтобы засунуть свою DLL в чужое адресное пространство. Можно и через CreateRemoteThread, но я ее не люблю А переходники патчить - это не то, о чем я всю жизнь мечтал. Asterix или пропатчить саму эту API Именно. Asterix но она ведь может даже не использоваться в явном виде, например протектор скопирует ее код куда-нибудь в выделенную память и выполнит :-( Они сволочи, они могут :-( Скопировать - это еще полбеды: можно засунуть свой код в ядро раньше, чем они это сделают, а вот воспроизвести "на пальцах" код GetTickCount (это сработает, я сам проверял) - это уже хуже. С другой стороны, пусть тебя согревает мысль, что НИКТО не знает, прокатит ли такой фокус в Longhorn'е (а что - встанут с левой ноги да и подвинут адрес соответствующей ячейки на пару байтиков), а потому авторы защит не рискнут использовать заведомо ненадежный код. Asterix Скоро протекторы начнут сбрасывать мои хуки нахрен С моими изделиями тоже плохо обращаются - то окно убьют почем зря, то по ключам из реестра в "хакерский софт" определят, то к Касперу в вирлист внесут. Но ты поверь - это совсем не больно Asterix А драйвер здесь может помочь? Драйвер - вещь хорошая. С ним можно что угодно куда угодно писать. Но изготовить подходящий драйвер будет заметно сложнее - тебе наверное нужно только один процесс обмануть, а не всю систему стоящим таймером заглючить?
CyberManiac <font color="blue]></font><!--color--> Хук нужен только чтобы засунуть свою DLL в чужое адресное пространство. Не всегда, например чтобы вернуть из API нужное значение или проделать какие-то нужные действия в момент вызова конкретной API. <font color="blue]></font><!--color--> можно засунуть свой код в ядро раньше, чем они это сделают Ну возьмут код этой API из другого процесса, где он не испорчен.. <font color="blue]></font><!--color--> а потому авторы защит не рискнут использовать заведомо ненадежный код. Это вполне надежно, к сожалению :-( <font color="blue]></font><!--color--> тебе наверное нужно только один процесс обмануть, а не всю систему стоящим таймером заглючить? Для одного, но наиболее надёжным способом
Asterix Не всегда, например чтобы вернуть из API нужное значение или проделать какие-то нужные действия в момент вызова конкретной API. Теперь понял, про какой хук речь. Я сначала думал, что про тот, который на сообщения ставят. Asterix Ну возьмут код этой API из другого процесса, где он не испорчен.. Так из чужого процесса можно хоть черта лысого достать. Например, ту же переменную, где тики щелкают. И мы плавно приходим к идеям 1. Патчить ядро на винте (я знаю, что это - гнусный изврат) 2. Написать драйвер и изнасиловать соответствующую DLL в рамках всей системы (что после этого случится - одному Гейтсу известно) 3. Изуродовать не только GetTickCount, но вообще все функции, которые могут хоть как-то вылезти за пределы процесса После чего порадоваться успешному залому всех конечностей 20-баксовой утилите и подать объявление в газету "Избавлю от мух, клопов, тараканов при помощи термоядерной бомбы". Asterix Это вполне надежно, к сожалению :-( Мне так не кажется. MS на неизменность потрохов своих изделий гарантийный талон не выдает, так что могут и поменять, если у них будет повод. Asterix Для одного, но наиболее надёжным способом Надежный способ там только один: использовать свое собственное ядро. Если ReactOS доведут до кондиции, оно у нас будет. Главное, чтобы всякие недоумники защит от запуска под не-MS Windows не понаставили, а то их ведь ломать придется