學習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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM