#include #include " />

#include #include"/>
 首页 > 作文

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

更新时间:2023-04-04 22:28:17 阅读: 评论:0

先上源码:

#include "inject_main.h"#include "resource.h"#include <windows.h>#include <tlhelp32.h>#include <string>#include <tchar.h>using namespace std;/// <summary>/// 通过进程名称获取该进程句柄/// </summary>/// <param name="processname"></param>/// <returns>成功返回 dword,失败返回 0</returns>dword getprocessbyname(const tchar* processname) {  // 获取到整个系统的进程  handle processall = createtoolhelp32snapshot(th32cs_snapprocess, null);  // 定义一个容器,该容器用来接收,进程信息  procesntry32w processinfo = { 0 };  processinfo.dwsize = sizeof(procesntry32w);  // 根据进程名称,循环判断是否是指定的进程  do  {    if (_tcscmp(processinfo.szexefile, processname) == 0)    {      // 释放进程快照,防止内存泄露      clohandle(processall);      // 如果是返回指定进程句柄      return processinfo.th32processid;    }    // 一个迭代函数  } w结构特点hile (process32next(processall, &processinfo));  // 释放进程快照,防止内存泄露  clohandle(processall);  return 0;}/// <summary>/// 获取指定 dll 的内存地址/// </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) {    clohandle(handle);    return null;  }  zeromemory(&moduleentry, sizeof(moduleentry32));  moduleentry.dwsize = sizeof(moduleentry32);  if (!module32first(handle, &moduleentry)) {    clohandle(handle);    return null;  }  do {    if (_tcscmp(moduleentry.szmodule, modulename) == 0) {      // 释放进程快照,防止内存泄露      clohandle(handle);      return moduleentry.hmodule;    }  } while (module32next(handle, &moduleentry));  clohandle(handle);  return 0;}/// <summary>/// 把指定dll注入到指定进程中/// </summary>/// <param name="processname">processname 进程名称</param>/// <param name="dllpath">dllpath dll路径</param>void injectdll(const wchar_t* processname, const char* dllpath) {  // 获取指定进程的句柄  dword dword = getprocessbyname(processname);  if (dw邹忌ord == 0)  {    messagebox(null, text("没有找到指定进程"), text("错误"), 0);    return;  }  //前行的力量作文 打开指定进程  handle hprocess = openprocess(process_all_access, fal, dword);  if (hprocess == null)  {    messagebox(null, text("指定进程打开失败"), text("错误"), 0);    return;  }  /*    在指定进程的地址,开辟一块内存空间,用来保存 dll的路径信息    lpvoid virtualallocex(    [in]      handle hprocess, 在那个进程中开辟内存    [in, optional] lpvoid lpaddress, 开辟内存的起始地址 (null,不需要控制起始位置)    [in]      size_t dwsize, 开辟内存的大小(当前保存的内容是 dll的路径)    [in]      dword flallocationtype, 内存分配的类型。(开辟内存)    [in]      dword flprotect,设置内存的权限 (可读可写)    );  */  lpvoid dlladdress = virtualallocex(hprocess, null, strlen(dllpath), mem_commit, page_readwrite);  /*    把dll的路径,写入到刚开辟出来的内存中    bool writeprocessmemory(    [in] handle hprocess, // 指定的进程    [in] lpvoid lpbaaddress, // dll路径字符串,写入的基址    [in] lpcvoid lpbuffer, // dll路径字符串,的指针    [in] size_t nsize, // 需要写入内存的字节长度    [out] size_t *lpnumberofbyteswritten // [out] 返回一个指针,不需要,null    );  */  if (writeprocessmemory(hprocess, dlladdress, dllpath, strlen(dllpath), null) == 0)  {    messagebox(null, text("路径写入失败"), text("错误"), 0);    return;  }  // 获取 kernel32.dll 这个模块  hmodule k32 = getmodulehandle(text("kernel32.dll"));  // 在 kernel32.dll 模块中找到 loadlibrary 这个函数的内存地址  lpvoid loadadd = getprocaddress(k32, "loadlibrarya");  /*    在指定进程中,创建一个线程    并通过这个线程,调用 loadlibrary 函数    通过 loadlibrary 函数,把 dll 载入到目标进程中    handle createremotethread(    [in] handle         hprocess, // 指定进程    [in] lpcurity_attributes lpthreadattributes, // 设置线程安全属性,表示线程是否可以继承,null就够了    [in] size_t         dwstacksize, // 堆栈的初始大小,0 表示使用可执行文件的默认大小    [in] lpthread_start_routine lpstartaddress, // 远程进程中,需要执行的那个函数的指针    [in] lpvoid         lpparameter, // 目前进程中 dll路径的指针    [in] dword         dwcreationflags, // 0 线程在创建后立即运行。    [out] lpdword        lpthreadid // [out] 当前不需要这个返回值    );  */  handle hthread = createremotethread(hprocess, null, 0, (lpthread_start_routine)loadadd, dlladdress, 0, null);  // 释放指定的模块  clohandle(hthread);  clohandle(hprocess);}/// <summary>/// 把指定进程中的dll卸载掉/// </summary>/// <param name="processname"></par有效教学论文am>/// <param name="dllpath"></param>void uninjectdll(const wchar_t* processname) {  // 通过进程名称获取该进程句柄  dword dword = getprocessbyname(processname);  if (dword == 0)  {    messagebox(null, text("没有找到指定进程"), text("错误"), 0);    return;  }  // 获取指定进程中指定模块的内存地址  hmodule hmodule = getprocessmodulehandle(dword, l"wx_read_write.dll");  // 打开指定进程  handle hprocess = openprocess(process_all_access, fal, dword);  if (hprocess == null)  {    messagebox(null, text("指定进程打开失败"),三价铬 text("错误"), 0);    return;  }  // 获取 kernel32.dll 这个模块  hmodule k32 = getmodulehandle(text("kernel32.dll"));  // 在 kernel32.dll 模块中找到 loadlibrary 这个函数的内存地址  lpvoid loadadd = getprocaddress(k32, "freelibrary");  handle hthread = createremotethread(hprocess, null, 0, (lpthread_start_routine)loadadd, (lpvoid)hmodule, 0, null);  // 释放指定的模块  clohandle(hthread);  clohandle(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://urs//qiaoas//documents//visual studio 2015//projects//consoleapplication1//debug//wx_read_write.dll" };  switch (umsg)  {  ca wm_initdialog:    break;  ca wm_clo:    enddialog(hwnddlg, 0); // 关闭窗体    break;  ca 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("进程名称不能为空"), text("错误"), 0);      }      if (sizeof(dllpath) == 0)      {        messagebox(null, text("dll路径不能为空"), text("错误"), 0);      }      injectdll(processname, dllpath); // 注入dll    }    if (wparam == btn_uninject_dll)    {      uninjectdll(processname); // 卸载dll    }    break;  default:    break;  }  return fal;}/// <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;}

