DLL注入

     最近的项目涉及了软件破解方面的知识,记录一下。

     将dll注入另一个进程。

// Inject.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include <TlHelp32.h>
#include <Psapi.h>
#include <tchar.h>

// LoadLibrary的不同版本
#if defined _UNICODE    
#define _LoadLibrary "LoadLibraryW"    //_UNICODE
#else
#define _LoadLibrary "LoadLibraryA"    //_MBCS
#endif

// 根据进程名获取PID
DWORD GetPID(LPTSTR lpProcess)
{
    HANDLE hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 获取进程快照句柄

    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    BOOL flag = Process32First(hProcSnap, &pe32); // 获取列表的第一个进程

    while(flag)
    {
        if(!_tcsicmp(pe32.szExeFile, lpProcess))
        {
            CloseHandle(hProcSnap);
            return pe32.th32ProcessID; //pid
        }
        flag=Process32Next(hProcSnap, &pe32); //获取下一个进程
    }

    CloseHandle(hProcSnap);
    return 0;
}

// 获取适当的Privilege
// hProcess  当前进程的handle
// Privilege 需要的Privilege
// 成功返回TRUE,失败返回FALSE
BOOL AdjustProcessPrivilege(HANDLE hProcess, TCHAR *Privilege)
{
    HANDLE hToken=NULL;
    OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);  //打开进程令牌环

    if(NULL==hToken) 
        return FALSE;

    LUID luid;
    if(!LookupPrivilegeValue(NULL, Privilege, &luid))  // 获得进程本地唯一ID
    {
        CloseHandle(hToken);
        return FALSE;
    }

    TOKEN_PRIVILEGES token_privileges;
    token_privileges.PrivilegeCount =1;
    token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    token_privileges.Privileges[0].Luid = luid;
    
    //调整进程权限
    if(!AdjustTokenPrivileges(hToken, FALSE, &token_privileges, NULL, NULL, NULL))
    {
        CloseHandle(hToken);
        return FALSE;
    }

    CloseHandle(hToken);

    return TRUE;
}

// 在进程中查找dll
HMODULE CheckProcessModule(LPTSTR lpRemoteProcess, LPTSTR lpInjectDll)
{
    DWORD nRemotePID = GetPID(lpRemoteProcess);
    HANDLE hRemoteProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, nRemotePID);

    HMODULE hMods[1024];    
    DWORD cbNeeded = 0;     // Get a handle to the process.    
    if( EnumProcessModules(hRemoteProcess, hMods, sizeof(hMods), &cbNeeded))    
    {        
        for (UINT i=0; i<(cbNeeded/sizeof(HMODULE)); i++)    
        {        
            TCHAR szModName[MAX_PATH];    // Get the full path to the module's file.        
            if (GetModuleFileNameEx(hRemoteProcess, hMods[i], szModName, sizeof(szModName)/sizeof(TCHAR)))        
            {        
                if (!_tcsicmp(lpInjectDll, szModName))
                {
                    CloseHandle(hRemoteProcess);
                    return hMods[i];
                }
            }
        }
    }

    CloseHandle(hRemoteProcess);
    return NULL;
}

BOOL InjectDll(LPTSTR lpRemoteProcess, LPTSTR lpInjectDll, BOOL bInject)
{
    // 获取SeDebugPrivilege权限
    if(FALSE == AdjustProcessPrivilege(GetCurrentProcess(), _T("SeDebugPrivilege"))) 
        return FALSE;    

    // 函数准备
    LPTHREAD_START_ROUTINE pfnThread = NULL;
    HINSTANCE hMod = GetModuleHandle(_T("kernel32.dll"));
    if (bInject) 
        pfnThread = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,_LoadLibrary);  // LoadLibrary注入
    else 
        pfnThread = (LPTHREAD_START_ROUTINE)GetProcAddress(hMod,"FreeLibrary"); // FreeLibrary卸载
    if(NULL == pfnThread) 
        return FALSE;

    __try
    {
        // 获取目标进程ID
        DWORD nRemotePID = GetPID(lpRemoteProcess);
        // 打开目标进程
        HANDLE hRemoteProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nRemotePID);
        if(hRemoteProcess == NULL)
        {
            return FALSE;
        }

        if (bInject) //注入
        {
            // 在远端进程中分配内存
            LPVOID ModName = VirtualAllocEx(hRemoteProcess, NULL, (_tcslen(lpInjectDll)+1)*sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE);
            if(!ModName)  
                __leave;

            // 在远端进程中写入dll的文件名
            if(0 == WriteProcessMemory(hRemoteProcess, ModName, lpInjectDll, (_tcslen(lpInjectDll)+1)*sizeof(TCHAR), NULL)) 
                __leave;

            // 创建远程线程
            HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, pfnThread, ModName, 0, NULL);
            if(NULL == hRemoteThread) 
                __leave;
            WaitForSingleObject(hRemoteThread,INFINITE);

            VirtualFreeEx(hRemoteProcess, ModName, 0, MEM_RELEASE);
            CloseHandle(hRemoteThread);
        }
        else //卸载
        {
            // 在进程中查找需要卸载的dll
            HMODULE hTarget = CheckProcessModule(lpRemoteProcess, lpInjectDll);
            // 创建远程线程
            HANDLE hRemoteThread = CreateRemoteThread(hRemoteProcess, NULL, 0, pfnThread, hTarget, 0, NULL);
            if(NULL == hRemoteThread) 
                __leave;
            WaitForSingleObject(hRemoteThread,INFINITE);

            CloseHandle(hRemoteThread);
        }

        CloseHandle(hRemoteProcess);
        return TRUE;
    }
    __finally
    {
    }

    return FALSE;
}

        以上已经将dll成功注入到目标进程,但是怎样让注入的dll执行?可以在dll加载时,执行一段代码。

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        Fun();  // 需要执行的代码
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

 

posted @ 2015-09-20 15:04  黑桃七  阅读(278)  评论(0编辑  收藏  举报