Process Creation Hook in Win8 X64

c++ / delphi package - dll injection and api hooking
Post Reply
jgh0721
Posts: 28
Joined: Tue Apr 22, 2014 8:06 am

Process Creation Hook in Win8 X64

Post by jgh0721 »

I create own hook dll by hook CreateProcessInternalW, ZwResumeThread in Win8 x64.

A) So I successfully hooked CreateProcessInternalW when icon dbl click to execute in desktop.

B) But, I unsuccessfully hooked when icon right click and execute as admin in desktop.

Both Dllmain called, and Hook API return TRUE, but in case B, CreateProcessInternalW nor ZwResumeThread neither called. so I can't control process creation.

i use madCodeHook 3.1.6
i use VMWare 10.0.0.2, Clean VM, Windows 8 Enterprise K
-------------------

Code: Select all

typedef NTSTATUS( WINAPI *PFZWRESUMETHREAD )
(
    HANDLE ThreadHandle,
    PULONG SuspendCount
);

extern PFZWRESUMETHREAD pfZwResumeThread;

typedef BOOL( WINAPI *PFCreateProcessInternalWcb )(
    HANDLE hToken,
    LPCWSTR lpApplicationName,
    LPWSTR lpCommandLine,
    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    BOOL bInheritHandles,
    DWORD dwCreationFlags,
    LPVOID lpEnvironment,
    LPCWSTR lpCurrentDirectory,
    LPSTARTUPINFOW lpStartupInfo,
    LPPROCESS_INFORMATION lpProcessInformation,
    PHANDLE hNewToken
);

extern PFCreateProcessInternalWcb pfCreateProcessInternalWcb;

------------------
NTSTATUS WINAPI zwResumeThreadHookProc( IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL )
{
    OutputDebugStringA( "Start-ZwResumeThread" );
    return pfZwResumeThread( ThreadHandle, SuspendCount );
}

