zoukankan      html  css  js  c++  java
  • 学习c++ (五) dll注入和卸载

    在学习第一篇时,就直接折腾代码,这是我学习的方法,基础的只是简单过一遍就好了,因为根本记得不够深刻,还是用了之后,才知道真正的含义。

    然后在第一篇的基础上,把卸载加进来了,同时重整理了注入的代码,更重要的是这次的消息接收,抛弃了MFC,直接用的C++写的,感觉真好

    另外,在这个注入和进程的通讯上,还遇到两个问题:

    第一点,对于OpenProcess 时使用的权限最好还是PROCESS_ALL_ACCESS,反正我换了台电脑,就会造成CreateRemoteThread失败

    第二点,在进程的通讯上,也存在权限问题,也就是说接收方如果不做处理 ,可能收不到,在WM_INITDIALOG中使用了ChangeWindowMessageFilter(WM_COPYDATA, 1)来处理一下

    还是直接贴代码,也懒得上工程,有些变量啥的可能看不全,刚入门的同学们对不住了,你们还是慢慢看

    #include "stdafx.h"
    #include "Inject.h"
    
    
    //#include <iostream>;
    //using namespace std;
    //#include <windows.h>;
    //#include <tlhelp32.h>;
    //#include <tchar.h>;
    
    
    
    
    // 提升进程访问权限
    bool enableDebugPriv()
    {
        HANDLE hToken;
        LUID sedebugnameValue;
        TOKEN_PRIVILEGES tkp;
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)
            )
        {
            return false;
        }
        if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
        {
            CloseHandle(hToken);
            return false;
        }
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Luid = sedebugnameValue;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
        {
            CloseHandle(hToken);
            return false;
        }
        return true;
    }
    // 根据进程名称得到进程ID,如果有多个运行实例的话,返回第一个枚举到的进程的ID
    DWORD processNameToId(LPCTSTR lpszProcessName)
    {
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        PROCESSENTRY32 pe;
        pe.dwSize = sizeof(PROCESSENTRY32);
        if (!Process32First(hSnapshot, &pe))
        {
            MessageBox(NULL,
                L"The frist entry of the process list has not been copyied to the buffer",
                L"Notice",
                MB_ICONINFORMATION | MB_OK
            );
            return 0;
        }
        while (Process32Next(hSnapshot, &pe))
        {
            if (!wcscmp(lpszProcessName, pe.szExeFile))
            {
                return pe.th32ProcessID;
            }
        }
        return 0;
    }
    
    
    
    
    bool InjectDll()
    {
        enableDebugPriv();
        DWORD dwProcessId = processNameToId(INJECT_PROCESS_NAME);
        if (dwProcessId == 0)
        {
            MessageBox(NULL,
                L"The target process have not been found !",
                L"Notice",
                MB_ICONINFORMATION | MB_OK
            );
            return FALSE;
        }
    
        return InjectDll(INJECT_DLL_NAME, dwProcessId);
    }
    
    bool InjectDll(const TCHAR* ptszDllFile, DWORD dwProcessId)
    {
        // 参数无效   
        if (NULL == ptszDllFile || 0 == ::_tcslen(ptszDllFile))
        {
            return false;
        }
        // 指定 Dll 文件不存在   
        if (-1 == _taccess(ptszDllFile, 0))
        {
            return false;
        }
        HANDLE hProcess = NULL;
        HANDLE hThread = NULL;
        DWORD dwSize = 0;
        TCHAR* ptszRemoteBuf = NULL;
        LPTHREAD_START_ROUTINE lpThreadFun = NULL;
        // 获取目标进程句柄   
        hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
        if (NULL == hProcess)
        {
            return false;
        }
        // 在目标进程中分配内存空间   
        dwSize = (DWORD)::_tcslen(ptszDllFile) + 1;
        ptszRemoteBuf = (TCHAR*)::VirtualAllocEx(hProcess, NULL, dwSize * sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
        if (NULL == ptszRemoteBuf)
        {
            ::CloseHandle(hProcess);
            return false;
        }
        // 在目标进程的内存空间中写入所需参数(模块名)   
        if (FALSE == ::WriteProcessMemory(hProcess, ptszRemoteBuf, (LPVOID)ptszDllFile, dwSize * sizeof(TCHAR), NULL))
        {
            ::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);
            ::CloseHandle(hProcess);
            return false;
        }
        // 从 Kernel32.dll 中获取 LoadLibrary 函数地址   
    #ifdef _UNICODE   
        lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
    #else   
        lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "LoadLibraryA");
    #endif   
        //LPVOID pFunc = LoadLibraryA;
     
        if (NULL == lpThreadFun)
        {
            ::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);
            ::CloseHandle(hProcess);
            return false;
        }
        // 创建远程线程调用 LoadLibrary   
        hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, ptszRemoteBuf, 0, NULL);
        if (NULL == hThread)
        {
            DWORD error = GetLastError();
            ::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);
            ::CloseHandle(hProcess);
            return false;
        }
        // 等待远程线程结束   
        ::WaitForSingleObject(hThread, INFINITE);
        // 清理   
        ::VirtualFreeEx(hProcess, ptszRemoteBuf, dwSize, MEM_DECOMMIT);
        ::CloseHandle(hThread);
        ::CloseHandle(hProcess);
        return true;
    }
    
    
    bool UnInjectDll()
    {
        enableDebugPriv();
        DWORD dwProcessId = processNameToId(INJECT_PROCESS_NAME);
        if (dwProcessId == 0)
        {
            MessageBox(NULL,
                L"The target process have not been found !",
                L"Notice",
                MB_ICONINFORMATION | MB_OK
            );
            return FALSE;
        }
    
        return UnInjectDll(INJECT_DLL_NAME, dwProcessId);
    }
    
    //-----------------------------------------------------------------------------------------------------------   
    // 函数: UnInjectDll   
    // 功能: 从目标进程中卸载一个指定 Dll 模块文件.   
    // 参数: [in] const TCHAR* ptszDllFile - Dll 文件名及路径   
    //       [in] DWORD dwProcessId - 目标进程 ID   
    // 返回: bool - 卸载成功返回 true, 卸载失败则返回 false.   
    // 说明: 采用远程线程注入技术实现   
    //-----------------------------------------------------------------------------------------------------------   
    bool UnInjectDll(const TCHAR* ptszDllFile, DWORD dwProcessId)
    {
        // 参数无效   
        if (NULL == ptszDllFile || 0 == ::_tcslen(ptszDllFile))
        {
            return false;
        }
        HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
        HANDLE hProcess = NULL;
        HANDLE hThread = NULL;
        // 获取模块快照   
        hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
        if (INVALID_HANDLE_VALUE == hModuleSnap)
        {
            return false;
        }
        MODULEENTRY32 me32;
        memset(&me32, 0, sizeof(MODULEENTRY32));
        me32.dwSize = sizeof(MODULEENTRY32);
        // 开始遍历   
        if (FALSE == ::Module32First(hModuleSnap, &me32))
        {
            ::CloseHandle(hModuleSnap);
            return false;
        }
        // 遍历查找指定模块   
        bool isFound = false;
        do
        {
            isFound = (0 == ::_tcsicmp(me32.szModule, ptszDllFile) || 0 == ::_tcsicmp(me32.szExePath, ptszDllFile));
            if (isFound) // 找到指定模块   
            {
                break;
            }
        } while (TRUE == ::Module32Next(hModuleSnap, &me32));
        ::CloseHandle(hModuleSnap);
        if (false == isFound)
        {
            return false;
        }
        // 获取目标进程句柄   
        hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
        if (NULL == hProcess)
        {
            return false;
        }
        // 从 Kernel32.dll 中获取 FreeLibrary 函数地址   
        LPTHREAD_START_ROUTINE lpThreadFun = (PTHREAD_START_ROUTINE)::GetProcAddress(::GetModuleHandle(_T("Kernel32")), "FreeLibrary");
        if (NULL == lpThreadFun)
        {
            ::CloseHandle(hProcess);
            return false;
        }
        // 创建远程线程调用 FreeLibrary   
        hThread = ::CreateRemoteThread(hProcess, NULL, 0, lpThreadFun, me32.modBaseAddr /* 模块地址 */, 0, NULL);
        if (NULL == hThread)
        {
            ::CloseHandle(hProcess);
            return false;
        }
        // 等待远程线程结束   
        ::WaitForSingleObject(hThread, INFINITE);
        // 清理   
        ::CloseHandle(hThread);
        ::CloseHandle(hProcess);
        return true;
    }
  • 相关阅读:
    Linq to sql与EF零碎知识点总结
    个人总结js客户端验证
    asp.net、mvc、ajax、js、jquery、sql、EF、linq、netadvantage第三方控件知识点笔记
    c#、sql、asp.net、js、ajax、jquery大学知识点笔记
    ActiveMQ 事务和XA
    三次握手“释放”连接
    ActiveMQ 集群和主从
    ActiveMQ 配置jdbc主从
    ActiveMQ 的连接和会话
    ActiveMQ 处理不同类型的消息
  • 原文地址:https://www.cnblogs.com/szyicol/p/13023428.html
Copyright © 2011-2022 走看看