DLL injection

simon_b
simon_b used Ask the Experts™
on
i'm trying to inject a DLL into a newly created process that hooks the createProcess function, so that every time that a child process is created, it will also be hooked. ultimately, it's intended to keep a track on which processes are launched, and how many times.

i'm using madshi's madCodeHookLib, and the code below is based on some examples that he provides. despite the excellent documentation on his site, and some advice that he was kind enough to offer, i still can't get it working.

when i run the code below, i get the "hook installed!" message from winMain, and then the "DLL_PROCESS_ATTACH" message from the dllMain, then the cmd prompt window opens. when i close the cmd prompt window, i get the "DLL_PROCESS_DETTACH" message. however, the "intercepted call to createProcess" message in CreateProcessHookProc never appears.

i'm sure i'm missing something blindingly obvious - but i can't work it out, and i'm banging my head on the desk here. so, all help and advice is much appreciated....

here's the code:

// demonstrate how madCodeHook can hook (almost) any API under any win32 OS
// a madCodeHook is normally only process wide
// look at the systemAPI demo for infos about system wide hooks
// (note, that you can even hook so-called shared system APIs under win9x)

#include <windows.h>
#include "madCodeHookLib.h"


// variable for the "next hook", which we then call in the callback function
// it must have *exactly* the same parameters and calling convention as the
// original function
// besides, it's also the parameter that you need to undo the code hook again
UINT( WINAPI *CreateProcessNextHook )(      LPCTSTR lpApplicationName,
                                                            LPTSTR lpCommandLine,
                                                            LPSECURITY_ATTRIBUTES lpProcessAttributes,
                                                            LPSECURITY_ATTRIBUTES lpThreadAttributes,
                                                            BOOL bInheritHandles,
                                                            DWORD dwCreationFlags,
                                                            LPVOID lpEnvironment,
                                                            LPCTSTR lpCurrentDirectory,
                                                            LPSTARTUPINFO lpStartupInfo,
                                                            LPPROCESS_INFORMATION lpProcessInformation );


// this function is our hook callback function, which will receive
// all calls to the original SomeFunc function, as soon as we've hooked it
// the hook function must have *exactly* the same parameters and calling
// convention as the original function
UINT WINAPI CreateProcessHookProc(      LPCTSTR lpApplicationName,
                                                            LPTSTR lpCommandLine,
                                                            LPSECURITY_ATTRIBUTES lpProcessAttributes,
                                                            LPSECURITY_ATTRIBUTES lpThreadAttributes,
                                                            BOOL bInheritHandles,
                                                            DWORD dwCreationFlags,
                                                            LPVOID lpEnvironment,
                                                            LPCTSTR lpCurrentDirectory,
                                                            LPSTARTUPINFO lpStartupInfo,
                                                            LPPROCESS_INFORMATION lpProcessInformation )
      {
      UINT result=1;

      // create process in suspended mode
      result = CreateProcessNextHook( lpApplicationName,
                                                      lpCommandLine,
                                                      lpProcessAttributes,
                                                      lpThreadAttributes,
                                                      bInheritHandles,
                                                      dwCreationFlags,
                                                      lpEnvironment,
                                                      lpCurrentDirectory,
                                                      lpStartupInfo,
                                                      lpProcessInformation );

      //inject madCodeHookLib dll
      InjectLibrary( lpProcessInformation->hProcess, "madCodeHookLib.dll" );

      //inject dll
      InjectLibrary( lpProcessInformation->hProcess, "dlI_injection_lib.dll" );

      // resume process
      ResumeThread( lpProcessInformation->hThread );

      return result;
      }


int pascal WinMain( HINSTANCE hCurInstance, HINSTANCE hPrevInstance, LPSTR lpCommandLine, int nCmdShow )
      {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof( si ) );
    ZeroMemory( &pi, sizeof( pi) );
    si.cb = sizeof( si );

      // we install our hook on the API...
      if( HookCode( CreateProcess, CreateProcessHookProc, ( PVOID* ) &CreateProcessNextHook ) )
            {
            MessageBox( 0, "hook installed!", "processAPISyswide:WinMain", MB_OK | MB_ICONINFORMATION );
            }

      // call the original (but hooked) API
      CreateProcess( NULL,                                    // No module name (use command line)
                           "cmd",                                    // Command line
                           NULL,                                    // Process handle not inheritable
                           NULL,                                    // Thread handle not inheritable
                           FALSE,                                  // Set handle inheritance to FALSE
                           0,                                          // No creation flags
                           NULL,                                    // Use parent's environment block
                           NULL,                                // Use parent's starting directory
                           &si,                                          // Pointer to STARTUPINFO structure
                           &pi );                                    // Pointer to PROCESS_INFORMATION structure

      // wait until child process exits(ie when user closes window)
      WaitForSingleObject( pi.hProcess, INFINITE );

      // Close process and thread handles
      CloseHandle( pi.hProcess );
      CloseHandle( pi.hThread );                        

