最近研究远程线程注入,发现这样一个问题,用自己写好的程序A将我的My.dll注入B进程作为其线程运行,
发现,如果B进程只有一个线程则注入成功,如果B进程为多线程,则注入失败,不知道什么原因

解决方案 »

  1.   

    进程A负责将My.dll插入到进程B地址空间,进程B是简单的基于对话框的应用程序,My.dll如果被成功插入到
    进程B 的地址空间,其弹出一个对话框。
    现在情况是这样的,先运行B,然后运行A将My.dll插入B的地址空间,结果成功。但当把B换成一个系统进程时
    例如EXPLORER.EXE,则弹出一个程序中止对话框,意思是EXPLORER.EXE所引用的内存不能为读。
    为什么插入的进程B是我自己写的就没问题。
    我把自己写的进程B中再开一个线程,结果也出现同样的错误。
      

  2.   

    你是不是在dll做了一些非法的操作呢?
      

  3.   

    jiang1013nan:
    My.dll没做什么,就是开了一个线程,在线程里弹出一个对话框,我试过了,My.dll不开线程,什么都不做也会有这个问题
      

  4.   

    我觉得应该是负责插入My.ddl的程序A的问题,该函数如下,可为什么进程能插入成功呢
    BOOL RemoteLoadLibrary(DWORD hProcessId,LPCSTR lpszDll)
    {
    DWORD dwWrite;
    DWORD dwSize=strlen(lpszDll)+1;
    //通过进程ID打开该运行进程的一个句柄,并请求适当的访问权限
    HANDLE hProcess=OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_VM_READ,FALSE,hProcessId);
    //需要将要注入的dll的路径字符串放入远程进程的地址空间中
    //然后当CreateRemoteThread时,需要将所放置字符串的地址传递给它
    //因此,首先要分配目标进程的地址空间中的内存,用于储存dll路径字符串
    LPVOID lpBuf=VirtualAllocEx(hProcess,NULL,dwSize,MEM_COMMIT,PAGE_READWRITE);
    if(0==lpBuf)
    {
    CloseHandle(hProcess);
    return FALSE;
    }
    //向远程进程中写入数据,即dll路径名
    if(WriteProcessMemory(hProcess,lpBuf,(LPVOID)lpszDll,dwSize,&dwWrite))
    {
    if(dwSize != dwWrite)
    {
    //此函数用于释放内存,当写入失败或是执行结束后,都要释放远程进程中被占用的内存
    VirtualFreeEx(hProcess,lpBuf,dwSize,MEM_DECOMMIT);
    CloseHandle(hProcess);
    return FALSE;
    }
    }
    else
    {
    VirtualFreeEx(hProcess,lpBuf,dwSize,MEM_DECOMMIT);
    CloseHandle(hProcess);
    return FALSE;
    }
    HMODULE hModule ; 
    hModule =GetModuleHandle ("kernel32.dll") ;
    LPTHREAD_START_ROUTINE fnStartAddr ; 
    fnStartAddr = ( LPTHREAD_START_ROUTINE ) GetProcAddress ( hModule, "LoadLibraryA" ) ;
    //在另一个进程中创建线程,此线程调用LoadLibrary以加载所需要的dll
    HANDLE hThread=CreateRemoteThread(hProcess,NULL,0,fnStartAddr,lpBuf,0,NULL);
    // HANDLE hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)lpFunc,lpBuf,0,&dwId);
    if(hThread==NULL)
    {
    VirtualFreeEx(hProcess,lpBuf,dwSize,MEM_DECOMMIT);
    CloseHandle(hProcess);
    return FALSE;
    }
    //检测hThread事件的信号状态,并设置直到事件变成有信号状态才返回,否则将一直等下去
    WaitForSingleObject(hThread,INFINITE);
    VirtualFreeEx(hProcess,lpBuf,dwSize,MEM_DECOMMIT);
    CloseHandle(hThread);
    CloseHandle(hProcess);
    return TRUE;
    }
      

  5.   

    Tr0j4n:
        写错了,是有的进程能插入成功,插入成功的进程B是最简单的基于对话框的应用程序,可以插入成功
    但在这个基于对话框的应用程序里开一个线程,结果就会失败,弹出一个应用程序终止的对话框,B被强行终止
      

  6.   

    你创建线程是在那个DLL里面的PROCESS_ATTACH里面做的吧
      

  7.   

    Tr0j4n:
           dll是基于MFC的动态链接库,在InitInstance()里创建线程,我用其它的dll文件试过了,包括
    《windows核心编程》里边的用于枚举进程DLL的那个ImgWalk.ddl,也是这个问题
      

  8.   

    贴代码吧,到底有有没有注入成功都不知道哦。我怀疑是THREAD_ATTACH的dll,然后重复注入或者初始化等一些工作。
      

  9.   

    自己调试一下,看看哪里异常,可以这样调试:把My.dll设置为启动项目,调试命令行设置为B.exe,设置好断点后按F5启动调试,再手动运行A.exe注入。
      

  10.   

    谢谢cnzdgs,
    今天又调试了一下,居然成功了,代码什么都没改,
    仔细想了想,忽然想到自己电脑里装了一个流量监控软件客户端NepViewClient.exe,是海王星网络流量监控
    的客户端,它为了让自己不被客户关闭,也使用了dll注入,它有两个注入的dll文件,haiblock.dll和wwinlib.dll,目的是让任务管理器中的进程列表中隐藏自己,我想应该是挂接了枚举进程的API函数,
    调试成功,就是这个客户端被我关闭掉了,我了证明想法,我又把它启动,结果注入就是失败,具体haiblock.dll与wwinlib.dll做了什么使我自己的代码注入失败,还没弄明白,但有一点可以肯定haiblock.dll与wwinlib.dll这两个dll被注入到了所有进程里。