首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

DLL 远程线程注入解决思路

2012-03-17 
DLL 远程线程注入最近在学习远程线程注入,遇到麻烦了。我用以下代码实现DLL 远程线程注入,可是感觉DLL好像

DLL 远程线程注入
最近在学习远程线程注入,遇到麻烦了。

我用以下代码实现DLL 远程线程注入,可是感觉DLL好像没被加载。
Loader代码如下:

C/C++ code
#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;}


DLL代码如下:
C/C++ code
// 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 



程序运行时,控制台程序闪一下就退出了,没有弹出MessageBox(NULL,"CreateRemoteThread failed!","tip",MB_OK);
也没有弹出MessageBox(NULL,"ok.","ok.",MB_OK);
这是为什么呢?

哪里有错误?


如果Loader代码换成下面的话,用(CreateProcess(NULL,pcTargetFileName, NULL,NULL,FALSE,0,NULL,NULL,&StartupInfo,&ProcessInfo))去创建一个进程的话,
就运行正常了,能看到我希望的结果。

究竟先前的Loader代码哪里有问题,哪位好人心人帮帮忙!

C/C++ code
#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;}


[解决办法]
打印hRemoteThread
[解决办法]
你注入系统进程的时候,你需要把你的dll拷贝到系统目录下,loadlibrary才可以找到,注入是成功的

热点排行