win32向目标进程注入代码
2014-04-01 14:34
459 查看
下面代码演示了向“记事本”程序(NOTEPAD.EXE)的进程地址空间中注入我们自己写的函数代码,大致原理如下:
1. 提升注入(注意和“被注入”的区别)程序的进程访问权限
2. 随便打开一个记事本文件,注意是用NOTEPAD.EXE打开的
3. 查找NOTEPAD.EXE对应的进程ID,即Process ID
4. 以所有权限(包括read/write)打开NOTEPAD.EXE的进程ID
5. 在NOTEPAD.EXE的进程ID地址空间中,申请一块内存
6. 向刚刚申请的内存中,写入我们想要写的任何代码(注意:注入的代码中全部都用指针的形式调用相关数据和函数)
7. 我们写的代码不会自动执行,需要在被注入的进程中创建一个新的线程,调用注入的代码
-------------------------------------------------------------------------------------------------------------------------------
相关代码如下:
---------------------------------------------------------------------
测试运行结果如下:
1. 提升注入(注意和“被注入”的区别)程序的进程访问权限
2. 随便打开一个记事本文件,注意是用NOTEPAD.EXE打开的
3. 查找NOTEPAD.EXE对应的进程ID,即Process ID
4. 以所有权限(包括read/write)打开NOTEPAD.EXE的进程ID
5. 在NOTEPAD.EXE的进程ID地址空间中,申请一块内存
6. 向刚刚申请的内存中,写入我们想要写的任何代码(注意:注入的代码中全部都用指针的形式调用相关数据和函数)
7. 我们写的代码不会自动执行,需要在被注入的进程中创建一个新的线程,调用注入的代码
-------------------------------------------------------------------------------------------------------------------------------
相关代码如下:
//整理:过客 //邮箱:386520874@qq.com //日期:2014.04.01 #pragma once #include <windows.h> #include <TlHelp32.h> #include "stdio.h" //-------------------------------------------------------- typedef struct tagWNDINFO { DWORD dwProcId; HWND hWnd; } WNDINFO, *LPWNDINFO; BOOL CALLBACK MyEnumProc(HWND hWnd,LPARAM lParam) { DWORD dwProcId; GetWindowThreadProcessId(hWnd, &dwProcId); //获得hWnd对应的线程ID LPWNDINFO pInfo = (LPWNDINFO)lParam; if(dwProcId == pInfo->dwProcId) //判断是否是我们需要寻找的ID { pInfo->hWnd = hWnd; return FALSE; } return TRUE; } HWND GetProcessMainWnd(DWORD dwProcId) { WNDINFO wi; wi.dwProcId = dwProcId; //被查询窗口的进程ID wi.hWnd = NULL; EnumWindows(MyEnumProc,(LPARAM)&wi); //枚举窗口 return wi.hWnd; //返回dwProcId对应的窗口句柄 } //-------------------------------------------------------- //线程参数结构体定义 typedef struct tagRemoteParam { char szTitle[60]; // MessageBox函数中窗口标题 char szMsg[60]; // MessageBox函数中显示的字符提示 DWORD dwMessageBox; // MessageBox函数的入口地址 } RemoteParam, *PRemoteParam; //定义MessageBox类型的函数指针 typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD); //线程函数定义 DWORD __stdcall threadProc(LPVOID lParam) { RemoteParam* pRP = (RemoteParam*)lParam; PFN_MESSAGEBOX pfnMessageBox; pfnMessageBox = (PFN_MESSAGEBOX)pRP->dwMessageBox; pfnMessageBox(NULL, pRP->szMsg, pRP->szTitle, 0); return 0; } //提升进程访问权限 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, "The frist entry of the process list has not been copyied to the buffer", "Notice", MB_ICONINFORMATION | MB_OK); return 0; } while(Process32Next(hSnapshot, &pe)) // 循环查找下一个进程 { if(!strcmp(lpszProcessName, pe.szExeFile)) // 找到了 { return pe.th32ProcessID; } } return 0; } //----------------------------------------------------------- int main(int argc, char* argv[]) { //定义线程体的大小,实际分配的内存大小是页内存大小的整数倍 const DWORD dwThreadSize = 4096; DWORD dwWriteBytes; //提升进程访问权限 enableDebugPriv(); //等待输入进程名称,注意大小写匹配 char szExeName[MAX_PATH] = { 0 }; // cout << "Please input the name of target process !" << endl; // cin >> szExeName; //接收命令行输入的字符串 // cout << szExeName << endl; // strcpy(szExeName,"notepad.exe"); // scanf("%s",szExeName); sprintf(szExeName,"NOTEPAD.EXE"); DWORD dwProcessId = processNameToId(szExeName); //Name转换成ID if(dwProcessId == 0) { MessageBox(NULL, "The target process have not been found !", "Notice", MB_ICONINFORMATION | MB_OK); return -1; } HWND hWnd=GetProcessMainWnd(dwProcessId); char szTile[MAX_PATH]; ::GetWindowText(hWnd, szTile, MAX_PATH); //获得已经打开的记事本窗口的标题 //根据进程ID得到进程句柄 HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId); if(!hTargetProcess) { MessageBox(NULL, "Open target process failed !", "Notice", MB_ICONINFORMATION | MB_OK); return 0; } //在宿主进程中为线程体开辟一块存储区域 //在这里需要注意 MEM_COMMIT | MEM_RESERVE 内存分配类型以及PAGE_EXECUTE_READWRITE内存保护类型 //其具体含义请参考MSDN中关于VirtualAllocEx函数的说明。 void* pRemoteThread = VirtualAllocEx(hTargetProcess, 0, dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if(!pRemoteThread) { MessageBox(NULL, "Alloc memory in target process failed !", "notice", MB_ICONINFORMATION | MB_OK); return 0; } //将线程体拷贝到宿主进程中 if(!WriteProcessMemory(hTargetProcess, pRemoteThread, &threadProc, dwThreadSize, 0)) { MessageBox(NULL, "Write data to target process failed !", "Notice", MB_ICONINFORMATION | MB_OK); return 0; } //定义线程参数结构体变量 RemoteParam remoteData; ZeroMemory(&remoteData, sizeof(RemoteParam)); //初始化 //填充结构体变量中的成员 HINSTANCE hUser32 = LoadLibrary("User32.dll"); remoteData.dwMessageBox = (DWORD)GetProcAddress(hUser32, "MessageBoxA"); //取得MessageBox API的地址 // strcat(remoteData.szTitle, "新建文本文档"); int len=strlen(szTile); szTile[len]='\0'; strcat(remoteData.szTitle, szTile); //MessageBox的标题 strcat(remoteData.szMsg, "Hello 你好吗?\\(^o^)/~"); //MessageBox的内容 //为线程参数在宿主进程中开辟存储区域 RemoteParam* pRemoteParam = (RemoteParam*)VirtualAllocEx(hTargetProcess , 0, sizeof(RemoteParam), MEM_COMMIT, PAGE_READWRITE); if(!pRemoteParam) { MessageBox(NULL, "Alloc memory failed !", "Notice", MB_ICONINFORMATION | MB_OK); return 0; } //将线程参数拷贝到宿主进程地址空间中 if(!WriteProcessMemory(hTargetProcess , pRemoteParam, &remoteData, sizeof(remoteData), 0)) { MessageBox(NULL, "Write data to target process failed !", "Notice", MB_ICONINFORMATION | MB_OK); return 0; } //在宿主进程中创建线程 HANDLE hRemoteThread = CreateRemoteThread(hTargetProcess, NULL, 0, (DWORD (__stdcall *)(void *))pRemoteThread, pRemoteParam, 0, &dwWriteBytes); if(!hRemoteThread) { MessageBox(NULL, "Create remote thread failed !", "Notice", MB_ICONINFORMATION | MB_OK); return 0; } CloseHandle(hRemoteThread); FreeLibrary(hUser32); return 0; }
---------------------------------------------------------------------
测试运行结果如下:
相关文章推荐
- [置顶] 恶意代码--dll动态链接库注入目标进程隐藏自身(亲测win7x86和x64有效)
- 利用远程线程将代码注入到目标进程中执行
- 利用远程线程将代码注入到目标进程中执行
- 给Source Insight做个外挂系列之二--将本地代码注入到Source Insight进程
- 向其他进程注入代码的三种方法
- 向其他进程注入代码的三种方法
- 转:向其他进程注入代码的三种方法
- 向其他进程注入代码的三种方法
- Delphi进程注入的部分代码 (非DLL注入)
- 注入的so在目标进程的内存空间中没有找到
- 向其他进程注入代码的三种方法
- Dll注入系统进程的部分代码
- 水木:java进程 代码注入 (Powered by zms)
- 向其他进程注入代码的三种方法
- 一份进程注入的代码
- 进程注入代码
- Win32环境下代码注入与API钩子的实现
- 将代码注入其它进程的三种方法
- 黑客内参-使用恶意软件将隐藏代码注入已知进程的渗透研究
- 向其他进程注入代码的三种方法