天天看點

程序注入的學習(上)

轉載請聲明出處:http://www.cnblogs.com/predator-wang/p/4792976.html

參考:http://andylin02.iteye.com/blog/459483

程序注入的方法分類如下:

    帶DLL的注入

        利用系統資料庫注入

        利用Windows Hooks注入

        利用遠端線程注入

        利用特洛伊DLL注入

    不帶DLL的注入

        直接将代碼寫入目标程序,并啟動遠端線程

1. 利用系統資料庫注入(appinit_dll 注入)

 AppInit_DLL參考:

https://support.microsoft.com/zh-cn/kb/197571

http://www.2cto.com/Article/201005/47409.html

   在Windows NT/2000/XP/2003中,有一個系統資料庫鍵值HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs。

User32.dll被加載到程序時,會擷取AppInit_DLLs系統資料庫項,若有值,則調用LoadLibrary() API加載使用者DLL。是以,DLL系統資料庫注入,并不會影響所有程序,隻會影響加載了user32.dll的程序.我們可以把自己的代碼放在一個DLL中,并加入該鍵值,這樣就可以注入到所有使用User32.dll的程序中了。

修改XP下系統資料庫:

RegDLL.dll的内容如下:

#include <windows.h>
#include <tchar.h>

#define DEF_PROCESS_NAME "explorer.exe" 

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpvRevered) {
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        HANDLE f = CreateFile(L"C://InjectSuccess.txt", FILE_ADD_FILE, FILE_SHARE_WRITE,
            NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
        CloseHandle(f);
    }
    return TRUE;
}      

當我們重新開機系統之後,會在C槽下發現:

發現這個DLL被注入到了許多exe中:

2. 利用Windows Hooks注入

   Windows系統給我們提供了一些挂鈎函數,使得被挂鈎的程序可以在自己處理接收到的消息之前,先執行我們的消息處理函數,而這個消息處理函數一般會放在DLL中,這實際上已經達到了注入代碼的效果。即,Hook住一個程序,在這個程序接收消息執行之前,搶先于它去執行。

DLL代碼,裡邊實作了挂鈎功能:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <iostream>
HHOOK g_hHook = NULL;
HINSTANCE hInst;
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    hInst = (HINSTANCE)hModule;
//     switch (ul_reason_for_call)
//     {
//     case DLL_PROCESS_ATTACH:
//     case DLL_THREAD_ATTACH:
//     case DLL_THREAD_DETACH:
//     case DLL_PROCESS_DETACH:
//         break;
//     }
    return TRUE;
}


LRESULT myKeyBrdFuncAd(int code, WPARAM wParam, LPARAM lParam)        //作為SetWindowsHook的回調函數
{
    ::MessageBoxA(NULL, "Hello Injection", "Injection", MB_OK);  
    /*std::cout << "CallBack" << std::endl;*/
    return CallNextHookEx(g_hHook, code, wParam, lParam);
}


#ifdef __cplusplus    // If used by C++ code,   
extern "C" {          // we need to export the C interface  
#endif  
    __declspec(dllexport) bool SetHook(DWORD dwThreadId)
    {
        g_hHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)myKeyBrdFuncAd, hInst, dwThreadId);
        if (g_hHook == NULL)
        {
            return false;
        }
        return true;
    }
#ifdef __cplusplus  
}
#endif        

再寫一個cpp,可以将鈎子安裝到某個線程:

#include <windows.h>
#include <iostream>

int main()
{
    typedef BOOL(*_pSetHook)(DWORD dwThreadId);
    HMODULE hDll = LoadLibrary("HookDll.dll");
    if (hDll == NULL)
    {
        std::cout << "LoadLibrary failed" << std::endl;
    }
    _pSetHook pSetHook = (_pSetHook)GetProcAddress(hDll, "SetHook");
    BOOL bRtn = (*pSetHook)((DWORD)8560);//GetCurrentThreadId()
    if (!bRtn)
    {
        std::cout << "Hook Failed" << std::endl;
    }

    FreeLibrary(hDll);
    system("pause");
    return 0;
}      

下面将這個鈎子安裝到Evernote:

先利用pstask檢視evernot的線程ID:

得到8560之後才能在上面的cpp中設定那個線程ID參數。

挂鈎線程8560之後,再向Evernote傳入鍵盤消息,先會彈出MessageBox:

然後CallNextHook才會把按鍵資訊傳入給Evernote:

再次輸入字元,先彈窗:

而後Evernote才能接收到“2”: