MFC-进程注入
进程注入:就是把自己的dll插入系统服务程序中
为什么要进行进程注入:
到了WinNT以后的系列操作系统中,每个进程都有自己的4GB私有进程地址空间,彼此互不相关。进程A中的一个地址,比如:0x12345678,到了进程B中的相同地方,存的东西完全不一样,或者说不可预料。所以说如果进程A想要看看或者修改进程B地址空间中的内容,就必须深入到其地址空间中,因为DLL是可以被加载到任何进程当中的,所以在进程注入中,DLL应该是主角,也就是说一些核心的代码都应该放在DLL中编写
注入的优点:就是进程隐藏,能穿透防火墙
注入的缺点:如果DLL程序的算法不是很好,或者DLL文件有Bug,那么将影响目标进程的执行效率,或者说干脆目标进程崩溃
用远程线程技术来实现进程的注入
新建项目
这个项目不需要界面的,所以创建win32工程
因为不需要界面和资源,所以要删除一些文件
在工程cpp中只留入口点,其余删除,如下
// Project1.cpp : 定义应用程序的入口点。 // #include "framework.h" #include "Project1.h" int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { return 0; }
此时编译一下,应该成功
代码:
h文件
#pragma once BOOL Inject(LPCTSTR szModule, DWORD dwID); /* * 参数1:LPCTSTR 动态链接库的路径 * 参数2:DWORD 目标进程ID */
cpp文件
// Project1.cpp : 定义应用程序的入口点。 // #include "framework.h" #include "Project1.h" int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { HANDLE hToken; //存放获得的令牌 TOKEN_PRIVILEGES tp; //令牌权限结构体 BOOL b = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);//获取当前进程的令牌 if (!b) { MessageBox(NULL, _T("获取进程的令牌句柄失败"), NULL, NULL); } BOOL b1 = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);//获取本地系统的指定权限 if (!b1) { MessageBox(NULL, _T("获取系统权限的特权值失败"), NULL, NULL); } tp.PrivilegeCount = 1; //只启动调试权限,所以权限的个数是一个 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //属性设置 BOOL b2 = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);//修改访问令牌的权限 DWORD d = GetLastError(); if (d != ERROR_SUCCESS) { MessageBox(NULL, _T("权限修改失败"), NULL, NULL); } if (d == ERROR_SUCCESS) { MessageBox(NULL, _T("权限修改成功"), NULL, NULL); } CloseHandle(hToken); HWND hWnd = ::FindWindow(_T("TFrmMain"), NULL);//获取与指定窗口类名和窗口名的最顶层窗口的窗口句柄 //寻找 语音计算器 进程 if (!hWnd) { MessageBox(NULL,_T("请打开语音计算器"),NULL,NULL); ExitProcess(0); } unsigned long pid; ::GetWindowThreadProcessId(hWnd, &pid);//获取指定进程的进程ID /* 参数:HANDLE Process 进程的句柄 句柄必须具有PROCESS_QUERY_INFORMATION或PROCESS_QUERY_LIMITED_INFORMATION访问权限 返回值:如果函数成功,则返回值为进程标识符 如果函数失败,则返回值为零 */ if(pid ==0){ MessageBox(NULL, _T("语音计算器进程ID获取失败"), NULL, NULL); ExitProcess(0); } b=Inject(_T("D:\\bb\\MFCdll\\Debug\\MFCdll.dll"), pid);//调用函数 return 0; } BOOL Inject(LPCTSTR szModule, DWORD dwID) { //在目标进程中装载dll HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION |PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD |PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, dwID); if (!process) { MessageBox(NULL, _T("进程权限获取失败"), NULL, NULL); return FALSE; } int cByte = (_tcslen(szModule)+1)*sizeof(TCHAR); //dll路径的字节数 LPVOID pAddr = VirtualAllocEx(process,NULL, cByte, MEM_COMMIT, PAGE_READWRITE); if (!pAddr || !WriteProcessMemory(process, pAddr, szModule, cByte,NULL)) { MessageBox(NULL, _T("路径写入失败"), NULL, NULL); return FALSE; } PTHREAD_START_ROUTINE pfnStartAddr =(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW"); //获取Kernel32动态链接库中LoadLibraryW函数的地址 if (!pfnStartAddr) { MessageBox(NULL, _T("LoadLibraryW函数地址获取失败"), NULL, NULL); return FALSE; } DWORD dwThreadID = 0; HANDLE hRemoteThread = CreateRemoteThread(process,NULL,0, pfnStartAddr, pAddr,0,&dwThreadID);//创建远程线程 /* 【在目标进程中装载dll】 参数1:HANDLE hProcess 线程所属进程的进程句柄 该句柄必须具有 PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE,和PROCESS_VM_READ 访问权限 参数2:LPSECURITY_ATTRIBUTES lpThreadAttributes 一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结构指定了线程的安全属性 参数3:SIZE_T dwStackSize 线程栈初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小 参数4:LPTHREAD_START_ROUTINE lpStartAddress 在远程进程的地址空间中,该线程的线程函数的起始地址 参数5:LPVOID lpParameter 传给线程函数的参数 参数6:DWORD dwCreationFlags 线程的创建标志 0 线程创建后立即运行 CREATE_SUSPENDED=0x00000004 线程创建后先将线程挂起,直到 ResumeThread 被调用 STACK_SIZE_PARAM_IS_A_RESERVATION=0x00010000 dwStackSize 参数指定为线程栈预订大小,如果STACK_SIZE_PARAM_IS_A_RESERVATION没有被指定,dwStackSize 参数指定为线程栈分配大小. 参数7:LPDWORD lpThreadId 指向新创建线程ID的指针,如果创建失败,该参数为NULL 返回值:成功返回新线程句柄,失败返回NULL */ if (!hRemoteThread) { MessageBox(NULL, _T("远程线程创建失败"), NULL, NULL); return FALSE; } CloseHandle(hRemoteThread); CloseHandle(process); return TRUE; }
运行
注意:管理员身份运行
出现这个窗口时,说明进程注入成功,dll中的函数开始执行了
实例工程下载:
链接:https://pan.baidu.com/s/1sE89t5ctZs1uPVPJ7Y91Dw
提取码:6666
MFCdll下载:
链接:https://pan.baidu.com/s/1cIoSVYz5JKeJm4KDSVkYOg
提取码:6666
语音计算器下载:
链接:https://pan.baidu.com/s/1SWVEgBCjTcPk5_wyBXmnjA
提取码:6666
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2019-05-22 初等函数
2019-05-22 python-第三方包的安装和升级和卸载