Skip to content

DLL Injector via Thread Context

mumusan edited this page Sep 17, 2014 · 3 revisions

SetThreadContext DLL Injection

via nerd.egloos.com

void __declspec(naked) InjectFunction()
{
    __asm
    {
        PUSHAD
        MOV EAX, 0xAAAAAAAA //eventually the address of LoadLibraryA

        PUSH 0xBBBBBBBB //eventually the module name
        call EAX

        POPAD
        //vc is pissy and requires us to emit the hardcoded jump
        __emit 0xE9
        __emit 0xCC
        __emit 0xCC
        __emit 0xCC
        __emit 0xCC
    }
}

void __declspec(naked) AfterFunction()
{
}

void InjectDll( HANDLE hProc, HANDLE hThread, char *DllName )
{
    //hold up
    SuspendThread( hThread );

    //get the thread context
    CONTEXT ThreadContext;
    ThreadContext.ContextFlags = CONTEXT_FULL;
    GetThreadContext( hThread, &ThreadContext );

    //copy the function to a tmp buffer
    ULONG FunctionSize = (PBYTE)AfterFunction - (PBYTE)InjectFunction;
    PBYTE LocalFunction = new BYTE[FunctionSize];
    memcpy( LocalFunction, InjectFunction, FunctionSize );

    //allocate a remote buffer
    PBYTE InjData = 
    (PBYTE)VirtualAllocEx( hProc, NULL, FunctionSize + strlen(DllName)+1, 
    MEM_COMMIT, PAGE_EXECUTE_READWRITE );

    //fixup the tmp buff
    for( ULONG i = 0;i < FunctionSize-3; i++ )
    {
        if ( *(PULONG)&LocalFunction[i] == 0xAAAAAAAA )
        {
            *(PULONG)&LocalFunction[i] = (ULONG)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "LoadLibraryA" );
        }
        if ( *(PULONG)&LocalFunction[i] == 0xBBBBBBBB )
        {
            *(PULONG)&LocalFunction[i] = (ULONG)InjData + FunctionSize;
        }
        if ( *(PULONG)&LocalFunction[i] == 0xCCCCCCCC )
        {
           *(PULONG)&LocalFunction[i] = ThreadContext.Eip - ((ULONG)&InjData[i] + 4) ;
        }
    }

    //write the tmp buff + dll
    //Format: [RemoteFunction][DllName][null char]
    ULONG dwWritten;
    WriteProcessMemory( hProc, InjData, LocalFunction, FunctionSize, &dwWritten );
    WriteProcessMemory( hProc, InjData + FunctionSize, DllName, strlen(DllName)+1, &dwWritten );

    //set the EIP
    ThreadContext.Eip = (ULONG)InjData;
    SetThreadContext( hThread, &ThreadContext );

    //resume the thread
    ResumeThread( hThread );
}

.Net relative

For .Net Advanced Threading Library additinally we need to get native Win32 handle of .Net thead which is very simple task. On this basis we'll make InjectedSynchronizationContext for any thread, which initially not supported message loops