最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++?DLL注入工具(完整源碼)

 更新時(shí)間:2022年02月07日 16:34:01   作者:?jiǎn)贪采? 
這篇文章主要介紹了C++?DLL注入工具的相關(guān)資料,并向大家分享了完整的源碼,具有一定的參考價(jià)值,希望對(duì)正在工作或?qū)W習(xí)的你有所幫助

先上源碼:

#include "Inject_Main.h"
#include "resource.h"
#include <Windows.h>
#include <TlHelp32.h>
#include <string>
#include <TCHAR.H>

using namespace std;


/// <summary>
/// 通過進(jìn)程名稱獲取該進(jìn)程句柄
/// </summary>
/// <param name="processName"></param>
/// <returns>成功返回 DWORD,失敗返回 0</returns>
DWORD GetProcessByName(CONST TCHAR* processName) {
? ? // 獲取到整個(gè)系統(tǒng)的進(jìn)程
? ? HANDLE processALL = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

? ? // 定義一個(gè)容器,該容器用來接收,進(jìn)程信息
? ? PROCESSENTRY32W processInfo = { 0 };
? ? processInfo.dwSize = sizeof(PROCESSENTRY32W);

? ? // 根據(jù)進(jìn)程名稱,循環(huán)判斷是否是指定的進(jìn)程
? ? do
? ? {
? ? ? ? if (_tcscmp(processInfo.szExeFile, processName) == 0)
? ? ? ? {
? ? ? ? ? ? // 釋放進(jìn)程快照,防止內(nèi)存泄露
? ? ? ? ? ? CloseHandle(processALL);
? ? ? ? ? ? // 如果是返回指定進(jìn)程句柄
? ? ? ? ? ? return processInfo.th32ProcessID;
? ? ? ? }
? ? ? ? // 一個(gè)迭代函數(shù)
? ? } while (Process32Next(processALL, &processInfo));
? ? // 釋放進(jìn)程快照,防止內(nèi)存泄露
? ? CloseHandle(processALL);
? ? return 0;
}

/// <summary>
/// 獲取指定 DLL 的內(nèi)存地址
/// </summary>
/// <param name="pid"></param>
/// <param name="moduleName"></param>
/// <returns></returns>
HMODULE GetProcessModuleHandle(DWORD pid, CONST TCHAR* moduleName) {
? ? MODULEENTRY32 moduleEntry;
? ? HANDLE handle = NULL;
? ? handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
? ? if (!handle) {
? ? ? ? CloseHandle(handle);
? ? ? ? return NULL;
? ? }
? ? ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
? ? moduleEntry.dwSize = sizeof(MODULEENTRY32);
? ? if (!Module32First(handle, &moduleEntry)) {
? ? ? ? CloseHandle(handle);
? ? ? ? return NULL;
? ? }
? ? do {
? ? ? ? if (_tcscmp(moduleEntry.szModule, moduleName) == 0) {
? ? ? ? ? ? // 釋放進(jìn)程快照,防止內(nèi)存泄露
? ? ? ? ? ? CloseHandle(handle);
? ? ? ? ? ? return moduleEntry.hModule;
? ? ? ? }
? ? } while (Module32Next(handle, &moduleEntry));
? ? CloseHandle(handle);
? ? return 0;
}