BOOL WINAPI createProcessInternalWcb( HANDLE hToken, LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation, PHANDLE hNewToken )
{
    DWORD dwLastError = ::GetLastError();
    OutputDebugStringA( "[Start-CreateProcessInternalW]" );
    return pfCreateProcessInternalWcb( hToken,
                                           lpApplicationName,
                                           lpCommandLine,
                                           lpProcessAttributes,
                                           lpThreadAttributes,
                                           bInheritHandles,
                                           dwCreationFlags,
                                           lpEnvironment,
                                           lpCurrentDirectory,
                                           lpStartupInfo,
                                           lpProcessInformation,
                                           hNewToken );
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                       )
{
    if( GetCurrentProcessId() <= 4 )
        return TRUE;

    switch( ul_reason_for_call )
    {
        case DLL_PROCESS_ATTACH:
        {
            OSVERSIONINFOW osi;
            dwScanedPID = 0;
            ZeroMemory( &osi, sizeof( osi ) );
            osi.dwOSVersionInfoSize = sizeof( osi );
            ::GetVersionExW( &osi );

            WCHAR wszBuffer[ MAX_PATH + 1 ] = { 0, };
            GetSystemDirectoryW( wszBuffer, MAX_PATH );
            _vecWhiteList.push_back( std::wstring( wszBuffer ) + L"\\consent.exe" );

            memset( wszBuffer, '\0', sizeof( WCHAR ) * (MAX_PATH + 1) );
            GetWindowsDirectoryW( wszBuffer, MAX_PATH );
            _vecWhiteList.push_back( std::wstring( wszBuffer ) + L"\\explorer.exe" );
            
            DebugLogA( "[Start-DllMain] iMonLope Hook, DLL_PROCESS_ATTACH, HOOK VER = %s", HOOK_DLL_VERINFO );
            InitializeMadCHook();
            if( isVistaOrHigherOS() == true )
                SetMadCHookOption( USE_NEW_IPC_LOGIC, NULL );

            if( osi.dwMajorVersion == 5 )
            {
                OutputDebugStringA( "Windows XP/2003/2003R2, CreateProcess Hook" );

                HookAPI( "kernel32.dll", "CreateProcessInternalW", createProcessInternalWcb, (PVOID*)&pfCreateProcessInternalWcb );
                HookAPI( "Advapi32.dll", "CreateProcessWithLogonW", createProcessWithLogonWcb, (PVOID*)&pfCreateProcessWithLogonWcb );
            }
            else if( osi.dwMajorVersion == 6 && osi.dwMinorVersion == 0 )
            {
                OutputDebugStringA( "Windows Vista, Windows Server 2008, CreateProcess Hook" );
                HookAPI( "kernel32.dll", "CreateProcessInternalW", createProcessInternalWcb, (PVOID*)&pfCreateProcessInternalWcb );
                HookAPI( "Advapi32.dll", "CreateProcessWithLogonW", createProcessWithLogonWcb, (PVOID*)&pfCreateProcessWithLogonWcb );
                HookAPI( "ntdll.dll", "ZwResumeThread", zwResumeThreadHookProc, (PVOID*)&pfZwResumeThread );
            }
            else if( osi.dwMajorVersion == 6 && osi.dwMinorVersion == 1 )
            {
                OutputDebugStringA( " Windows 7, Windows Server 2008 R2, CreateProcess Hook" );
                HookAPI( "kernel32.dll", "CreateProcessInternalW", createProcessInternalWcb, (PVOID*)&pfCreateProcessInternalWcb );
                HookAPI( "Advapi32.dll", "CreateProcessWithLogonW", createProcessWithLogonWcb, (PVOID*)&pfCreateProcessWithLogonWcb );
                HookAPI( "ntdll.dll", "ZwResumeThread", zwResumeThreadHookProc, (PVOID*)&pfZwResumeThread );
            }
            else if( osi.dwMajorVersion == 6 && osi.dwMinorVersion == 2 )
            {
                OutputDebugStringA( " Windows 8, Windows Server 2012, CreateProcess Hook" );
                CollectHooks();
                HookAPI( "KernelBase.dll", "CreateProcessInternalW", createProcessInternalWcb, (PVOID*)&pfCreateProcessInternalWcb );
                HookAPI( "Advapi32.dll", "CreateProcessWithLogonW", createProcessWithLogonWcb, (PVOID*)&pfCreateProcessWithLogonWcb );
                // HookAPI( "ntdll.dll", "ZwResumeThread", zwResumeThreadHookProc, (PVOID*)&pfZwResumeThread );
                HookAPI( "ntdll.dll", "NtCreateUserProcess", ntCreateUserProcess, (PVOID*)&pfNtCreateUserProcess );
                // HookAPI( "ntdll.dll", "RtlCreateUserProcessParameters", rtlCreateProcessParameters, (PVOID*)&pfRtlCreateProcessParameters );
                FlushHooks();
            }

            OutputDebugStringA( "[Finish-DllMain] iMonLope Hook, DLL_PROCESS_ATTACH" );

            break;
        }
        case DLL_PROCESS_DETACH:
        {
            // FinalizeMadCHook 를 호출하면 자동으로 Unhook 된다
            OutputDebugStringA( "[Start-DllMain] iMonLope Hook, DLL_PROCESS_DETACH" );

            if( hSfcLib != NULL )
                FreeLibrary( hSfcLib );
            hSfcLib = NULL;

            FinalizeMadCHook();
            OutputDebugStringA( "[Finish-DllMain] iMonLope Hook, DLL_PROCESS_DETACH" );
            break;
        }

        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;
    }

    return TRUE;

}
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: Process Creation Hook in Win8 X64

Post by madshi »

There are several process creation APIs. CreateProcessWithLogonW and CreateProcessAsUserA/W come to my mind right now, but I'm not sure if that's the one which is used for right click -> run as admin. I also don't know if these end up in CreateProcessInternalW. Maybe not. I think user elevation *may* also involve the process being started from some system process, so your hook dll might have to be injected in the system processes, too, but I'm not really sure about that. You could try hooking NtCreateProcess(Ex), but I think doing that won't give you the exe file name.

It might make sense to add a secondary "new process" detection by making use of the automated dll injection. If you inject your hook dll system wide, you can call in DllMain "GetModuleFileName(0)". That will give you the name of each new process. So if you missed a new process in your CreateProcessInternalW hooks, by checking the current process in your hook dll's DllMain you'd have a 2nd layer of new process detection.
Post Reply