1

今日、ソース インジェクトについて説明する記事 (http://www.codeproject.com/KB/threads/winspy.aspx) を読み、同じことを行うプログラムを作成してみました。しかし、ソースを winmind に注入すると、クラッシュします。クラッシュの理由が見つかりません。

私のコード:

1.注入データ構造体の記述

typedef LRESULT (WINAPI *MESSAGEBOX)(HWND, LPCWSTR, LPCWSTR, UINT);

typedef struct {
HWND hwnd;
    UINT type;
    MESSAGEBOX fnMessageBox;            // pointer to user32!SendMessage
    BYTE pbText[64 * sizeof(TCHAR)];    // text param
    BYTE pbTextCap[64 * sizeof(TCHAR)]; // caption param
} INJDATA, *PINJDATA;

2.注入されるコード

static int WINAPI ThreadFunc (INJDATA *pData)
{
    int nXferred = 0;

    nXferred = pData->fnMessageBox( pData->hwnd, (LPCWSTR)pData->pbText, (LPCWSTR)pData->pbTextCap, pData->type );
    pData->pbText [63 * sizeof(TCHAR)] = __TEXT('\0');
    pData->pbTextCap [63 * sizeof(TCHAR)] = __TEXT('\0');       

    return nXferred;
}


// This function marks the memory address after ThreadFunc.
// int cbCodeSize = (PBYTE) AfterThreadFunc - (PBYTE) ThreadFunc.
static void AfterThreadFunc (void) {
}

3.ThreadFuncとINJDATAをリモートプロセスにコピーし、リモートThreadFuncの実行を開始する

int CallMessageBox (HANDLE hProcess, HWND hWnd, LPCWSTR pbString, LPCWSTR pbStringCap)
{   
    HINSTANCE   hUser32;
    INJDATA     *pDataRemote;   // the address (in the remote process) where INJDATA will be copied to;
    DWORD       *pCodeRemote;   // the address (in the remote process) where ThreadFunc will be copied to;
    HANDLE      hThread = NULL; // the handle to the thread executing the remote copy of ThreadFunc;
    DWORD       dwThreadId = 0;

    int       nCharsXferred = 0; // number of chars retrieved by WM_GETTEXT in the remote thread;
    DWORD dwNumBytesXferred = 0; // number of bytes written/read to/from the remote process;

    __try {
        hUser32 = GetModuleHandle(__TEXT("user32"));
        if (hUser32 == NULL)
            __leave;

        // Initialize INJDATA and then 
        // copy it to the remote process
        INJDATA DataLocal = {
            hWnd,
            MB_OK,
            (MESSAGEBOX) GetProcAddress(hUser32, "MessageBoxW")         
        };

        if( DataLocal.fnMessageBox == NULL )
            __leave;        

        wcscpy((LPWSTR) DataLocal.pbText, (LPCWSTR) pbString);
        wcscpy((LPWSTR) DataLocal.pbTextCap, (LPCWSTR) pbStringCap);

        // 1. Allocate memory in the remote process for INJDATA
        // 2. Write a copy of DataLocal to the allocated memory
        pDataRemote = (INJDATA*) VirtualAllocEx( hProcess, 0, sizeof(INJDATA), MEM_COMMIT, PAGE_READWRITE );
        if (pDataRemote == NULL)
            __leave;
        WriteProcessMemory( hProcess, pDataRemote, &DataLocal, sizeof(INJDATA), &dwNumBytesXferred );


        // Calculate the number of bytes that ThreadFunc occupies
        const int cbCodeSize = ((LPBYTE) AfterThreadFunc - (LPBYTE) ThreadFunc);

        // 1. Allocate memory in the remote process for the injected ThreadFunc
        // 2. Write a copy of ThreadFunc to the allocated memory
        pCodeRemote = (PDWORD) VirtualAllocEx( hProcess, 0, cbCodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE );       
        if (pCodeRemote == NULL)
            __leave;
        WriteProcessMemory( hProcess, pCodeRemote, &ThreadFunc, cbCodeSize, &dwNumBytesXferred );


        // Start execution of remote ThreadFunc
        hThread = CreateRemoteThread(hProcess, NULL, 0, 
                (LPTHREAD_START_ROUTINE) pCodeRemote,
                pDataRemote, 0 , &dwThreadId);
        if (hThread == NULL)
            __leave;

        WaitForSingleObject(hThread, INFINITE);

        }
    __finally {

        if ( pDataRemote != 0 )
            VirtualFreeEx( hProcess, pDataRemote, 0, MEM_RELEASE );

        if ( pCodeRemote != 0 )
            VirtualFreeEx( hProcess, pCodeRemote, 0, MEM_RELEASE );

        if ( hThread != NULL ) {
            GetExitCodeThread(hThread, (PDWORD) &nCharsXferred);
            CloseHandle(hThread);           
        }
    }

    // Return the number of chars retrieved 
    return nCharsXferred;
}
4

1 に答える 1

3

残念ながら、この説明は古くなっています。Windows の最新バージョンには、ASLR (アドレス空間レイアウトのランダム化) と呼ばれる保護機能があります。基本的なコード インジェクションからそれらを保護し、各プロセスが独自のアドレス空間を持つようにします。すべてのプロセスで ASLR が有効になっているわけではありませんが、ほとんどの場合、古い技術は適合しません。

編集: 挿入されたコードが実行された後、クラッシュしましたか? その場合、おそらく EIP レジスタがインクリメントされているが、挿入されたシェルコードで実行する命令がこれ以上ないためです。割り当てられたメモリに命令ポインターを設定してコードを実行しましたが、その後、プロセスには実行する有効な命令がなくなりました。これを防ぐために、もう少しメモリを割り当てて単純なシェルコードを作成します。このシェルコードは単純に無限にループし、EIP がメモリ内でランダムなことを実行するのを防ぎます。

于 2012-11-10T15:21:36.693 に答える