/// <summary>
/// 把指定DLL注入到指定進(jìn)程中
/// </summary>
/// <param name="processName">processName 進(jìn)程名稱</param>
/// <param name="dllPath">dllPath dll路徑</param>
void InjectDll(const wchar_t* processName, const char* dllPath) {
? ? // 獲取指定進(jìn)程的句柄
? ? DWORD dword = GetProcessByName(processName);
? ? if (dword == 0)
? ? {
? ? ? ? MessageBox(NULL, TEXT("沒有找到指定進(jìn)程"), TEXT("錯(cuò)誤"), 0);
? ? ? ? return;
? ? }
? ? // 打開指定進(jìn)程
? ? HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dword);
? ? if (hProcess == NULL)
? ? {
? ? ? ? MessageBox(NULL, TEXT("指定進(jìn)程打開失敗"), TEXT("錯(cuò)誤"), 0);
? ? ? ? return;
? ? }
? ? /*
? ? ? ? 在指定進(jìn)程的地址,開辟一塊內(nèi)存空間,用來保存 DLL的路徑信息
? ? ? ? LPVOID VirtualAllocEx(
? ? ? ? [in] ? ? ? ? ? HANDLE hProcess, 在那個(gè)進(jìn)程中開辟內(nèi)存
? ? ? ? [in, optional] LPVOID lpAddress, 開辟內(nèi)存的起始地址 (NULL,不需要控制起始位置)
? ? ? ? [in] ? ? ? ? ? SIZE_T dwSize, ?開辟內(nèi)存的大?。ó?dāng)前保存的內(nèi)容是 DLL的路徑)
? ? ? ? [in] ? ? ? ? ? DWORD ?flAllocationType, 內(nèi)存分配的類型。(開辟內(nèi)存)
? ? ? ? [in] ? ? ? ? ? DWORD ?flProtect,設(shè)置內(nèi)存的權(quán)限 (可讀可寫)
? ? ? ? );
? ? ?*/
? ? LPVOID DLLAddress = VirtualAllocEx(hProcess, NULL, strlen(dllPath), MEM_COMMIT, PAGE_READWRITE);
? ? /*
? ? ? ? 把DLL的路徑,寫入到剛開辟出來的內(nèi)存中
? ? ? ? BOOL WriteProcessMemory(
? ? ? ? [in] ?HANDLE ?hProcess, // 指定的進(jìn)程
? ? ? ? [in] ?LPVOID ?lpBaseAddress, // DLL路徑字符串,寫入的基址
? ? ? ? [in] ?LPCVOID lpBuffer, // DLL路徑字符串,的指針
? ? ? ? [in] ?SIZE_T ?nSize, // 需要寫入內(nèi)存的字節(jié)長(zhǎng)度
? ? ? ? [out] SIZE_T ?*lpNumberOfBytesWritten // [out] 返回一個(gè)指針,不需要,NULL
? ? ? ? );
? ? */

? ? if (WriteProcessMemory(hProcess, DLLAddress, dllPath, strlen(dllPath), NULL) == 0)
? ? {
? ? ? ? MessageBox(NULL, TEXT("路徑寫入失敗"), TEXT("錯(cuò)誤"), 0);
? ? ? ? return;
? ? }

? ? // 獲取 Kernel32.dll 這個(gè)模塊
? ? HMODULE k32 = GetModuleHandle(TEXT("Kernel32.dll"));
? ? // 在 Kernel32.dll 模塊中找到 LoadLibrary 這個(gè)函數(shù)的內(nèi)存地址
? ? LPVOID loadADD = GetProcAddress(k32, "LoadLibraryA");
? ? /*
? ? ? ? 在指定進(jìn)程中,創(chuàng)建一個(gè)線程
? ? ? ? 并通過這個(gè)線程,調(diào)用 LoadLibrary 函數(shù)
? ? ? ? 通過 LoadLibrary 函數(shù),把 DLL 載入到目標(biāo)進(jìn)程中
? ? ? ? HANDLE CreateRemoteThread(
? ? ? ? [in] ?HANDLE ? ? ? ? ? ? ? ? hProcess, // 指定進(jìn)程
? ? ? ? [in] ?LPSECURITY_ATTRIBUTES ?lpThreadAttributes, // 設(shè)置線程安全屬性,表示線程是否可以繼承,NULL就夠了
? ? ? ? [in] ?SIZE_T ? ? ? ? ? ? ? ? dwStackSize, // 堆棧的初始大小,0 表示使用可執(zhí)行文件的默認(rèn)大小
? ? ? ? [in] ?LPTHREAD_START_ROUTINE lpStartAddress, // 遠(yuǎn)程進(jìn)程中,需要執(zhí)行的那個(gè)函數(shù)的指針
? ? ? ? [in] ?LPVOID ? ? ? ? ? ? ? ? lpParameter, // 目前進(jìn)程中 DLL路徑的指針
? ? ? ? [in] ?DWORD ? ? ? ? ? ? ? ? ?dwCreationFlags, // 0 線程在創(chuàng)建后立即運(yùn)行。
? ? ? ? [out] LPDWORD ? ? ? ? ? ? ? ?lpThreadId // [out] 當(dāng)前不需要這個(gè)返回值
? ? ? ? );
? ? */
? ? HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadADD, DLLAddress, 0, NULL);


? ? // 釋放指定的模塊
? ? CloseHandle(hThread);
? ? CloseHandle(hProcess);

}

/// <summary>
/// 把指定進(jìn)程中的DLL卸載掉
/// </summary>
/// <param name="processName"></param>
/// <param name="dllPath"></param>
void UnInjectDll(const wchar_t* processName) {
? ? // 通過進(jìn)程名稱獲取該進(jìn)程句柄
? ? DWORD dword = GetProcessByName(processName);
? ? if (dword == 0)
? ? {
? ? ? ? MessageBox(NULL, TEXT("沒有找到指定進(jìn)程"), TEXT("錯(cuò)誤"), 0);
? ? ? ? return;
? ? }
? ? // 獲取指定進(jìn)程中指定模塊的內(nèi)存地址
? ? HMODULE hmodule = GetProcessModuleHandle(dword, L"WX_Read_Write.dll");

? ? // 打開指定進(jìn)程
? ? HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dword);
? ? if (hProcess == NULL)
? ? {
? ? ? ? MessageBox(NULL, TEXT("指定進(jìn)程打開失敗"), TEXT("錯(cuò)誤"), 0);
? ? ? ? return;
? ? }

? ? // 獲取 Kernel32.dll 這個(gè)模塊
? ? HMODULE k32 = GetModuleHandle(TEXT("Kernel32.dll"));
? ? // 在 Kernel32.dll 模塊中找到 LoadLibrary 這個(gè)函數(shù)的內(nèi)存地址
? ? LPVOID loadADD = GetProcAddress(k32, "FreeLibrary");

? ? HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadADD, (LPVOID)hmodule, 0, NULL);

? ? // 釋放指定的模塊
? ? CloseHandle(hThread);
? ? CloseHandle(hProcess);
}


/// <summary>
///?
/// </summary>
/// <param name="hwndDlg"></param>
/// <param name="uMsg"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <returns></returns>
INT_PTR CALLBACK dialogProc(_In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
? ? wchar_t processName[100] = L"WeChat.exe";
? ? char dllPath[400] = { "C://Users//qiaoas//documents//visual studio 2015//Projects//ConsoleApplication1//Debug//WX_Read_Write.dll" };
? ? switch (uMsg)
? ? {
? ? case WM_INITDIALOG:
? ? ? ? break;
? ? case WM_CLOSE:
? ? ? ? EndDialog(hwndDlg, 0); // 關(guān)閉窗體
? ? ? ? break;
? ? case WM_COMMAND:
? ? ? ? /*GetDlgItemText(hwndDlg, Text_ProcessName, processName, sizeof(processName));
? ? ? ? GetDlgItemText(hwndDlg, Text_DLLPath, (LPWSTR)dllPath, sizeof(dllPath));*/

? ? ? ? if (wParam == Btn_Inject_DLL)
? ? ? ? {
? ? ? ? ? ? if (sizeof(processName) == 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? MessageBox(NULL, TEXT("進(jìn)程名稱不能為空"), TEXT("錯(cuò)誤"), 0);
? ? ? ? ? ? }
? ? ? ? ? ? if (sizeof(dllPath) == 0)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? MessageBox(NULL, TEXT("DLL路徑不能為空"), TEXT("錯(cuò)誤"), 0);
? ? ? ? ? ? }
? ? ? ? ? ? InjectDll(processName, dllPath); // 注入DLL
? ? ? ? }
? ? ? ? if (wParam == Btn_unInject_DLL)
? ? ? ? {
? ? ? ? ? ? UnInjectDll(processName); // 卸載DLL
? ? ? ? }
? ? ? ? break;
? ? default:
? ? ? ? break;
? ? }
? ? return FALSE;
}


/// <summary>
/// 初始化
/// </summary>
/// <param name="hInstance"></param>
/// <param name="hPrevInstance"></param>
/// <param name="lpCmdLine"></param>
/// <param name="nCmdShow"></param>
/// <returns></returns>
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
? ? _In_opt_ HINSTANCE hPrevInstance,
? ? _In_ LPWSTR ? ?lpCmdLine,
? ? _In_ int ? ? ? nCmdShow)
{
? ? DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, &dialogProc);
? ? return 0;
}

初學(xué)C++,代碼可能有些地方寫的不夠好,但是注入卸載是完全沒問題的。

注入邏輯解釋:

使用CreateRemoteThread 函數(shù)可以為目標(biāo)進(jìn)程創(chuàng)建一個(gè)新的線程。

在一個(gè)進(jìn)程為另一個(gè)進(jìn)程創(chuàng)建的線程就是遠(yuǎn)程線程。

使用 LoadLibrary 函數(shù)把指定的DLL加載到進(jìn)程中

因此就可以在創(chuàng)建遠(yuǎn)程線程的同時(shí)調(diào)用 LoadLibrary 函數(shù),把指定的DLL加載到目標(biāo)進(jìn)程中。

為什么創(chuàng)建遠(yuǎn)程線程的時(shí)候調(diào)用 LoadLibrary 函數(shù)就能把 DLL 注入到目標(biāo)進(jìn)程中?

  • LoadLibrary  函數(shù)是 Kernel32.dll 中的一個(gè)成員
  • Kernel32.dll 這個(gè)DLL是創(chuàng)建進(jìn)程必須的一個(gè)DLL,并且所有進(jìn)程在內(nèi)存中指向的 Kernel32.dll 是同一個(gè)地址
  • 所以只要獲取到當(dāng)前進(jìn)程中 LoadLibrary 函數(shù)的地址就夠了

為什么要在目標(biāo)進(jìn)程中開辟一塊內(nèi)存,再把DLL路徑寫入到塊內(nèi)存中?

  • LoadLibrary 函數(shù)需要一個(gè)參數(shù),就是DLL的路徑
  • 把當(dāng)前進(jìn)程中的一個(gè)地址傳到另一個(gè)進(jìn)程中,鬼知道另一個(gè)進(jìn)程獲取這個(gè)地址中的數(shù)據(jù)時(shí),讀取到的是否是我們想要的。
  • 因此需要把DLL的路徑直接寫入到目標(biāo)進(jìn)程中。
  • VirtualAllocEx 函數(shù),在目標(biāo)進(jìn)程中開辟一塊空間,用來存放DLL路徑
  • WriteProcessMemory 函數(shù),把DLL的路徑寫入進(jìn)去
  • GetModuleHandle 獲取 Kernel32.dll 模塊
  • GetProcAddress 獲取 LoadLibraryA 函數(shù)在內(nèi)存中的地址
  • CreateRemoteThread 創(chuàng)建遠(yuǎn)程線程,并調(diào)用 LoadLibraryA 函數(shù)

LoadLibrary 、LoadLibraryALoadLibraryW 這三者的區(qū)別。

LoadLibrary 是一個(gè)宏,可以根據(jù)字符集的不同,自動(dòng)決定是使用 LoadLibraryA 還是 LoadLibraryW

LoadLibrary 宏定義的源碼:

WINBASEAPI
_Ret_maybenull_
HMODULE
WINAPI
LoadLibraryA(
? ? _In_ LPCSTR lpLibFileName
? ? );

WINBASEAPI
_Ret_maybenull_
HMODULE
WINAPI
LoadLibraryW(
? ? _In_ LPCWSTR lpLibFileName
? ? );

#ifdef UNICODE
#define LoadLibrary ?LoadLibraryW
#else
#define LoadLibrary ?LoadLibraryA
#endif // !UNICODE

卸載邏輯:

使用 CreateRemoteThread 函數(shù)創(chuàng)建一個(gè)遠(yuǎn)程線程

調(diào)用 FreeLibrary 函數(shù),卸載DLL

FreeLibrary 函數(shù)在 Kernel32.dll 模塊中,邏輯同上

FreeLibrary 函數(shù)需要 DLL 的內(nèi)存地址

遍歷進(jìn)程快照可以獲取到指定模塊的內(nèi)存地址

卸載和注入的思路都是一樣的

確認(rèn)DLL是否注入到目標(biāo)進(jìn)程中:

方式一:使用 procexp

方式二:Cheat Engine

確認(rèn) Kernel32.dll 中的 FreeLibrary 和 LoadLibraryA 在多個(gè)進(jìn)程中是否指向同一塊內(nèi)存地址:

 可以通過CE查看多個(gè)進(jìn)程中  Kernel32.dll 的內(nèi)存地址是否相同

再通過  Kernel32.dll 中函數(shù)的內(nèi)存地址,確認(rèn) FreeLibrary 和 LoadLibraryA 這兩個(gè)函數(shù)

