第43章:内核6中的DLL注入

由于从 Win 7 开始引入了会话机制,因此使得之前通过 CreateRemoteThread() API 注入的旧方法对某些进程(服务进程)不再适用.

注入非0级的会话层能够成功,而对于0级会话的进程,例如 svchost.exe 会注入失败.

探索一下原因:

在 OD 中打开程序,并输入参数( X64dbg 没有找到能输入参数的地方 ).

可以看到 函数里面调用了 Ex 后缀的函数,跟进后:

里面存在了很多代码.根据书中提示, Ex 后缀的函数,比原来多了一个参数. 但是记住一点, CreateRemoteThread() API 的参数是没有改变的.

多的这一个参数是 lpAttributeList , If lpThreadAttributes is NULL, the thread gets a default security descriptor and the handle cannot be inherited.

看到这里,其实可以发现,这里不是影响其注入的原因.继续向下找:

此处的参数变多, 而且名字中也有创建线程之意, 并且根据书中作者的测试, 如果直接调用 CreateThreadEx() 是可以成功的.

可以推测, 这11个参数中的某些参数, 用了前面的代码计算出的值, 而这些参数引起线程不能成功创建.

从书中得知,真正的不同在 CreateSuspended 值, 使用 CreateThreadEx 成功创建的话该值为1, 而使用 CreateRemoteThread 时该值为0.

并且,书中提到,实际上, CreateThreadEx() 正常工作并且成功创建了线程,但是在后面的API 中,通过判断,没有启动该线程:

自己在做实验时,并没有出现如作者所示的提示, 可能是用的 OD 的版本不一样导致的.

BOOL MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)
{
    HANDLE      hThread = NULL;
    FARPROC     pFunc = NULL;

    if( IsVistaOrLater() )    // Vista, 7, Server2008
    {
        pFunc = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateThreadEx");
        if( pFunc == NULL )
        {
            printf("MyCreateRemoteThread() : GetProcAddress("NtCreateThreadEx") failed!!! [%d]
",
                   GetLastError());
            return FALSE;
        }

        ((PFNTCREATETHREADEX)pFunc)(&hThread,          // 调用 CreateRemoteThread 的内部函数,直接注入,不再需要恢复运行
                                    0x1FFFFF,          // 因为此处 CreateSuspended 为 NULL
                                    NULL,  
                                    hProcess,
                                    pThreadProc,
                                    pRemoteBuf,
                                    FALSE,
                                    NULL,
                                    NULL,
                                    NULL,
                                    NULL);
        if( hThread == NULL )
        {
            printf("MyCreateRemoteThread() : NtCreateThreadEx() failed!!! [%d]
", GetLastError());
            return FALSE;
        }
    }
    else                    // 2000, XP, Server2003
    {
        hThread = CreateRemoteThread(hProcess, 
                                     NULL, 
                                     0, 
                                     pThreadProc, 
                                     pRemoteBuf, 
                                     0, 
                                     NULL);
        if( hThread == NULL )
        {
            printf("MyCreateRemoteThread() : CreateRemoteThread() failed!!! [%d]
", GetLastError());
            return FALSE;
        }
    }

    if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )
    {
        printf("MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]
", GetLastError());
        return FALSE;
    }

    return TRUE;
}
原文地址:https://www.cnblogs.com/Rev-omi/p/13546999.html