[分析]detours 通过修改输入表注入DLL -- UpdateImports 函数的分析

前段时间有一个需求,就是在进程启动的第一时间实现dll的注入,当时一想以为很简单嘛,比如拦截CreateProcessInternalW等不就行了吗?后来发现如果你在CreateProcessInternalW前处理进程还没有启动,而之后处理的话,进程的主线程已经开始工作了,再后来通过修改创建标志把创建的进程的主线程挂起,等进程创建后我来注入,此时才发现创建远线程搞不定, 此时进程只有NTDLL,其他模块还没有加载呢.再最后终于发现了detours 2.1为我们提供了一个函数DetourCreateProcessWithDllW,它可以实现在进程创建初期就将dll加载进去,下面我就来分析一下detours怎么做到在进程初期就将dll加载进程的.

先来看DetourCreateProcessWithDllW函数,可以分为四个步骤:

BOOL 
WINAPI 
DetourCreateProcessWithDllW(LPCWSTR lpApplicationName,
                            __in_z LPWSTR lpCommandLine,
                            LPSECURITY_ATTRIBUTES lpProcessAttributes,
                            LPSECURITY_ATTRIBUTES lpThreadAttributes,
                            BOOL bInheritHandles,
                            DWORD dwCreationFlags,
                            LPVOID lpEnvironment,
                            LPCWSTR lpCurrentDirectory,
                            LPSTARTUPINFOW lpStartupInfo,
                            LPPROCESS_INFORMATION lpProcessInformation,
                            LPCSTR lpDetouredDllFullName,
                            LPCSTR lpDllName,
                            PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW)
{
    
// 第一步:修改创建标志位
    DWORD dwMyCreationFlags = (dwCreationFlags | CREATE_SUSPENDED);
    PROCESS_INFORMATION pi;

    
if (pfCreateProcessW == NULL) {
        pfCreateProcessW 
= CreateProcessW;
    }


    
// 第二步:调用原始CreateProcessW
    if (!pfCreateProcessW(lpApplicationName,
                          lpCommandLine,
                          lpProcessAttributes,
                          lpThreadAttributes,
                          bInheritHandles,
                          dwMyCreationFlags,
                          lpEnvironment,
                          lpCurrentDirectory,
                          lpStartupInfo,
                          
&pi)) {
        
return FALSE;
    }


    LPCSTR rlpDlls[
2];
    DWORD nDlls 
= 0;
    
if (lpDetouredDllFullName != NULL) {
        rlpDlls[nDlls
++= lpDetouredDllFullName;
    }

    
if (lpDllName != NULL) {
        rlpDlls[nDlls
++= lpDllName;
    }


    
// 第三步: 修改目标进程的输入表
    if (!UpdateImports(pi.hProcess, rlpDlls, nDlls)) {
        
return FALSE;
    }


    
if (lpProcessInformation) {
        CopyMemory(lpProcessInformation, 
&pi, sizeof(pi));
    }


    
// 第四步: 让目标进程的主线程继续运行
    if (!(dwCreationFlags & CREATE_SUSPENDED)) {
        ResumeThread(pi.hThread);
    }

    
return TRUE;
}

呵呵,看出来了,原来detours使用的是修改输入表来实现dll的注入的,在来看其中最关键的函数UpdateImports,

BOOL WINAPI UpdateImports(HANDLE hProcess, LPCSTR  * plpDlls, DWORD nDlls)
{
    BOOL fSucceeded 
= FALSE;
    BYTE 
* pbNew = NULL;
    DETOUR_EXE_RESTORE der;
    DWORD i;

    ZeroMemory(
&der, sizeof(der));
    der.cb 
= sizeof(der);

    
// 从 0x10000 开始寻找MEM_IMGAE标志的内存,然后验证其是否是exe
    
// 如果是那么返回其首地址
    PBYTE pbModule = (PBYTE)FindExe(hProcess);

    IMAGE_DOS_HEADER idh;
    ZeroMemory(
&idh, sizeof(idh));

    
// 读取 IMAGE_DOS_HEADER
    if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {
        DETOUR_TRACE((
"ReadProcessMemory(idh) failed: %d ", GetLastError()));

      finish:
        
if (pbNew != NULL) {
            delete[] pbNew;
            pbNew 
= NULL;
        }

        
return fSucceeded;
    }

    CopyMemory(
&der.idh, &idh, 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值