初学c++,代码可能有些地方写的不够好,但是注入卸载是完全没问题的。

注入逻辑解释:

使用createremotethread 函数可以为目标进程创建一个新的线程。

在一个进程为另一个进程创建的线程就是远程线程。

使用 loadlibrary 函数把指定的dll加载到进程中

因此就可以在创建远程线程的同时调用 loadlibrary 函数,把指定的dll加载到目标进程中。

为什么创建远程线程的时候调用 loadlibrary 函数就能把 dll 注入到目标进程中?

loadlibrary  函数是 kernel32.dll 中的一个成员kernel32.dll 这个dll是创建进程必须的一个dll,并且所有进程在内存中指向的 kernel32.dll 是同一个地址所以只要获取到当前进程中 loadlibrary 函数的地址就够了

为什么要在目标进程中开辟一块内存,再把dll路径写入到块内存中?

loadlibrary 函数需要一个参数,就是dll的路径把当前进程中的一个地址传到另一个进程中,鬼知道另一个进程获取这个地址中的数据时,读取到的是否是我们想要的。因此需要把dll的路径直接写入到目标进程中。virtualallocex 函数,在目标进程中开辟一块空间,用来存放dll路径writeprocessmemory 函数,把dll的路径写入进去getmodulehandle 获取 kernel32.dll 模块getprocaddress 获取 loadlibrarya 函数在内存中的地址createremotethread 创建远程线程,并调用 loadlibrarya 函数

loadlibraryloadlibraryaloadlibraryw 这三者的区别。

loadlibrary 是一个宏,可以根据字符集的不同,自动决定是使用 loadlibrarya 还是 loadlibraryw

loadlibrary 宏定义的源码:

winbaapi_ret_maybenull_hmodulewinapiloadlibrarya(  _in_ lpcstr lplibfilename  );winbaapi_ret_maybenull_hmodulewinapiloadlibraryw(  _in_ lpcwstr lplibfilename  );#ifdef unicode#define loadlibrary loadlibraryw#el#define loadlibrary loadlibrarya#endif // !unicode

卸载逻辑:

使用 createremotethread 函数创建一个远程线程

调用 freelibrary 函数,卸载dll

freelibrary 函数在 kernel32.dll 模块中,逻辑同上

freelibrary 函数需要 dll 的内存地址

遍历进程快照可以获取到指定模块的内存地址

卸载和注入的思路都是一样的

确认dll是否注入到目标进程中:

方式一:使用 procexp

方式二:cheat engine

确认 kernel32.dll 中的 freelibrary 和 loadlibrarya 在多个进程中是否指向同一块内存地址:

可以通过ce查看多个进程中 kernel32.dll 的内存地址是否相同

再通过 kernel32.dll 中函数的内存地址,确认 freelibrary 和 loadlibrarya 这两个函数

到此这篇关于c++ dll注入工具(完整源码)的文章就介绍到这了,更多相关c++ dll注入工具内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 22:28:16,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/d012a94453402f343af230f3edbe75f6.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:C++ DLL注入工具(完整源码).doc

本文 PDF 下载地址:C++ DLL注入工具(完整源码).pdf

标签:进程   函数   内存   路径
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图
  • 我要关灯
    我要开灯
  • 返回顶部