用什么方法可以将指定DLL插入到另一个进程的地址空间中,以便挂接其它进程?
感激不尽

解决方案 »

  1.   

    ----------------------  Injection.h ----------------------
    #pragma once
    #include<windows.h>
    //允许远程调试 
    #define ENABLE_REMOTE_DEBUG 0#pragma pack(push)
    #pragma pack(4)
    typedef struct
    {
    FARPROC _LoadLibrary;
    FARPROC _GetProcAddress;
    DWORD dwParam;
    char szFileName[500];
    char szEntry[100];
    }InjectionStruct;
    #pragma pack(pop)BOOL InjectWindow(HWND hWindow,LPCSTR szModule,LPCSTR szEntry);
    BOOL InjectProcess(DWORD dwProcessID,LPCSTR szModule,LPCSTR szEntry,DWORD dwParam);----------------------  Injection.cpp ----------------------
    #include "Injection.h"BYTE lpShellCode[]=
    {
    #if ENABLE_REMOTE_DEBUG==1
    0xCC, //int 3
    #endif
    0xE8,0x00,0x00,0x00,0x00, //CALL HI.00401209
    0x5B, //POP EBX
    0x81,0xEB,0x09,0x12,0x40,0x00,  //SUB EBX,HI.00401209                      ;  入口地址BX,H
    0x8D,0x83,0x44,0x12,0x40,0x00, //LEA EAX,DWORD PTR DS:[EBX+____FileName]
    0x50, //PUSH EAX
    0xFF,0x93,0x38,0x12,0x40,0x00,  //CALL DWORD PTR DS:[EBX+DataPool]
    0x8D,0x93,0x38,0x14,0x40,0x00, //LEA EDX,DWORD PTR DS:[EBX+____Entry]
    0x52, //PUSH EDX
    0x50, //PUSH EAX
    0xFF,0x93,0x3C,0x12,0x40,0x00,  //CALL DWORD PTR DS:[EBX+____GetProcAddres>
    0x0B,0xC0, //OR EAX,EAX
    0x74,0x08, //JE SHORT HI.00401237
    0xFF,0xB3,0x40,0x12,0x40,0x00,  //PUSH DWORD PTR DS:[EBX+____Window]
    0xFF,0xD0, //CALL EAX
    0xC3 //RETN
    };
    BOOL InjectProcess(DWORD dwProcessID,LPCSTR szModule,LPCSTR szEntry,DWORD dwParam)
    {
    InjectionStruct inject;

    DWORD dwBytesWritten;
    HMODULE hMod=GetModuleHandle("kernel32.dll");
    HANDLE hProcess;
    LPVOID lpRemoteCode;
    HANDLE hThread;
    DWORD dwShellCodeSize=sizeof(lpShellCode);

      inject._LoadLibrary=GetProcAddress(hMod,"LoadLibraryA");
    inject._GetProcAddress=GetProcAddress(hMod,"GetProcAddress");
    inject.dwParam=dwParam;
    strcpy(inject.szFileName,szModule);
    strcpy(inject.szEntry,szEntry);

    hProcess=OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE,FALSE,dwProcessID);
    if(hProcess)
    {
    lpRemoteCode=VirtualAllocEx(hProcess,NULL,dwShellCodeSize + sizeof(InjectionStruct),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    if(lpRemoteCode)
    {
    WriteProcessMemory(hProcess,lpRemoteCode,lpShellCode,dwShellCodeSize,&dwBytesWritten);
    WriteProcessMemory(hProcess,(LPBYTE)lpRemoteCode+dwShellCodeSize,&inject,sizeof(InjectionStruct),&dwBytesWritten);
    hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)lpRemoteCode,NULL,0,0);
    CloseHandle(hThread);
    return TRUE;
    }
    }
    return FALSE;
    }BOOL InjectWindow(HWND hWindow,LPCSTR szModule,LPCSTR szEntry)
    {
    DWORD dwProcessID;
    GetWindowThreadProcessId(hWindow,&dwProcessID);
    return InjectProcess(dwProcessID,szModule,szEntry,(DWORD)hWindow);
    }
    以前写的一段代码。
    其中szModule是需要插入的DLL的地址,szEntry是插入到进程后执行的入口函数名
    其中DLL中导出的szEntry必须满足以下原形:
    VOID (WINAPI*)(DWORD dwParam)
    如果用第二个InjectWindow,则传入的dwParam为被插入的窗口的HWND
      

  2.   

    感谢 lexchou(龍子龍孫) 和 kugou123(酷狗)的回复,我试试先~~~~
    其它高手如果有更好的方法,也请赐教,不胜感激!
      

  3.   

    还有有一种方法是安装windows hook,只要目标程序有响应的消息,你可以在你的回调函数中,判断进程名,如果是目标进程就可以LoadLibrary,这种方法保险些,注入远端线程的方法兼容性不是太好,很多进程无法注入
      

  4.   

    注入之前要先获得权限,参见http://blog.csdn.net/jiangsheng/archive/2003/11/09/3789.aspx
      

  5.   

    通过NT Native API NtLdrLoadModule()配合CreateRemoteThread()
    好处是对于不加载Kernel32的进程也有效,缺点是编程比较困难