dll 주입의 APC 주입

4186 단어
APC 주입의 원리는 스레드가 깨어났을 때 APC의 등록 함수가 실행되는 메커니즘을 이용하여 우리의 DLL 로드 코드를 실행하고 DLL 주입의 목적을 완성하는 것이다. 구체적인 절차는 다음과 같다.
1) EXE        SleepEx()  WaitForSingleObjectEx() ,           (   Messagebox       OK       )。

2)         ,        APC          。

3)  QueueUserAPC()  API           APC          ,        Loadlibrary()      ,      DLL   。

절차는 다음과 같습니다.
// TESTAPC2.cpp :              。
//

#include "stdafx.h"
#include 
#include
#include
#include
#include
#pragma comment(lib,"shlwapi.lib")
#pragma comment(lib,"ntdll.lib")
using namespace std;
//       PID
DWORD GetPidFormName(wstring wsProcessname)
{
    HANDLE hSnaoshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnaoshot == INVALID_HANDLE_VALUE)
    {
        return false;
    }
    PROCESSENTRY32W pe = { sizeof(pe) };
    BOOL bok;
    for (bok = Process32FirstW(hSnaoshot, &pe); bok; bok = Process32NextW(hSnaoshot,&pe))
    {
        wstring wsNowProcName = pe.szExeFile;
        if (StrStrI(wsNowProcName.c_str(), wsProcessname.c_str()) != NULL)
        {
            CloseHandle(hSnaoshot);
            return pe.th32ProcessID;
        }
    }
    CloseHandle(hSnaoshot);
    return 0;
}
//dll        wsProcessname
BOOL Injection_APC(const wstring &wsProcessname, const WCHAR wcCacheInDllPath[])
{
    DWORD dwProcessId = GetPidFormName(wsProcessname);
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (!hProcess)
    {
        return FALSE;
    }
    PVOID lpData = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    DWORD dwRet;
    if (lpData)
    {
        //              dll    
        WriteProcessMemory(hProcess, lpData, (LPVOID)wcCacheInDllPath,MAX_PATH, &dwRet);
        CloseHandle(hProcess);
    }
    //    
    THREADENTRY32 te = { sizeof(te) };
    HANDLE handleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);//         
    if (handleSnap == INVALID_HANDLE_VALUE)
    {
        return false;
    }
    bool bstat = false;
    if (Thread32First(handleSnap, &te))
    {
        do {
            if (te.th32OwnerProcessID == dwProcessId)
            {
                HANDLE handleThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
                if (handleThread)
                {
                    DWORD dwRet = QueueUserAPC((PAPCFUNC)LoadLibraryW, handleThread, (ULONG_PTR)lpData);
                }
                if (dwRet > 0)
                {
                    bstat = TRUE;
                }
                CloseHandle(handleThread);
            }
        } while (Thread32Next(handleSnap, &te));
        CloseHandle(handleSnap);
        return bstat;
    }

    }
    int main()
    {
        Injection_APC(L"testapc.exe", L"testapcdll.dll");
        return 0;
    }

테스트 exe 프로그램:
    #include
    int main()
    {
        MessageBox(NULL, L"start", L"tit", MB_OK);
        SleepEx(1000 * 60 * 5, true);
        MessageBox(NULL, L"end", L"tit", MB_OK);
        Sleep(-1);
    }

dll 프로그램을 테스트하려면 다음과 같이 하십시오.
#include
#include"dll.h"
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved)
{
    switch (dwReason)
    {
        //                  
    case DLL_PROCESS_ATTACH:
        MessageBox(NULL, L"in apc ok~", L"tit", MB_OK);
        /**
        *  DLL       (LoadLibrary),            ,
        *             false   DLL         
        **/
        break;

        //           
    case DLL_THREAD_ATTACH:

        break;

        //             
    case DLL_THREAD_DETACH:

        break;

        //          
    case DLL_PROCESS_DETACH:
        /**
        *  DLL        (FreeLibrary),           
        *      ,       
        **/
        break;
    }
    return 1;
}
/*
void helloDLL(void)
{
//MessageBox(NULL, TEXT("Hello DLL~"), TEXT("Title"), MB_OK);
}*/

좋은 웹페이지 즐겨찾기