博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
dll注入到指定进程
阅读量:4507 次
发布时间:2019-06-08

本文共 4761 字,大约阅读时间需要 15 分钟。

talk is cheap,show me code

代码有详细注释

主程序

#include "stdafx.h"#include 
#include
#include
#include
using namespace std;int EnableDebugPriv(char* name){ HANDLE hToken; TOKEN_PRIVILEGES tp; LUID luid; //打开进程令牌环 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); //获得进程本地唯一ID LookupPrivilegeValue(NULL, name, &luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; tp.Privileges[0].Luid = luid; //调整权限 AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); return 0;}//*****************************************************************************************************************************BOOL InjectDll(LPCSTR DllFullPath, const DWORD dwRemoteProcessId){ // 提升权限(必须管理员身份) EnableDebugPriv(SE_DEBUG_NAME); //打开远程线程 HANDLE hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId); if (hRemoteProcess == NULL) { cout << "Error: OpenProcess failed!\n" << endl; return FALSE; } //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名空间 LPVOID pszLibFileRemote = VirtualAllocEx(hRemoteProcess, NULL, lstrlen(DllFullPath) + 1, MEM_COMMIT, PAGE_READWRITE); if (pszLibFileRemote == NULL) { CloseHandle(hRemoteProcess); cout << "Error: VirtualAllocEx failed!\n" << endl; return FALSE; } //使用WriteProcessMemory函数将DLL的路径名写入到远程进程的内存空间 if (!WriteProcessMemory(hRemoteProcess, pszLibFileRemote, DllFullPath, lstrlen(DllFullPath) + 1, NULL)) { CloseHandle(hRemoteProcess); cout << "Error: WriteProcessMemory failed!\n" << endl; return FALSE; } //启动远程线程LoadLibraryA,通过远程线程调用创建新的线程 HANDLE hRemoteThread; if ((hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, pszLibFileRemote, 0, NULL)) == NULL) { CloseHandle(hRemoteProcess); cout << "Error: the remote thread could not be created.\n" << endl; return FALSE; } else { // 等待线程退出 要设置超时 以免远程线程挂起导致程序无响应 //WaitForSingleObject(hRemoteThread, 10000); // 如果等待线程 DLL中的DllMain不要写MessageBox cout << "Success: the remote thread was successfully created.\n" << endl; } // 释放句柄 CloseHandle(hRemoteProcess); CloseHandle(hRemoteThread); return TRUE;}// 根据进程名称获取进程IDDWORD FindTarget(LPCSTR lpszProcess){ DWORD dwRet = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32 ); Process32First(hSnapshot, &pe32 ); do { if (lstrcmpi(pe32.szExeFile, lpszProcess) == 0) { dwRet = pe32.th32ProcessID; break; } } while (Process32Next(hSnapshot, &pe32)); CloseHandle(hSnapshot); return dwRet; }//*****************************************************************************************************************************int main(){ DWORD id = FindTarget((LPCSTR)"calc.exe"); cout << id << endl; // 获取可执行文件所在目录 TCHAR szFilePath[MAX_PATH + 1]; GetModuleFileName(NULL, szFilePath, MAX_PATH); *(_tcsrchr(szFilePath, '\\')) = 0; _tcscat_s(szFilePath, sizeof(szFilePath), "\\dll.dll"); cout << szFilePath << endl; InjectDll(szFilePath, id);//这个数字是你想注入的进程的ID号 return 0;}

dllmain

// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "stdafx.h"#include 
using namespace std;BOOL APIENTRY DllMain(HINSTANCE hInst /* Library instance handle. */, DWORD reason /* Reason this function is being called. */, LPVOID reserved /* Not used. */){ switch (reason) { case DLL_PROCESS_ATTACH: //当这个DLL被映射到了进程的地址空间时 MessageBox(0, TEXT("From DLL\n"), TEXT("Process Attach"), MB_ICONINFORMATION); cout << "Process Attach" << endl; break; case DLL_PROCESS_DETACH: //这个DLL从进程的地址空间中解除映射 MessageBox(0, TEXT("From DLL\n"), TEXT("Process Detach"), MB_ICONINFORMATION); cout << "Process Detach" << endl; break; case DLL_THREAD_ATTACH: //一个线程正在被创建 MessageBox(0, TEXT("From DLL\n"), TEXT("Thread Attach"), MB_ICONINFORMATION); cout << "Thread Attach" << endl; break; case DLL_THREAD_DETACH: //线程终结 MessageBox(0, TEXT("From DLL\n"), TEXT("Thread Detach"), MB_ICONINFORMATION); cout << "Thread Detach" << endl; break; } return TRUE;}

需要注意的地方

  1. 环境是vs,字符集是多字节
  2. 这份代码中的hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, pszLibFileRemote, 0, NULL)中的也可采用GetProcAddress函数
  3. 这份代码并不是通用注入代码(如果需要通用需要自行解析pe头结构从中取出kernel32.dll的GetProcAddress地址),所以64位windows上需要把vs设置为编译x64

转载于:https://www.cnblogs.com/Akkuman/p/7725927.html

你可能感兴趣的文章
jsp第三章
查看>>
Android平台下利用zxing实现二维码开发
查看>>
【HTTP】Fiddler(三)- Fiddler命令行和HTTP断点调试
查看>>
镜像源归类
查看>>
IE下的document.onclick问题
查看>>
[模板]后缀数组
查看>>
git添加本地文件到github仓库
查看>>
0502《构建之法》第六、七章读后感
查看>>
[福大软工] Z班——Beta现场答辩反馈
查看>>
利用Pycharm本地调试spark-streaming(包含kafka和zookeeper等操作)
查看>>
Web控件
查看>>
状压DP泛做
查看>>
The New Stack:KubeEdge将Kubernetes的能力延伸至边缘
查看>>
Datatable的Select()
查看>>
Django之中间件
查看>>
博客作业05--查找
查看>>
SQL面试题目汇总
查看>>
为何img、input等内联元素可以设置宽、高
查看>>
Java知识总结---整合SpringMVC+Mybatis+Spring(二)
查看>>
android android:duplicateParentState=&quot;true&quot; &quot;false&quot;
查看>>