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,如果有多个运行实例的话,返回第一个枚举到的进程的ID
DWORD 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)
#endif

BOOL 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