InjectLibraryW() between sessions in windows 7/8?

c++ / delphi package - dll injection and api hooking
Post Reply
TCS
Posts: 33
Joined: Tue Aug 19, 2014 8:58 pm

InjectLibraryW() between sessions in windows 7/8?

Post by TCS »

Hey,

I am trying to call "InjectLibraryW()" from windows service to a 32bit application in another session, but the function fails, and GetLastError() return ERROR_SUCCESS.
Is it even possible? or do I have to create a new process in the other session?


Thanks in advance!
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: InjectLibraryW() between sessions in windows 7/8?

Post by iconic »

Injecting from a service will work for any process in any session (assuming it's not smss or a Windows protected process such as audiodg.exe which are special exceptions). Where is your DLL located on disk, is it accessible to all processes i.e> C:\? Lastly, are you injecting with special flags or injecting into a single process? What does your InjectLibraryW() call look like? Is this Delphi or c/c++?

--Iconic
TCS
Posts: 33
Joined: Tue Aug 19, 2014 8:58 pm

Re: InjectLibraryW() between sessions in windows 7/8?

Post by TCS »

Sorry it took me a while to answer!

First of all, I had a little mistake, the error returns is ERROR_INVALID_PARAMETER. I guess I am missing something :-( .

The DLL is located on the disk, and I am giving the function the full path:
c:\program files\....\injectee.dll

The HANDLE to the injected process (which is explorer.exe) is valid with PROCESS_ALL_ACCESS permissions.
The code I am executing is (C++):

Code: Select all

BOOL is_injected = InjectLibraryW(fullpath_dll.c_str(), (HANDLE)proc_handle, 10000);
is_injected is FALSE.

I should also point out that I am not using the injection driver (it is not loaded).

Thanks again!
TCS
Posts: 33
Joined: Tue Aug 19, 2014 8:58 pm

Re: InjectLibraryW() between sessions in windows 7/8?

Post by TCS »

Just an update, I am getting "ERROR_INVALID_PARAMETER" not "ERROR_SUCCESS".
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibraryW() between sessions in windows 7/8?

Post by madshi »

Some questions:

(1) Have you called InitializeMadCHook() before calling InjectLibraryW()?
(2) How are you testing is_injected for true/false? Some people have been using "if (is_injected == FALSE)" in the past, which is not the correct way to check BOOL values, so I'm asking just to be safe.
(3) Try giving the hook dll read/execute NTFS rights for "Everyone", just to make sure it's not an NTFS security rights problem.
(4) Try injecting a dll which is already loaded, e.g. kernel32.dll. Does that return succeess or does that also fail?
TCS
Posts: 33
Joined: Tue Aug 19, 2014 8:58 pm

Re: InjectLibraryW() between sessions in windows 7/8?

Post by TCS »

(1) Have you called InitializeMadCHook() before calling InjectLibraryW()?
Yes, not necessarily in the same thread that is doing the actual inject. Is it important?
I tried to call InitializeMadCHook() in the specific injecting thread and it didn't help much.

(2) How are you testing is_injected for true/false? Some people have been using "if (is_injected == FALSE)" in the past, which is not the correct way to check BOOL values, so I'm asking just to be safe.
Is that okay?

Code: Select all

BOOL is_injected = InjectLibraryW(fullpath_dll.c_str(), (HANDLE)proc_handle, 10000);
		
// if injection itself fails
if(!is_injected)
{
	// handle error
}
(3) Try giving the hook dll read/execute NTFS rights for "Everyone", just to make sure it's not an NTFS security rights problem.
Done. Didn't help.

(4) Try injecting a dll which is already loaded, e.g. kernel32.dll. Does that return succeess or does that also fail?[/quote]
Tried injecting kernel32.dll and got the same result, last error is 0x57...

Important:
Doing these tests I noticed that the injection does succeed (The DLL is being loaded), but the function still returns FALSE. I have to know if the DLL got injected successfully (I can think of workarounds, but I prefer the "correct" way). Looks like I am missing something out.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibraryW() between sessions in windows 7/8?

Post by madshi »

InitializeMadCHook() doesn't have to be called in the same thread, it just needs to be completed before you use madCodeHook in any thread.

Your "if" statement should work just fine.

Try calling EnableAllPrivileges() before calling InjectLibraryW(). Does that help?

Code: Select all

void WINAPI EnableAllPrivileges( void )
{
    HANDLE hToken;


    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        __try
        {
            DWORD returnLength;
            GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &returnLength);
            if (returnLength != 0)
            {
                TOKEN_PRIVILEGES *pTokenPrivileges = (TOKEN_PRIVILEGES *) LocalAlloc(LPTR, returnLength*2);
                if (GetTokenInformation(hToken, TokenPrivileges, pTokenPrivileges, returnLength * 2, &returnLength))
                {
                    LUID backup;
                    if (!LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &backup))
                    {
                        backup.HighPart = 0;
                        backup.LowPart = 0;
                    }
                    LUID restore;
                    if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &restore))
                    {
                        restore.HighPart = 0;
                        restore.LowPart = 0;
                    }
                    LUID owner;
                    if (!LookupPrivilegeValue(NULL, SE_TAKE_OWNERSHIP_NAME, &owner))
                    {
                        owner.HighPart = 0;
                        owner.LowPart = 0;
                    }
                    // Update all the privileges to enable except backup and restore
                    //      Enabling backup/restore privileges breaks Explorer's Samba support
                    for (int i = 0; i < (int) pTokenPrivileges->PrivilegeCount - 1; i++)
                    {
                        if ( ( (pTokenPrivileges->Privileges[i].Luid.HighPart !=  backup.HighPart) ||
                            (pTokenPrivileges->Privileges[i].Luid.LowPart  !=  backup.LowPart)     ) &&
                            ( (pTokenPrivileges->Privileges[i].Luid.HighPart != restore.HighPart) ||
                            (pTokenPrivileges->Privileges[i].Luid.LowPart  != restore.LowPart)     ) &&
                            ( (pTokenPrivileges->Privileges[i].Luid.HighPart !=   owner.HighPart) ||
                            (pTokenPrivileges->Privileges[i].Luid.LowPart  !=   owner.LowPart)     )    )
                        {
                            pTokenPrivileges->Privileges[i].Attributes = pTokenPrivileges->Privileges[i].Attributes | SE_PRIVILEGE_ENABLED;
                        }
                    }
                    AdjustTokenPrivileges(hToken, FALSE, pTokenPrivileges, returnLength, NULL, NULL);
                }
                LocalFree(pTokenPrivileges);
            }
        }
        __finally
        {
            CloseHandle(hToken);
        }
    }
}
And how long does InjectLibraryW() take until it returns? Maybe it gets stuck for the full timeout duration of 10 seconds and then returns with a failure result? Or does it return sooner than that?
TCS
Posts: 33
Joined: Tue Aug 19, 2014 8:58 pm

