线程的远程注入
2010-08-03 11:43
239 查看
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/vcforever/archive/2005/03/15/320144.aspx
在上一篇文章《线程的远程注入》中介绍了如何让其他的进程中执行自己的代码的一种方法
及自己定义一个线程,在线程体中编写执行代码,然后使用VirtualAllocEx函数为线程体以
及线程中用到的字符常量和调用的MessageBox入口函数地址,在目标进程中开辟存储区,然
后再通过WriteProcessMemory函数,将这些数据写入目标进程的地址空间中。最后通过
CreateRemoteThread函数,让自己的线程运行在目标进程中。
上面的方法需要为线程和常量在目标进程中开辟足够的存储空间,而且这个空间的大小很难
确定,稍不注意就会发生访问违规的错误。
下面我来介绍另外一种在其他进程中执行自己的代码的方法,让目标进程加载我们自己编写的
DLL模块。
首先我们来创建一个DLL模块(稍后我们将要把这个DLL加载到目标进程中,让目标进程来运行
DLL中的代码)。
我们创建的这个DLL模块非常简单,只是得到加载该DLL的进程的ID,然后通过MessageBox函数
显示出来,当然也可以写一些复杂的代码。不过我们这里只是介绍一下方法,有个显示结果足
以:)。下面就是DLL模块的代码:
下一步我们就可以专注于如何把这个DLL挂接到目标进程中。
首先我们通过OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId)来打开我们试图加载DLL的进程(注意
进程的打开权限一定要设置为PROCESS_ALL_ACCESS,因为我们要在目标进程中创建线程)。
然后我们可以使用CreateRemoteThread来创建LoadLibraryA线程来启动我们的这个DLL。
LoadLibraryA存在于系统的kernel32.dll中用来加载DLL模块,该函数只有一个参数就是DLL文件的名称(该
名称包括路径)。由于加载DLL的操作是在其他进程中进行,所以我们必须把DLL的文件名称拷贝到目标进程
的地址空间中。
我们必须计算出该文件名所占的内存空间
int nLength = (strlen(pszFileName)+1)*sizeof(char);
接下来使用VirtualAllocEx函数为DLL文件名在目标进程中分配地址空间,在使用WriteProcessMemory将
DLL的文件名拷贝到刚刚分配的地址中。
下一步就是取得LoadLibraryA函数的入口地址
PTHREAD_START_ROUTINE pfnLoadLibraryA =
(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
因为kernel32.dll模块是系统的核心模块,所以该模块中的函数地址在所有进程中全都相同。
我们在本进程中得到的LoadLibraryA函数的入口地址同样适用于其他进程。
所有条件已经具备,最后我们使用CreateRemoteThread函数,将LoadLibraryA函数的入口地址以及DLL的文件
名作为参数,即可让目标进程加载我们自己的DLL,至于你要让你的DLL中运行什么代码,就自己看着办吧!
让远程进程挂接自己的DLL的思路就是这样,下面给出完整代码:
本文参考了西祠高手shotgun的《揭开木马的神秘面纱》,代码为自己所写,放在这里供大家参考。
大家可以参考上面的步骤自己实现一遍!
在上一篇文章《线程的远程注入》中介绍了如何让其他的进程中执行自己的代码的一种方法
及自己定义一个线程,在线程体中编写执行代码,然后使用VirtualAllocEx函数为线程体以
及线程中用到的字符常量和调用的MessageBox入口函数地址,在目标进程中开辟存储区,然
后再通过WriteProcessMemory函数,将这些数据写入目标进程的地址空间中。最后通过
CreateRemoteThread函数,让自己的线程运行在目标进程中。
上面的方法需要为线程和常量在目标进程中开辟足够的存储空间,而且这个空间的大小很难
确定,稍不注意就会发生访问违规的错误。
下面我来介绍另外一种在其他进程中执行自己的代码的方法,让目标进程加载我们自己编写的
DLL模块。
首先我们来创建一个DLL模块(稍后我们将要把这个DLL加载到目标进程中,让目标进程来运行
DLL中的代码)。
我们创建的这个DLL模块非常简单,只是得到加载该DLL的进程的ID,然后通过MessageBox函数
显示出来,当然也可以写一些复杂的代码。不过我们这里只是介绍一下方法,有个显示结果足
以:)。下面就是DLL模块的代码:
//Test.dll源代码 // #include <windows.h> BOOL APIENTRY DllMain(HANDLE hMoudle, DWORD dwReason, LPVOID lpReserved) { char* pszProcessId = (char*)malloc(10*sizeof(char)); switch(dwReason) { case DLL_PROCESS_ATTACH: _itoa(GetCurrentProcessId(), pszProcessId, 10); MessageBox(NULL, pszProcessId, "Notice", MB_ICONINFORMATION | MB_OK); case DLL_PROCESS_DETACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return TRUE; }
下一步我们就可以专注于如何把这个DLL挂接到目标进程中。
首先我们通过OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId)来打开我们试图加载DLL的进程(注意
进程的打开权限一定要设置为PROCESS_ALL_ACCESS,因为我们要在目标进程中创建线程)。
然后我们可以使用CreateRemoteThread来创建LoadLibraryA线程来启动我们的这个DLL。
LoadLibraryA存在于系统的kernel32.dll中用来加载DLL模块,该函数只有一个参数就是DLL文件的名称(该
名称包括路径)。由于加载DLL的操作是在其他进程中进行,所以我们必须把DLL的文件名称拷贝到目标进程
的地址空间中。
我们必须计算出该文件名所占的内存空间
int nLength = (strlen(pszFileName)+1)*sizeof(char);
接下来使用VirtualAllocEx函数为DLL文件名在目标进程中分配地址空间,在使用WriteProcessMemory将
DLL的文件名拷贝到刚刚分配的地址中。
下一步就是取得LoadLibraryA函数的入口地址
PTHREAD_START_ROUTINE pfnLoadLibraryA =
(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
因为kernel32.dll模块是系统的核心模块,所以该模块中的函数地址在所有进程中全都相同。
我们在本进程中得到的LoadLibraryA函数的入口地址同样适用于其他进程。
所有条件已经具备,最后我们使用CreateRemoteThread函数,将LoadLibraryA函数的入口地址以及DLL的文件
名作为参数,即可让目标进程加载我们自己的DLL,至于你要让你的DLL中运行什么代码,就自己看着办吧!
让远程进程挂接自己的DLL的思路就是这样,下面给出完整代码:
#include <windows.h> #include <psapi.h> #include <string> #include <iostream> #pragma comment(lib, "Psapi.lib") //提升进程访问权限 void enableDebugPriv() { HANDLE hToken; LUID sedebugnamue; TOKEN_PRIVILEGES tkp; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return; if (!LookupPrivilegue(NULL, SE_DEBUG_NAME, &sedebugnamue)) { CloseHandle(hToken); return; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Luid = sedebugnamue; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) CloseHandle(hToken); } //根据进程名称取得进程ID,如果有多个运行实例则返回第一个枚举出来的进程ID DWORD getSpecifiedProcessId(const char* pszProcessName) { DWORD processId[1024], cbNeeded, dwProcessesCount; HANDLE hProcess; HMODULE hMod; char szProcessName[MAX_PATH] = "UnknownProcess"; DWORD dwArrayInBytes = sizeof(processId)*sizeof(DWORD); if (!EnumProcesses(processId, dwArrayInBytes, &cbNeeded)) return 0; //计算数组中的元素个数 dwProcessesCount = cbNeeded / sizeof(DWORD); enableDebugPriv(); for (UINT i = 0; i < dwProcessesCount; i++) { hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId[i]); if (!hProcess) { continue; } else { if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) { GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName)); if (!_stricmp(szProcessName, pszProcessName)) { CloseHandle(hProcess); return processId[i]; } } } } CloseHandle(hProcess); return 0; } int main(int argc, char* argv[]) { std::cout << "please input the name of target process !" << std::endl; //等待输入进程名称 std::string strProcessName; std::cin >> strProcessName; //在这里为了简单起见,使用了绝对路径 char szDllPath[MAX_PATH] = "D://test.dll"; char szFileName[MAX_PATH] = "D://test.dll"; //提升进程访问权限 enableDebugPriv(); if (strProcessName.empty()) { MessageBox(NULL, "The target process name is invalid !", "Notice", MB_ICONSTOP); return -1; } //根据进程名称得到进程ID DWORD dwTargetProcessId = getSpecifiedProcessId(strProcessName.c_str()); HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetProcessId); if (!hTargetProcess) { MessageBox(NULL, "Open target process failed !", "Notice", MB_ICONSTOP); return -1; } //计算DLL文件名称所占的存储空间 int memorySize = (strlen(szDllPath) + 1) * sizeof(char); //在目标进程中开辟存储空间,用来存放DLL的文件名称 char* pszFileNameRemote = (char*)VirtualAllocEx(hTargetProcess, 0, memorySize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (!pszFileNameRemote) { MessageBox(NULL, "Alloc dll name string in target process failed !", "Notice", MB_ICONSTOP); return -1; } //将DLL的文件名写入目标进程地址空间 if (!WriteProcessMemory(hTargetProcess, pszFileNameRemote, (LPVOID)szFileName, memorySize, NULL)) { MessageBox(NULL, "Write dll name string to target process failed !", "Notice", MB_ICONSTOP); return -1; } PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); HANDLE hRemoteThread = CreateRemoteThread(hTargetProcess, NULL, 0, pfnStartAddr, pszFileNameRemote, 0, NULL); WaitForSingleObject(hRemoteThread, INFINITE); VirtualFreeEx(hTargetProcess, 0, memorySize, NULL); if (hRemoteThread) CloseHandle(hTargetProcess); return 0; }
本文参考了西祠高手shotgun的《揭开木马的神秘面纱》,代码为自己所写,放在这里供大家参考。
大家可以参考上面的步骤自己实现一遍!
相关文章推荐
- 通过远程线程向其他进程注入代码
- 远程线程的注入和注出
- InjectDLL 远程注入 线程插入
- 注入远程线程简单例子[修改]
- 外挂或病毒注入DLL到宿主进程,然后远程启动线程方式
- 远程注入线程
- (学习记录)代码注入之远程线程篇
- 代码注入之远程线程篇
- Dll注入技术之远程线程注入
- 利用远程线程将代码注入到目标进程中执行
- 线程的远程注入
- 利用远程线程直接注入
- 使用远程线程来注入DLL
- 利用远程线程无DLL直接注入
- 利用远程线程将代码注入到目标进程中执行
- 初探线程的远程注入
- WinAPI【远程注入】 远线程直接代码注入 Delphi实例
- 线程远程注入
- 进程注入DLL实现(APC和远程线程创建)
- 利用远程线程实现dll的注入