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 寄存器增加了,但在注入的 shellcode 中没有更多指令可以执行。您将指令指针设置为分配的内存并执行代码,但在该过程之后只是没有更多有效的指令可以执行。为了防止这种情况,我会分配更多的内存并编写一个简单的 shellcode,它会简单地无限循环并防止 EIP 在内存中执行一些随机的事情。

于 2012-11-10T15:21:36.693 回答