Re: InjectLibraryW() between sessions in windows 7/8?

Post by TCS »

(1) EnableAllPrivileges() did not work
(2) It does not wait all 10 seconds (it doesn't get stuck inside).
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibraryW() between sessions in windows 7/8?

Post by madshi »

Can you create a little demo project for me which reproduces the problem? That would be great! You can hardcode the process ID if that makes your life easier. I can modify the process ID when compiling and testing here. I'll be on vacation the next week, though, so I won't be able to look into this until the week after that.
TCS
Posts: 33
Joined: Tue Aug 19, 2014 8:58 pm

Re: InjectLibraryW() between sessions in windows 7/8?

Post by TCS »

Okay, I found the problem, but not the solution...

I have a driver that notifies my service when a process has been created. Once I get this message I inject the library into the process.
If I inject at the moment of the notification I get that error, if I wait a bit, I don't.

Is there a way to fix this (lets recall that the injection works!) ???
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: InjectLibraryW() between sessions in windows 7/8?

Post by madshi »

Is it possible that the new process isn't really "known" in user land yet at the moment when you try to inject? If your driver signals the new process to user land very quickly, maybe this could explain this problem? I'm not totally sure, though.

Is there a reason you're not using the madCodeHook driver? It injects the dll from within the driver, which works around any such issues as mentioned above.
Post Reply