Time to reverse ...

    So the first of April died out. Someone sniffed their devices on the new Google Nose service that day , someone played in “Field of Miracles” , and someone, having forgotten about the fateful date, just gloomily shook his back from the chalk ...

    I, inspired by the article about hidden opportunities customization of the process explorer.exe, also decided to do something funny.
    Let my second hand clock in Windows go back today! Not the most useful mod in the economy, of course, but for academic and recreational purposes it’s quite suitable :)
    I left the hour and minute hands in the right direction. Sometimes you still have to half-eat up the clock in the tray - let them show the time with an accuracy of at least a minute ...

    Training


    The sequence of actions seems to be approximately the following:
    1. Explore explorer.exe and understand how it counts time
    2. Something to change something in the logic so that the clock goes back

    Changing the logic of some 32-bit usermode process is not difficult: for a long time there is a debugger OllyDbg that many people have loved, there are plenty of tutorials on it even in Russian. Therefore, to give a twist to it, it was decided to implement the task on my 64-bit Windows 7 - I wanted to find out how processes with double-digit capacity live there for a long time ...

    In the 64-bit world, at the disassembler level, unfortunately, it’s not very sweet yet: you don’t feel comfortable for debugging, you do n’t need the most convenient Detours , for which they ask you to pay no less than $ 9,999.95 (well, thank you for not $ 10k - marketers know how to make the price more attractive). Even old 32-bit injectorscannot be used to implement 64-bit dlls. Apparently, my default search engine will have to work hard ...

    Yes, fans of static analysis will forgive me, I didn’t have a relationship with IDA Pro, so I had almost no choice - the old WinDbg was waiting in the wings.
    In matters of working with WinDbg, the most valuable source of information is the windbg.info resource .

    Explore explorer.exe


    We are connected to the process and are looking for something related to the word " clock ":



    Having looked better at the list of functions given out, you can notice an inconspicuous function explorer!CClockCtl::_RecalcCurTime. Is the first shot right at the target? Let's see what is inside it:



    That's right, immediately after the function prologue we see a GetLocalTime call , which, as you know, returns the local time and date. If we can influence the return result of this function, we can also change the direction of the second hand - it remains only to put a hook on this function.

    To implement our plans, we need to somehow get into the address space of the process explorer.exe. And the CLI DLL-Injector command-line utility will help us in the best way possible.. Not only does it support 32 and 64 bits, it also knows how to implement dll in two ways: through the LoadLibrary injection, and by directly writing the code through WriteProcessMemory and then transferring the relocs.

    Directly to install hooks inside the explorer.exe process, we will use the simple and reliable MinHook library .
    It is worth noting that behind the apparent simplicity of the library, there is a very thought-out logic inside that works even in fairly complex cases. So, the Powerful x86 / x64 Mini Hook-Engine library , which I tried to use at first, led to Access Violation due to the fact that the first GetLocalTime function instruction is a relative JMP transition. In this case, the task is complicated by the need to recalculate the offset.

    Implementation


    We decided on the tools. Now it remains to write a dll, which with DLL_PROCESS_ATTACH will put a hook on the GetLocalTime function:

    #include 
    #include "MinHook.h"
    // Статически линкуемся с libMinHook.dll
    #pragma comment(lib, "libMinHook.x64.lib")
    // Указатель на оригинальный GetLocalTime
    static void (WINAPI *GetLocalTime_)(LPSYSTEMTIME lpSystemTime);
    void WINAPI MyGetLocalTime(LPSYSTEMTIME lpSystemTime)
    {
      // Вызываем оригинальный GetLocalTime
      GetLocalTime_(lpSystemTime);
      // Инвертируем количество секунд: 59 -> 0, 0 -> 59
      lpSystemTime->wSecond = 59 - lpSystemTime->wSecond;
    }
    BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
    {
      switch (dwReason) {
      case DLL_PROCESS_ATTACH:
        // Не повторяйте этого в продакшене!
        // Во избежание неприятных дедлоков, внутри DllMain() нужно оставлять только самый необходимый функционал
        // Инициализируем библиотеку libMinHook
        if (MH_Initialize() != MH_OK) {
          return FALSE;
        }
        // Создаём хук (пока что он будет в выключенном состоянии)
        if (MH_CreateHook(&GetLocalTime, &MyGetLocalTime, reinterpret_cast(&GetLocalTime_)) != MH_OK) {
          return FALSE;
        }
        // Активизируем хук
        if (MH_EnableHook(&GetLocalTime) != MH_OK) {
          return FALSE;
        }
      }
      return TRUE;
    }
    

    We use the received dll


    Now you can implement the dll. We launch the injector in the console with the following command:



    In the --lib key, it is important to pass the full path to the dll, for more details why this is done see comment

    Everything, you can enjoy the results! (carefully, hypnotizing)

    Sources (projects for VS2010) and binaries for self-picking can be found here .

    Also popular now: