VC++另类实现进程插入
2012-08-02 13:07:33 来源:WEB开发网核心提示:// WaiGuaTestDlg.cpp : implementation file//#include "stdafx.h"#include "WaiGuaTest.h"#include "WaiGuaTestDlg.h"#include "Tlh
// 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; }
更多精彩
赞助商链接