DLL 远程线程注入
最近在学习远程线程注入,遇到麻烦了。
我用以下代码实现DLL 远程线程注入,可是感觉DLL好像没被加载。
Loader代码如下:
#include "stdafx.h"#include <windows.h>#include <TlHelp32.h>// 提升进程访问权限bool AdjustProcessTokenPrivilege(){ 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,如果有多个运行实例的话,返回第一个枚举到的进程的IDDWORD GetProcessIDFromName(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 (stricmp(lpszProcessName, pe.szExeFile)==0) // 大小写无关比较 { CloseHandle(hSnapshot); return pe.th32ProcessID; } } return 0;}int main(int argc, char* argv[]){ // 我们自己的DLL文件的文件名,如果不在同一目录下,需要指定完成路径 char * pszFileName = "Alert.dll"; // 计算文件名字符串的长度 int nSize = ( strlen(pszFileName) + 1 ) * sizeof(char); // 要写入目标进程的字符串参数的地址 char * pszDllFileRemote = NULL; // 提升进程访问权限 AdjustProcessTokenPrivilege(); // 得到目标进程ID DWORD dwProcessID=GetProcessIDFromName("winlogon.exe"); // 打开进程,并获得所有权限 HANDLE hRemoteProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID); // 在目标进程中分配iSize大小的空间以便将我们的DLL的文件名作为参数写入目标进程 pszDllFileRemote=(char*)VirtualAllocEx(hRemoteProcess,NULL,nSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE); // 分配成功 if(NULL != pszDllFileRemote) { // 把我们的DLL文件名写入目标进程的内存中 if(WriteProcessMemory(hRemoteProcess,pszDllFileRemote,(LPVOID)pszFileName,nSize,NULL)) { // 我们要在内存中执行的LoadLibrary函数所在的系统DLL HMODULE hModuleKernel32 = LoadLibrary("Kernel32"); // 获取Kernel32.dll中的Loadlibrary函数的地址 PTHREAD_START_ROUTINE pStart = (PTHREAD_START_ROUTINE)GetProcAddress(hModuleKernel32,"LoadLibraryA"); // 建立远程线程进行注入。 // 这里多说几句CreateRemoteThread函数是在我们的引导程序DllLoader.exe中执行的, // 如果lpParamter参数直接传递字符串的话这个字符串的内存是在DllLoader.exe中的, // 目标进程是无法访问这个地址的,这就是之所以前面很麻烦的把我们的DLL的文件名 // 用WriteProcessMemory写入到目标进程的内存中的原因,只有这样目标进程才能正确的得到文件名参数。 HANDLE hRemoteThread=CreateRemoteThread(hRemoteProcess,NULL,0,pStart,pszDllFileRemote,0,NULL); if (hRemoteThread==NULL) { MessageBox(NULL,"CreateRemoteThread failed!","tip",0); } } } return 0;}
// Alert.cpp : 定义 DLL 应用程序的入口点。//#include "stdafx.h"#ifdef _MANAGED#pragma managed(push, off)#endifBOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { MessageBox(NULL,"ok.","ok.",MB_OK); break; } } return TRUE;}#ifdef _MANAGED#pragma managed(pop)#endif
#include "stdafx.h"#include <windows.h>#include <TlHelp32.h>int main(int argc, char* argv[]){ // 我们自己的DLL文件的文件名,如果不在同一目录下,需要指定完成路径 char * pcFileName = "Alert.dll"; // 计算文件名字符串的长度 int iSize = ( strlen(pcFileName) + 1 ) * sizeof(char); // 要写入目标进程的字符串参数的地址 char * pcLibFileRemote = NULL; // 目标程序的文件名 char * pcTargetFileName="notepad.exe"; // 创建进程所需的进程信息结构体 PROCESS_INFORMATION ProcessInfo; // 创建进程所需的启动信息结构体 STARTUPINFO StartupInfo; ZeroMemory(&StartupInfo, sizeof(StartupInfo)); // 初始化工作 StartupInfo.cb = sizeof StartupInfo; // 计算大小 // 开始为目标程序建立进程 if(CreateProcess(NULL,pcTargetFileName, NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo,&ProcessInfo)) { // 打开进程,并获得所有权限 HANDLE handleTarget=OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessInfo.dwProcessId); // 在目标进程中分配iSize大小的空间以便将我们的DLL的文件名作为参数写入目标进程 pcLibFileRemote=(char*)VirtualAllocEx(handleTarget,NULL,iSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE); // 分配成功 if(NULL != pcLibFileRemote) { // 把我们的DLL文件名写入目标进程的内存中 if(WriteProcessMemory(handleTarget,pcLibFileRemote,(LPVOID)pcFileName,iSize,NULL)) { // 我们要在内存中执行的LoadLibrary函数所在的系统DLL HMODULE hmoduleKernel32 = LoadLibrary("Kernel32"); // 获取Kernel32.dll中的Loadlibrary函数的地址 PTHREAD_START_ROUTINE pStart = (PTHREAD_START_ROUTINE)GetProcAddress(hmoduleKernel32,"LoadLibraryA"); // 建立远程线程进行注入。 // 这里多说几句CreateRemoteThread函数是在我们的引导程序DllLoader.exe中执行的, // 如果lpParamter参数直接传递字符串的话这个字符串的内存是在DllLoader.exe中的, // 目标进程是无法访问这个地址的,这就是之所以前面很麻烦的把我们的DLL的文件名 // 用WriteProcessMemory写入到目标进程的内存中的原因,只有这样目标进程才能正确的得到文件名参数。 CreateRemoteThread(handleTarget,NULL,0,pStart,pcLibFileRemote,0,NULL); } } } return 0;}