Pages

Monday, May 18, 2015

[C/C++] From kernel32!Sleep to ntdll!NtDelayExecution

Code snippet:

#include <windows.h>

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif

    MessageBoxW(
        NULL,
        L"Close me to start delay!",
        captionMsg,
        MB_ICONINFORMATION);

    Sleep(2000);

    MessageBoxW(
        NULL,
        L"Finished!",
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}
Inside Debugger:
........
........
PUSH  0
CALL  ESI
PUSH  7D0
CALL  DWORD PTR DS:[<&KERNEL32.Sleep>] ; kernel32.Sleep
PUSH  40
PUSH  EDI
........
........
PUSH  ESI
PUSH  DWORD PTR SS:[EBP+C]
CALL  DWORD PTR DS:[<&ntdll.NtDelayExecution>] ; ntdll.ZwDelayExecution
MOV   DWORD PTR SS:[EBP-1C],EAX
CMP   DWORD PTR SS:[EBP+C],EDI
........
........
Final code snippet:
#include <windows.h>
#include <ntdll.h>

#define NATIVE

int WINAPI iWinMain() {
#ifdef _WIN64
    LPWSTR captionMsg = L"64-bit Application";
#else
    LPWSTR captionMsg = L"32-bit Application";
#endif

    LARGE_INTEGER Interval;

    MessageBoxW(
        NULL,
        L"Close me to start delay!",
        captionMsg,
        MB_ICONINFORMATION);

#ifdef NATIVE
    Interval.QuadPart = -20000000; // delay 2 seconds
    NtDelayExecution(FALSE, &Interval);
#else
    Sleep(2000);
#endif

    MessageBoxW(
        NULL,
        L"Finished!",
        captionMsg,
        MB_ICONINFORMATION);

    return 0;
}
Source:
http://www.mediafire.com/download/afrw4e8lx8zrud4/Sleep.rar