//      UnhookCode( ( PVOID* ) &CreateProcessNextHook );

      return 0;
      }

and here's the DLL:

// demonstrate how to use madCodeHook to hook into another process

// this DLL hooks into the message handling of the current process
// by hooking the official Windows API CreateProcess


#include <windows.h>

#include "madCodeHookLib.h"


#define EXPORT extern "C" __declspec (dllexport)


// variable for the "next hook", which we then call in the callback function
// it must have *exactly* the same parameters and calling convention as the
// original function
// besides, it's also the parameter that you need to undo the code hook again
UINT( WINAPI *CreateProcessNextHook )(      LPCTSTR lpApplicationName,
                                                            LPTSTR lpCommandLine,
                                                            LPSECURITY_ATTRIBUTES lpProcessAttributes,
                                                            LPSECURITY_ATTRIBUTES lpThreadAttributes,
                                                            BOOL bInheritHandles,
                                                            DWORD dwCreationFlags,
                                                            LPSTARTUPINFO lpStartupInfo,
                                                            LPVOID lpEnvironment,
                                                            LPCTSTR lpCurrentDirectory,
                                                            LPPROCESS_INFORMATION lpProcessInformation );


// this function is our hook callback function, which will receive
// all calls to the original SomeFunc function, as soon as we've hooked it
// the hook function must have *exactly* the same parameters and calling
// convention as the original function
UINT WINAPI CreateProcessHookProc(      LPCTSTR lpApplicationName,
                                                      LPTSTR lpCommandLine,
                                                      LPSECURITY_ATTRIBUTES lpProcessAttributes,
                                                      LPSECURITY_ATTRIBUTES lpThreadAttributes,
                                                      BOOL bInheritHandles,
                                                      DWORD dwCreationFlags,
                                                      LPSTARTUPINFO lpStartupInfo,
                                                      LPVOID lpEnvironment,
                                                      LPCTSTR lpCurrentDirectory,
                                                      LPPROCESS_INFORMATION lpProcessInformation )
      {
      UINT result;

      char buf [50] = ( "intercepted call to createProcess\n for " );
      lstrcat( buf, lpCommandLine );

      MessageBox( 0, buf, "dlI_injection_lib.dll:CreateProcessHookProc", MB_OK | MB_ICONINFORMATION );

      // now call the original function
      result = CreateProcessNextHook( lpApplicationName,
                                                      lpCommandLine,
                                                      lpProcessAttributes,
                                                      lpThreadAttributes,
                                                      bInheritHandles,
                                                      dwCreationFlags,
                                                      lpStartupInfo,
                                                      lpEnvironment,
                                                      lpCurrentDirectory,
                                                      lpProcessInformation );

      return result;
      }


int WINAPI DllMain( HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved )
      {
      switch( fdwReason )
            {
            case DLL_PROCESS_ATTACH:
                  HookCode( CreateProcess, CreateProcessHookProc, ( PVOID* ) &CreateProcessNextHook );
MessageBox( 0, "DLL_PROCESS_ATTACH", "dlI_injection_lib.dll:DllMain", MB_OK | MB_ICONINFORMATION );
                  break;

            case DLL_PROCESS_DETACH:
                  UnhookCode( ( PVOID* ) &CreateProcessNextHook );
MessageBox( 0, "DLL_PROCESS_DETTACH", "dlI_injection_lib.dll:DllMain", MB_OK | MB_ICONINFORMATION );
                  break;
            }

      return TRUE;
      }
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
On which OS are you running this? Are you sure that cmd is using CreateProcess? I guess it's using CreateProcessW. So please add a hook to CreateProcessW. Then probably it will work.

Some hints:

(1) You should only call InjectLibrary and ResumeThread, if the original CreateProcess API succeeded.
(2) You didn't start the new process in suspended mode. So the "ResumeThread" call makes no sense. You should "or" a CREATE_SUSPENDED to the start parameters. Also you should call "ResumeThread" only if the original creation flags did *not* contain CREATE_SUSPENDED anyway.
(3) InjectLibrary is not recommended to be used on processes, which are not fully initialized yet. Fur this situation you should use InjectLibrary2. This API is only available in the newer version of madCodeHookLib. If you don't have it yet, write me, then I can send it to you.

Regards, Madshi.
Commented:
There is no CreateProcess() function.  CreateProcess is a macro #defined to be either CreateProcessA() or CreateProcessW().

Commented:
In Delphi CreateProcess always points to CreateProcessA. But anyway, you're right, we should talk of A or W to make things clear. When I wrote CreateProcess I meant CreateProcessA. Sorry...

Regards, Madshi.

Author

Commented:
sorry about the delay finalizing this question. i never did get my head round dll injection, left my job, turned my back on IT, and became a cycle courier in london. so it goes.....

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial