InjectLibrary failed on microsoft windows server 2003

c++ / delphi package - dll injection and api hooking
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

InjectLibrary failed on microsoft windows server 2003

Post by ameetmalekar »

Hi,

I am trying to inject a dll in internet explorer. It successfully get injected if I inject it through an exe which is running in same user mode. But it fails if I try to inject it through the injector from service mode.

I am facing this issue on windows server 2003 standard edition service pack 2 and on some XP machines. It works fine on 2k8, win 7.

Regards,
Ameet
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibrary failed on microsoft windows server 2003

Post by madshi »

(1) Did you call InitializeMadCHook() before calling InjectLibrary()?
(2) How does your InjectLibrary() call look like exactly?
(3) Does InjectLibrary() return true or false? If it's false, what does GetLastError() say?
(4) Try giving read/execute NTFS rights to "Everyone", just to make sure it's got nothing to do with NTFS access rights.
(5) Are we talking about doing injection while the Explorer is already running? Or are we talking about starting injection before the Explorer starts?
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: InjectLibrary failed on microsoft windows server 2003

Post by ameetmalekar »

Hi,
(1) Yes, i called InitializeMadCHook() before calling InjectLibrary().
(2) int res=InjectLibraryA(dllName,tempHandle,7000);
(3)InjectLibrary() returns 0, GetLastError() returns 1.
(4) My machine is in Admin mode and my user is admin. I also gave NTFS full rights to "Everyone".But still not working.
(5) It fails in both conditions :(
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibrary failed on microsoft windows server 2003

Post by madshi »

Some more questions:

(1) Have you checked whether the process handle is valid?
(2) How does your OpenProcess() call look like?
(3) Does your hook dll have any static links other than ntdll.dll and kernel32.dll?
(4) Does injection succeed if you inject an "empty" dll?
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: InjectLibrary failed on microsoft windows server 2003

Post by ameetmalekar »

Hi Thanks for reply... My observations are as below,

(1) Yes, handle is valid. (Have successfully terminated process with same handle)
(2) HANDLE tempHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE, pid);
(3) No, My hook dll does not have any static links other than ntdll.dll and kernel32.dll.
(4) I tried to inject an "empty" dll but same problem occurs with it.

Regards,
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibrary failed on microsoft windows server 2003

Post by madshi »

Ok. So now I need a way to reproduce this problem somehow. You said you can reproduce it on *SOME* XP machines. That suggests that you can't reproduce it on every XP machine? Can you reproduce it on a fresh/clean XP/2003 VM?
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: InjectLibrary failed on microsoft windows server 2003

Post by ameetmalekar »

Yes, It is getting reproduced on clean 2003 VM.
I am not able to find a single 2003 machine where I can inject a simple dll through a process which is running in/by service mode.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibrary failed on microsoft windows server 2003

Post by madshi »

XP and 2003 pretty much share the same kernel, so what is true for 2003 should also be true for XP. So can you also reproduce this on a clean XP VM? I'm asking because I have an XP VM ready for testing, but not a 2003 VM, would have to set that up first...
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: InjectLibrary failed on microsoft windows server 2003

Post by ameetmalekar »

Hi,

It is not getting reproduced on clean XP machine :(
But it always occurs on windows server 2003 standard edition service pack 2.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibrary failed on microsoft windows server 2003

Post by madshi »

Weird. Ok, I'll setup a 2003 VM and come back to you...
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: InjectLibrary failed on microsoft windows server 2003

Post by ameetmalekar »

Thanks
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibrary failed on microsoft windows server 2003

Post by madshi »

Hi there,

finally got around trying this. I did this:

(1) Installed a brand new Windows Server 2003 Standard Edition x86 PC with SP2.
(2) Created an empty folder "test" on the desktop.
(3) Added "Everyone" to the security settings of the "test" folder with full access.
(4) Copied a test service and dll into that "test" folder.
(5) Installed the service.
(6) The service when started (not installed) injected the dll into the Explorer.
(7) Double checked with ProcessExplorer.

No problems, works just fine here. Not sure why it doesn't work for you.

Here's the code I've used for the service:

Code: Select all

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

// ***************************************************************

// these are our service parameters
char  CServiceName  [24] = "madDllInjectPraveen";
char  CServiceDescr [25] = "madCodeHook_praveen_demo";
DWORD CServiceType       = SERVICE_WIN32_OWN_PROCESS;
DWORD CServiceStart      = SERVICE_AUTO_START;

// ***************************************************************

// we need this handle is several functions, so we have to make it global
SERVICE_STATUS_HANDLE statusHandle;

void UpdateStatus(DWORD status)
// update the status of our service
{
  SERVICE_STATUS ss;

  ZeroMemory(&ss, sizeof(ss));
  ss.dwServiceType      = CServiceType;
  ss.dwCurrentState     = status;
  ss.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  ss.dwWaitHint         = 8000;
  SetServiceStatus(statusHandle, &ss);
}

void WINAPI ServiceHandler(DWORD control)
// this function gets called when our service shall be stopped or started
{
  HANDLE event;
  CHAR evName [MAX_PATH];

  if ((control == SERVICE_CONTROL_STOP) || (control == SERVICE_CONTROL_SHUTDOWN))
  {
    // our service is about to stop
    UpdateStatus(SERVICE_STOP_PENDING);
    // then we set our shutdown event
    lstrcpy(evName, CServiceName);
    lstrcat(evName, "ShutdownEvent");
    event = OpenGlobalEvent(evName);
    SetEvent(event);
    CloseHandle(event);
  }
  else
    UpdateStatus(SERVICE_RUNNING);
}

void WINAPI ServiceProc(DWORD, LPSTR*)
// this is the main function of our service, we do all the work here...
{
  HANDLE event;
  CHAR evName [MAX_PATH];

  statusHandle = RegisterServiceCtrlHandler(CServiceName, ServiceHandler);
  if (statusHandle)
  {
    UpdateStatus(SERVICE_START_PENDING);
    InitializeMadCHook();
    
    lstrcpy(evName, CServiceName);
    lstrcat(evName, "ShutdownEvent");
    event = CreateGlobalEvent(evName, true, false);

    HANDLE ph = OpenProcess(PROCESS_ALL_ACCESS, false, 1780);  // 1780 = hard coded Explorer process ID
    InjectLibrary("HookTerminateAPIs32.dll", ph);
    CloseHandle(ph);

    UpdateStatus(SERVICE_RUNNING);

    WaitForSingleObject(event, INFINITE);
    CloseHandle(event);

   	FinalizeMadCHook();
    UpdateStatus(SERVICE_STOPPED);
  }
}

void RunService()
// this is the main thread of our injection service
// we have to call StartServiceCtrlDispatcher as soon as possible here
{
  SERVICE_TABLE_ENTRY st [2];

  ZeroMemory(&st, sizeof(st));
  st[0].lpServiceName = CServiceName;
  st[0].lpServiceProc = &ServiceProc;
  StartServiceCtrlDispatcher(st);
}

// ***************************************************************

void InstallService()
// this function is executed, if someone starts our service exe manually
// if our service is installed, we uninstall it and vice versa
{
  CHAR                   arrCh [MAX_PATH + 1];
  SC_HANDLE              c1, c2;
  DWORD                  c3;
  SERVICE_STATUS         ss;
  LPQUERY_SERVICE_CONFIG qsc;
  int                    i1;
  bool                   b1;

  GetModuleFileName(GetModuleHandle(NULL), arrCh, MAX_PATH);
  // first we contact the service control manager
  c1 = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  if (!c1)
    // didn't work, maybe we asked for too many access rights?
    c1 = OpenSCManager(NULL, NULL, 0);
  if (c1)
  {
    // okay, that worked, now we try to open our service
    c2 = OpenService(c1, CServiceName, SERVICE_ALL_ACCESS | DELETE);
    if (c2)
    {
      // our service is already installed, let's check the parameters
      b1 = false;
      c3 = 0;
      QueryServiceConfig(c2, NULL, 0, &c3);
      if (c3)
      {
        qsc = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, c3 * 2);
        b1 = (QueryServiceConfig(c2, qsc, c3 * 2, &c3)) &&
             ( (qsc->dwServiceType != CServiceType ) ||
               (qsc->dwStartType   != CServiceStart) ||
               (lstrcmpi(qsc->lpDisplayName, CServiceDescr)) );
        LocalFree(qsc);
      }
      if (!ControlService(c2, SERVICE_CONTROL_INTERROGATE, &ss))
        ss.dwCurrentState = SERVICE_STOPPED;
      if ((!b1) && (ss.dwCurrentState == SERVICE_RUNNING))
      {
        // the parameters are correct, so we try to stop and remove it
        if (ControlService(c2, SERVICE_CONTROL_STOP, &ss))
        {
          if (DeleteService(c2))
               MessageBox(0, "the service is removed again",                "information...", MB_ICONINFORMATION);
          else MessageBox(0, "the service is stopped, but removing failed", "warning...",     MB_ICONWARNING);
        }
        else
          MessageBox(0, "stopping failed", "warning...", MB_ICONWARNING);
      }
      else
      {
        if (b1)
          // not all parameters are correct, so we try to correct them
          if (ChangeServiceConfig(c2, CServiceType, CServiceStart, SERVICE_ERROR_NORMAL,
                                  arrCh, NULL, NULL, NULL, NULL, NULL, CServiceDescr))
               MessageBox(0, "correction of service parameters succeeded", "information...", MB_ICONINFORMATION);
          else MessageBox(0, "correction of service parameters failed",    "warning...",     MB_ICONWARNING);
        if (ss.dwCurrentState != SERVICE_RUNNING)
          // our service was installed, but not running, so we start it
          if (StartService(c2, 0, NULL))
               MessageBox(0, "the service was restarted", "information...", MB_ICONINFORMATION);
          else MessageBox(0, "restarting failed",         "warning...",     MB_ICONWARNING);
      }
      CloseServiceHandle(c2);
    }
    else
    {
      // probably our service is not installed yet, so we do that now
      c2 = CreateService(c1, CServiceName, CServiceDescr,
                         SERVICE_ALL_ACCESS | STANDARD_RIGHTS_ALL,
                         CServiceType, CServiceStart,
                         SERVICE_ERROR_NORMAL, arrCh, NULL, NULL, NULL, NULL, NULL);
      if (c2)
      {
        // installation went smooth
        // we want to give everyone full access to our service
        if (!AddAccessForEveryone(c2, SERVICE_ALL_ACCESS | DELETE))
          MessageBox(0, "access manipulation didn't work", "warning...", MB_ICONWARNING);
        // now let's start the service
        if (StartService(c2, 0, NULL))
        {
          // starting succeeded, but does the service run through?
          // the service tries to create an ipc queue
          // if that fails, it stops and removes itself
          ss.dwCurrentState = SERVICE_STOPPED;
          for (i1 = 1; (i1 < 50); i1++)
          {
            if (!ControlService(c2, SERVICE_CONTROL_INTERROGATE, &ss))
              ss.dwCurrentState = SERVICE_STOPPED;
            if ((ss.dwCurrentState == SERVICE_RUNNING) || (ss.dwCurrentState == SERVICE_STOPPED))
              break;
            Sleep(50);
          }
          if (ss.dwCurrentState == SERVICE_RUNNING)
               MessageBox(0, "the service is installed now",      "information...", MB_ICONINFORMATION);
          else MessageBox(0, "installation failed (ipc failure)", "warning...",     MB_ICONWARNING);
        }
        else 
          MessageBox(0, "installation succeeded, but starting failed", "warning...", MB_ICONWARNING);
        CloseServiceHandle(c2);
      }
      else
        MessageBox(0, "you don't have enough privileges", "sorry...", MB_ICONWARNING);
    }
    CloseServiceHandle(c1);
  }
  else
    MessageBox(0, "you don't have enough privileges", "sorry...", MB_ICONWARNING);
}

// ***************************************************************

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
  if (AmSystemProcess())
    RunService();
  else
    InstallService();
  return true;
}
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: InjectLibrary failed on microsoft windows server 2003

Post by ameetmalekar »

Hi,

Thanks for reply,

Here is the scenario in which it is not working.

The injector service is running on the 2003 machine. If i take another session with same user using RDP of that machine and run target process on that session then InjectLibrary fails. But it is working fine if I run target process on main session(without RDP). We also tried with your code but result is same.
madshi
Site Admin
Posts: 10754
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibrary failed on microsoft windows server 2003

Post by madshi »

You didn't say anything about RDP until now. Would be nice to have all the information before I try to reproduce a problem...

Can you please retest with the latest build, just to be safe?

http://madshi.net/madCollectionBeta.exe (installer 2.7.7.9)
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: InjectLibrary failed on microsoft windows server 2003

Post by ameetmalekar »

Sorry for that :sorry: , but we didn't think that RDP could be the reason.
Checked with new beta version (2.7.7.13) but still it is not able to inject with the scenario.
Post Reply