美文网首页
每日总结-第三十八天-代码注入

每日总结-第三十八天-代码注入

作者: SamiraG | 来源:发表于2020-05-20 15:16 被阅读0次

    代码注入是一种向目标进程插入独立运行代码并使之运行的技术,一般调用CreateRemoteThread()API以远程线程形式运行插入的代码,所以也被称为线程注入。
    首先向目标进程插入代码和数据,在此过程中,代码以线程过程形式插入,而代码中使用的数据则以线程参数的形式传入,也就是说代码与数据是分别注入的。

    // CodeInjection.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    #include "windows.h"
    #include "stdio.h"
    #include "windef.h"
    typedef struct _THREAD_PARAM
    {
        //FARPROC是一个(int FAR WINAPI*)()类型的指针
        FARPROC pFunc[2];  // LoadLibraryA(), GetProcAddress()
        char szBuf[4][128];  // "user32.dll", "MessageBoxA",
                             // "www.reversecore.com", "ReverseCore"
    } THREAD_PARAM, *PTHREAF_PARAM;
    
    // LoadLibraryA() 函数指针PFLOADLIBRARYA
    typedef HMODULE (WINAPI *PFLOADLIBRARYA)(LPCSTR lpLibFileName);
    
    // GetProcAddress()
    typedef FARPROC (WINAPI *PFGETPROCADDRESS)
    (
        HMODULE hModule,
        LPCSTR lpProcName
    );
    
    // MessageBoxA()
    typedef int (WINAPI *PFMESSAGEBOXA)
    (
        HWND hWnd,
        LPCSTR lpText,
        LPCSTR lpCaption,
        UINT uType
    );
    
    // Thread Procedure
    DWORD WINAPI ThreadProc(LPVOID lParam)
    {
        PTHREAF_PARAM pParam = (PTHREAF_PARAM)lParam;
        HMODULE hMod = NULL;
        FARPROC pFunc = NULL;
    
        // LoadLibraryA("user32.dll")
        // pParam->pFunc[0] -> kernel32!LoadLibraryA()
        // pParam->szBuf[0] -> "user32.dll"
        hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]);
    
        // GetProcAddress("MessageBoxA")
        // pParam->pFunc[1] -> kernel32!GetProcAddress()
        // pParam->szBuf[1] -> "MessageBoxA"
        pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod, 
            pParam->szBuf[1]);
    
        // MessageBoxA(NULL, "www...", "ReverseCore", MB_OK)
        // pParam->szBuf[2] = "www..."
        // pParam->szBuf[3] = "ReverseCore"
        ((PFMESSAGEBOXA)pFunc)(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
    
        return 0;
    }
    
    BOOL InjectCode(DWORD dwPID)
    {
        HMODULE hMod = NULL;
        THREAD_PARAM param = { 0, };
        HANDLE hProcess = NULL;
        HANDLE hThread = NULL;
        LPVOID pRemoteBuf[2] = { 0, };
        DWORD dwSize = 0;
    
        hMod = GetModuleHandleA("kernel32.dll");
    
        param.pFunc[0] = GetProcAddress(hMod, "LoadLibraryA");
        param.pFunc[1] = GetProcAddress(hMod, "GetProcAddress");
        strcpy_s(param.szBuf[0], "user32.dll");
        strcpy_s(param.szBuf[1], "MessageBoxA");
        strcpy_s(param.szBuf[2], "www.reversecore.com");
        strcpy_s(param.szBuf[3], "ReverseCore");
    
        // OpenProcess
        hProcess = OpenProcess(PROCESS_ALL_ACCESS,
            FALSE,
            dwPID);
    
        // Allocation for THREAD_PRARM
        dwSize = sizeof(THREAD_PARAM);
        pRemoteBuf[0] = VirtualAllocEx(hProcess, 
            NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
        if (pRemoteBuf[0] == NULL)
        {
            printf("VirtualAllocEx failed\n");
            return FALSE;
        }
        if (!WriteProcessMemory(hProcess,
            pRemoteBuf[0], (LPVOID)&param, dwSize, NULL))
        {
            printf("WriteProcessMemory failed\n");
            return FALSE;
        }
    
        // Allocation for ThreadProc
        dwSize = (DWORD)InjectCode - (DWORD)ThreadProc;
        printf("dwSize: %d\n", dwSize);
        pRemoteBuf[1] = VirtualAllocEx(hProcess, NULL, dwSize,
            MEM_COMMIT, PAGE_EXECUTE_READWRITE);  // 这里注意要有可执行权限
        if (pRemoteBuf[1] == NULL)
        {
            printf("VirtualAllocEx failed\n");
            return FALSE;
        }
        if (!WriteProcessMemory(hProcess, pRemoteBuf[1],
            (LPVOID)ThreadProc, dwSize, NULL))
        {
            printf("WriteProcessMemory failed\n");
            return FALSE;
        }
    
        hThread = CreateRemoteThread(hProcess,
            NULL,
            0,
            (LPTHREAD_START_ROUTINE)pRemoteBuf[1],
            pRemoteBuf[0],
            0,
            NULL);
        if (hThread == NULL)
        {
            printf("CreateRemoteThread failed\n");
            return FALSE;
        }
    
        WaitForSingleObject(hThread, INFINITE);
    
        CloseHandle(hThread);
        CloseHandle(hProcess);
    
        return TRUE;
    }
    
    int main(int argc, char *argv[])
    {
        DWORD dwPID = 0;
    
        if (argc != 2)
        {
            printf("\n usage: %s PID\n", argv[0]);
            return 1;
        }
    
        dwPID = (DWORD)atol(argv[1]);
        InjectCode(dwPID);
    
        return 0;
    }
    

    执行的时候注意要生成release版本,因为MS Virual C++中使用Release模式编译程序代码后,源代码中函数顺序与二进制代码中的顺序是一致的,所以代码中的InjectCode-ThreadProc才可以表示ThreadProc函数的大小。
    将PID设置成notepad.exe的PID时,结果如下:

    相关文章

      网友评论

          本文标题:每日总结-第三十八天-代码注入

          本文链接:https://www.haomeiwen.com/subject/aglgohtx.html