到此這篇關(guān)于C++ DLL注入工具(完整源碼)的文章就介紹到這了,更多相關(guān)C++ DLL注入工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)雙人五子棋游戲

    C語(yǔ)言實(shí)現(xiàn)雙人五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)雙人五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Windows安裝Qt6.4.2及簡(jiǎn)單驗(yàn)證

    Windows安裝Qt6.4.2及簡(jiǎn)單驗(yàn)證

    本文主要介紹了Windows安裝Qt6.4.2及簡(jiǎn)單驗(yàn)證,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 浮點(diǎn)數(shù)在計(jì)算機(jī)中存儲(chǔ)方式是怎樣的

    浮點(diǎn)數(shù)在計(jì)算機(jī)中存儲(chǔ)方式是怎樣的

    這篇文章介紹了浮點(diǎn)數(shù)在計(jì)算機(jī)中是如何存儲(chǔ)的,講解的比較詳細(xì),有需要的朋友可以參考一下。
    2016-06-06
  • Visual Studio 2022中創(chuàng)建的C++項(xiàng)目無(wú)法使用萬(wàn)能頭<bits/stdc++.h>的解決方案

    Visual Studio 2022中創(chuàng)建的C++項(xiàng)目無(wú)法使用萬(wàn)能頭<bits/stdc++.h>的

    如果大家也遇到下面這種問題,可能是沒有include文件夾中沒有bits/stdc++.h,這篇文章主要介紹了Visual Studio 2022中創(chuàng)建的C++項(xiàng)目無(wú)法使用萬(wàn)能頭<bits/stdc++.h>的解決方案,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)不掛科指南之隊(duì)列詳解

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)不掛科指南之隊(duì)列詳解

    這篇博客主要介紹一下隊(duì)列的概念,并且采用 C 語(yǔ)言,編寫兩種存儲(chǔ)實(shí)現(xiàn)方式:順序存儲(chǔ)和鏈?zhǔn)酱鎯?chǔ),當(dāng)然還有常規(guī)的隊(duì)列基本操作的實(shí)現(xiàn)算法
    2022-09-09
  • Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫(kù)清理

    Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)通用數(shù)據(jù)庫(kù)清理

    項(xiàng)目如果需要存儲(chǔ)很多日志記錄比如運(yùn)行日志,時(shí)間長(zhǎng)了記錄數(shù)量非常多,數(shù)據(jù)庫(kù)體積不斷增大,對(duì)應(yīng)數(shù)據(jù)庫(kù)表的增刪改查的效率不斷降低,因此需要將早期的數(shù)據(jù)清理。本文將詳細(xì)介紹一下通用數(shù)據(jù)庫(kù)清理的實(shí)現(xiàn),需要的可以參考一下
    2022-02-02
  • 詳解C語(yǔ)言之順序表

    詳解C語(yǔ)言之順序表

    這篇文章主要為大家介紹了C語(yǔ)言的順序表,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • 從C語(yǔ)言過渡到C++之基本變化

    從C語(yǔ)言過渡到C++之基本變化

    在之前的C++代碼訓(xùn)練營(yíng)系列中,我試圖用完成具體項(xiàng)目的方式給大家介紹C++,但后來大家反饋說這樣從C過渡到C++有點(diǎn)跟不上。于是我又專門設(shè)計(jì)了這個(gè)《從C到C++》的過渡專題,我準(zhǔn)備通過10篇文章介紹一下C++和C的重要區(qū)別。
    2017-07-07
  • C語(yǔ)言實(shí)現(xiàn)學(xué)生宿舍信息管理系統(tǒng)課程設(shè)計(jì)

    C語(yǔ)言實(shí)現(xiàn)學(xué)生宿舍信息管理系統(tǒng)課程設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)學(xué)生宿舍信息管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語(yǔ)言實(shí)現(xiàn)線性表的基本操作詳解

    C語(yǔ)言實(shí)現(xiàn)線性表的基本操作詳解

    線性表是最基本、最簡(jiǎn)單、也是最常用的一種數(shù)據(jù)結(jié)構(gòu)。一個(gè)線性表是n個(gè)具有相同特性的數(shù)據(jù)元素的有限序列,這篇文章帶你學(xué)習(xí)如何通過C語(yǔ)言實(shí)現(xiàn)線性表的順序存儲(chǔ)和鏈?zhǔn)酱鎯?chǔ)
    2021-11-11

最新評(píng)論

盘锦市| 阿巴嘎旗| 太康县| 鹤山市| 喀喇| 合阳县| 乌兰察布市| 甘肃省| 镇江市| 游戏| 闸北区| 灌南县| 满洲里市| 泽州县| 社旗县| 岢岚县| 资中县| 惠州市| 浦城县| 西华县| 石泉县| 石城县| 南陵县| 伽师县| 福建省| 徐州市| 望城县| 寿宁县| 当涂县| 新郑市| 柞水县| 东山县| 舒兰市| 石柱| 馆陶县| 长子县| 新兴县| 雅安市| 年辖:市辖区| 若尔盖县| 青神县|