VC++另类实现进程插入

来源:岁月联盟 编辑:exp 时间:2012-08-02
[cpp] 
// WaiGuaTestDlg.cpp : implementation file 
// 
 

#include "stdafx.h" 
#include "WaiGuaTest.h" 
#include "WaiGuaTestDlg.h" 
 
#include "Tlhelp32.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CAboutDlg dialog used for App About 
 
class CAboutDlg : public CDialog 

public: 
    CAboutDlg(); 
     
    // Dialog Data 
    //{{AFX_DATA(CAboutDlg) 
    enum { IDD = IDD_ABOUTBOX }; 
    //}}AFX_DATA 
     
    // ClassWizard generated virtual function overrides 
    //{{AFX_VIRTUAL(CAboutDlg) 
protected: 
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support 
    //}}AFX_VIRTUAL 
     
    // Implementation 
protected: 
    //{{AFX_MSG(CAboutDlg) 
    //}}AFX_MSG 
    DECLARE_MESSAGE_MAP() 
}; 
 
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) 

    //{{AFX_DATA_INIT(CAboutDlg) 
    //}}AFX_DATA_INIT 

 
void CAboutDlg::DoDataExchange(CDataExchange* pDX) 

    CDialog::DoDataExchange(pDX); 
    //{{AFX_DATA_MAP(CAboutDlg) 
    //}}AFX_DATA_MAP 

 
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) 
//{{AFX_MSG_MAP(CAboutDlg) 
// No message handlers 
//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CWaiGuaTestDlg dialog 
 
CWaiGuaTestDlg::CWaiGuaTestDlg(CWnd* pParent /*=NULL*/) 
: CDialog(CWaiGuaTestDlg::IDD, pParent) 

    //{{AFX_DATA_INIT(CWaiGuaTestDlg) 
    m_ProcName = _T(""); 
    //}}AFX_DATA_INIT 
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 

 
void CWaiGuaTestDlg::DoDataExchange(CDataExchange* pDX) 

    CDialog::DoDataExchange(pDX); 
    //{{AFX_DATA_MAP(CWaiGuaTestDlg) 
    DDX_CBString(pDX, IDC_COM_Proc, m_ProcName); 
    //}}AFX_DATA_MAP 

 
BEGIN_MESSAGE_MAP(CWaiGuaTestDlg, CDialog) 
//{{AFX_MSG_MAP(CWaiGuaTestDlg) 
ON_WM_SYSCOMMAND() 
ON_WM_PAINT() 
ON_WM_QUERYDRAGICON() 
ON_BN_CLICKED(IDC_BUT_GetProc, OnBUTGetProc) 
ON_BN_CLICKED(IDC_BUT_EXECUTION, OnButExecution) 
//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CWaiGuaTestDlg message handlers 
 
BOOL CWaiGuaTestDlg::OnInitDialog() 

    CDialog::OnInitDialog(); 
     
    // Add "About..." menu item to system menu. 
     
    // IDM_ABOUTBOX must be in the system command range. 
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 
    ASSERT(IDM_ABOUTBOX < 0xF000); 
     
    CMenu* pSysMenu = GetSystemMenu(FALSE); 
    if (pSysMenu != NULL) 
    { 
        CString strAboutMenu; 
        strAboutMenu.LoadString(IDS_ABOUTBOX); 
        if (!strAboutMenu.IsEmpty()) 
        { 
            pSysMenu->AppendMenu(MF_SEPARATOR); 
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 
        } 
    } 
     
    // Set the icon for this dialog.  The framework does this automatically 
    //  when the application's main window is not a dialog 
    SetIcon(m_hIcon, TRUE);         // Set big icon 
    SetIcon(m_hIcon, FALSE);        // Set small icon 
     
    // TODO: Add extra initialization here 
     
    return TRUE;  // return TRUE  unless you set the focus to a control 

 
void CWaiGuaTestDlg::OnSysCommand(UINT nID, LPARAM lParam) 

    if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
    { 
        CAboutDlg dlgAbout; 
        dlgAbout.DoModal(); 
    } 
    else 
    { 
        CDialog::OnSysCommand(nID, lParam); 
    } 

 
// If you add a minimize button to your dialog, you will need the code below 
//  to draw the icon.  For MFC applications using the document/view model, 
//  this is automatically done for you by the framework. 
 
void CWaiGuaTestDlg::OnPaint()  

    if (IsIconic()) 
    { 
        CPaintDC dc(this); // device context for painting 
         
        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); 
         
        // Center icon in client rectangle 
        int cxIcon = GetSystemMetrics(SM_CXICON); 
        int cyIcon = GetSystemMetrics(SM_CYICON); 
        CRect rect; 
        GetClientRect(&rect); 
        int x = (rect.Width() - cxIcon + 1) / 2; 
        int y = (rect.Height() - cyIcon + 1) / 2; 
         
        // Draw the icon 
        dc.DrawIcon(x, y, m_hIcon); 
    } 
    else 
    { 
        CDialog::OnPaint(); 
    } 

 
// The system calls this to obtain the cursor to display while the user drags 
//  the minimized window. 
HCURSOR CWaiGuaTestDlg::OnQueryDragIcon() 

    return (HCURSOR) m_hIcon; 

 
void CWaiGuaTestDlg::OnBUTGetProc()  

    // TODO: Add your control notification handler code here 
    ((CComboBox *)GetDlgItem(IDC_COM_Proc))->ResetContent(); 
     
    for(int i=0 ; i < 100 ; i++) 
        szThreadId[i] = 0; 
     
    HANDLE hSnapShot; 
    PROCESSENTRY32 szEntry; 
     
    szEntry.dwSize = sizeof(PROCESSENTRY32); 
     
    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS , 0); 
     
    if(hSnapShot == INVALID_HANDLE_VALUE) 
    { 
        MessageBox("CreateToolhelp32Snapshot Error!"); 
        return; 
    } 
     
    if(Process32First(hSnapShot,&szEntry)) 
    { 
        int i=1; 
        ((CComboBox *)GetDlgItem(IDC_COM_Proc))->AddString(szEntry.szExeFile); 
         
        szThreadId[0] = szEntry.th32ProcessID; 
         
        while(Process32Next(hSnapShot,&szEntry)) 
        { 
            ((CComboBox *)GetDlgItem(IDC_COM_Proc))->AddString(szEntry.szExeFile); 
            szThreadId[i] = szEntry.th32ProcessID; 
            i++; 
        } 
         
        MessageBox("获取系统进程列表成功"); 
        ((CComboBox *)GetDlgItem(IDC_COM_Proc))->SetCurSel(i-1); 
         
        return; 
    } 

 
void CWaiGuaTestDlg::OnButExecution()  

    // TODO: Add your control notification handler code here 
     
    //*******跳过远程线程代码,执行本程序******* 
    goto REMOTE_THREAD_END; 
     
     
    ////////////////////////////////////////////////////////////////////////// 
    //////*******远程线程代码******* 
    ////////////////////////////////////////////////////////////////////////// 
REMOTE_THREAD_BEGIN: 
     
    _asm     
    { 
        //*******给LoadLibrary函数地址占位******* 
LoadLibraryAddr: 
        nop 
        nop 
        nop 
        nop 
        //*******给FreeLibrary函数地址占位******* 
FreeLibraryAddr: 
        nop 
        nop 
        nop 
        nop 
        //*******给动态链接库名占位******* 
LibraryName: 
        nop 
        nop 
        nop 
        nop 
        nop 
        nop 
        nop 
        nop 
         
 
        //*******代码开始的真正位置******* 
REMOTE_THREAD_CODE:  
     
        //*******实现地址重定位,ebx保存差值******* 
        call    relocal 
relocal: 
        pop     ebx 
        sub     ebx , offset relocal 
         
        ////////////////////////////////////////////////////////////////////////// 
        //*******调用LoadLibrary******* 
        ////////////////////////////////////////////////////////////////////////// 
        //*******压入LoadLibrary参数(动态链接库名)******* 
        mov     eax , ebx 
        add     eax , offset LibraryName 
        push    eax 
         
        //*******调用LoadLibrary******* 
        mov     eax , ebx 
        add     eax , offset LoadLibraryAddr 
        mov     eax , [eax] 
        call    eax 
         
        or      eax , eax 
        jnz     NEXT1 
        ret 
        ////////////////////////////////////////////////////////////////////////// 
        //*******以上调用LoadLibrary******* 
        ////////////////////////////////////////////////////////////////////////// 
 
NEXT1: 
        // *******压入FreeLibrary参数******* 
        push    eax 
         
        // *******调用FreeLibrary******* 
        mov     eax , ebx 
        add     eax , offset FreeLibraryAddr 
        mov     eax , [eax] 
        call    eax 
        ////////////////////////////////////////////////////////////////////////// 
        //*******以上调用FreeLibrary******* 
        ////////////////////////////////////////////////////////////////////////// 
        ret 
         
    } 
REMOTE_THREAD_END: 
    ////////////////////////////////////////////////////////////////////////// 
    ////以上为远程线程代码 
    ////////////////////////////////////////////////////////////////////////// 
     
     
    //*******首先获取选中的进程句柄******* 
     
    int nSelectedThreadId; 
    nSelectedThreadId = ((CComboBox *)GetDlgItem(IDC_COM_Proc))->GetCurSel(); 
     
    nSelectedThreadId = szThreadId[nSelectedThreadId]; 
     
    HANDLE hSelectedProcHandle; 
     
    hSelectedProcHandle = OpenProcess(PROCESS_ALL_ACCESS , FALSE , nSelectedThreadId); 
    if(!hSelectedProcHandle) 
    { 
        MessageBox("打开进程失败!"); 
        return; 
    } 
     
    // *******得到远程线程代码长度******* 
     
    int nRemoteThreadCodeLength; 
     
    _asm  
    { 
        mov eax , offset REMOTE_THREAD_END 
            mov ebx , offset REMOTE_THREAD_BEGIN 
            sub eax , ebx 
            mov nRemoteThreadCodeLength , eax 
    } 
     
    // *******在宿主进程中申请远程线程代码空间******* 
     
    LPVOID pRemoteThreadAddr; 
     
    pRemoteThreadAddr = VirtualAllocEx(hSelectedProcHandle , NULL , nRemoteThreadCodeLength ,  
        MEM_COMMIT,PAGE_EXECUTE_READWRITE); 
     
    if(!pRemoteThreadAddr) 
    { 
        MessageBox("Alloc Memory Error!"); 
        return; 
    } 
     
     
    //*******向宿主进程空间中复制远程线程代码******* 
     
    LPVOID  pRemoteThreadCodeBuf; 
    DWORD   nWritenNum , nSuccess; 
     
    _asm mov    eax , offset REMOTE_THREAD_BEGIN 
        _asm mov    pRemoteThreadCodeBuf , eax 
         
        nSuccess = WriteProcessMemory(hSelectedProcHandle , pRemoteThreadAddr , pRemoteThreadCodeBuf , 
        nRemoteThreadCodeLength , &nWritenNum); 
     
    if(!nSuccess) 
    { 
        MessageBox("Copy Remote Thread Code Error!"); 
        return; 
    } 
     
     
     
     
     
    // *******修正远程线程代码******* 
     
    // *******首先获取两个关键函数的地址******* 
     
    HMODULE hKernel32; 
    hKernel32 = LoadLibrary("Kernel32.dll"); 
     
    if(!hKernel32) 
    { 
        MessageBox("导入Kernel32.dll错误!"); 
        return; 
    } 
     
    LPVOID pLoadLibrary , pGetProcAddress , pFreeLibrary; 
     
    pLoadLibrary = (LPVOID)GetProcAddress(hKernel32 , "LoadLibraryA"); 
     
    if(!pLoadLibrary) 
    { 
        MessageBox("获取LoadLibrary函数地址失败!"); 
        return; 
    } 
     
    pGetProcAddress = (LPVOID)GetProcAddress(hKernel32 , "GetProcAddress"); 
     
    if(!pGetProcAddress) 
    { 
        MessageBox("获取GetProcAddress函数地址失败!"); 
        return; 
    } 
     
    pFreeLibrary = (LPVOID)GetProcAddress(hKernel32 , "FreeLibrary"); 
     
    if(!pGetProcAddress) 
    { 
        MessageBox("获取FreeLibrary函数地址失败!"); 
        return; 
    } 
     
    // *******修正代码******* 
     
    PBYTE pRemoteAddrMove; 
     
    pRemoteAddrMove = (PBYTE)pRemoteThreadAddr; 
     
    // *******修正LoadLibrary地址******* 
     
    nSuccess = WriteProcessMemory(hSelectedProcHandle ,  
        pRemoteAddrMove ,  
        &pLoadLibrary , 
        4 ,  
        &nWritenNum); 
     
    if(!nSuccess) 
    { 
        MessageBox("修正LoadLibrary地址错误!"); 
        return; 
    } 
     
    //*******修正FreeLibrary地址******* 
     
    pRemoteAddrMove +=4; 
     
    nSuccess = WriteProcessMemory(hSelectedProcHandle , 
        pRemoteAddrMove ,  
        &pFreeLibrary , 
        4 , 
        &nWritenNum); 
     
    if(!nSuccess) 
    { 
        MessageBox("修正FreeLibrary地址错误!"); 
        return; 
    } 
     
    //*******传递动态链接库名******* 
     
    char szDllName[8] = {"Dll.dll"}; 
     
    pRemoteAddrMove +=4; 
     
    nSuccess = WriteProcessMemory(hSelectedProcHandle ,  
        pRemoteAddrMove ,  
        szDllName , 
        8 ,  
        &nWritenNum); 
     
    if(!nSuccess) 
    { 
        MessageBox("修正GetProcAddress地址错误!"); 
        return; 
    } 
     
    //********把指针移动到远程线程代码开始处******* 
    pRemoteAddrMove +=8; 
     
    // *******创建远程线程******* 
     
    HANDLE hRemoteThreadHandle; 
     
    // *******定义远程线程函数类型******* 
    typedef unsigned long (WINAPI *stRemoteThreadProc)(LPVOID); 
     
    stRemoteThreadProc pRemoteThreadProc; 
     
    // *******把入口地址赋给声明的函数******* 
    pRemoteThreadProc = (stRemoteThreadProc)pRemoteAddrMove; 
     
    hRemoteThreadHandle = CreateRemoteThread(hSelectedProcHandle , NULL , 0 ,  
        pRemoteThreadProc , 0 , 0 , NULL); 
     
     
    //*******测试******* 
    CString szBuf; 
    szBuf.Format("开始地址:%x/nLoadLibrary地址:%x/nGetProcAddress地址%x/n代码开始地址:%x" ,  
        pRemoteThreadAddr , pLoadLibrary , pGetProcAddress , pRemoteAddrMove); 
    MessageBox(szBuf);   
     
     
    return;