HOOK這是一種思想

1、H 0 0 K:
 不知道何時開始,我不喜歡叫這些知識爲技術,喜歡把這些知識叫作思想。技術只是實現思想的一種行爲。
 HOOK這是一個很古老的話題,我見過最先的帖子日期在2004年左右,而我2018年才學習,不變的是思想。windows


2、用戶層:
 windows下用戶層被泛指三環,上層社會,比較高端繁華的地方,讓人嚮往,確實很棒。數組


3、內核層:
 windows下內核層泛指零環,底層社會,硬件、驅動設備等等協調工做,無時無刻輸送着勞動成果,他們沒有華麗外表封裝本身,可是他們並不醜陋,相反的是他們真的很"偉大"。

4、聊聊那些HOOK先關的學問
 那時候的人真聰明,想出各類辦法去繞過、截獲,利用本來的軌道辦一些本身事情,簡單說這就是我理解的Hook。
HOOK這是一種思想
 爲何放上去一張很Lol的圖呢?這是我第一次理解、見到HOOK的樣子,我仍然覺着他很溫馨。之前也總喜歡用工具畫一些精美的圖片,如今除了寫文檔報告,都是用這種草稿圖,感受更爲親切。
 Hook是有目的,有需求點,纔去截獲某一個過程,去實現本身的功能又不影響系統正常的運轉。
 Hook手段滿天飛,inlinehook、IAThook、IDThook、Objecthook、SSDThook,很遺憾很遺憾,除了新鮮感,如今的學習徹底體會不到那個年代的樂趣,這是我接觸Hook的感觸。

Inlinehook: jmp跳轉,我的感受跳轉的水平決定你的代碼的穩定性。注意會破壞棧頂的5個字節,由於jmp 0x...會佔用函數開始前5個字節,先讀取原函數的前5個字節保存,而後在進行替換jmp跳轉,執行jmp之後,要執行保存的原函數機器碼,而後在跳到jmp下一條指令執行。
HOOK這是一種思想ide


IAThook:
 瞭解PE的人知道IAT(import address table),脫殼過程當中被加密最頻繁的地方,開闢虛擬空間加密、解密IAT。在PE頭中擴展頭裏面最後一個數組(數據目錄表)中的第2項(下標1)與第12項(下標11)均可以找到對應IAT的RVA。
 《windows PE權威指南中》導入表的結構又稱雙橋結構,其中一條橋在加載到內存後就會被填充成IAT(FirstThunk),而經過尋找另外一條橋INT(OriginalFirstThunk)實現函數綁定。因此單橋沒法進行函數綁定其實INT與IAT在文件中指向的是同一個結構體_IMAGE_THUNK_DATA32這種結構體,可是加載到內存後會把IAT填充成正確的函數地址,可執行程序才能在內存中找IAT調用正確的函數地址。
 說道這裏你應該明白什麼是IAT:保存加載到內存後正確的函數地址數組。Iathook就很明顯了,替換函數地址,從而該進程或者線程調用函數的時候,去IAT找到的是咱們本身的函數地址便可。
HOOK這是一種思想
籠統的說inthook分爲三步,如上圖所示:
第一步、你要知道應用程序在調用函數的時候會去找IAT,獲取IAT中保存的地址,知道了這些東西之後,你知道去截獲、替換的是什麼,就是地址。
第二步、咱們找到IAT,通常狀況下咱們不去找IAT,咱們只須要經過GetProcAddress()或者直接用函數名(函數名編譯器看來就是地址)就能夠獲取。而後找到被應用程序調用的函數,如何去找呢?最簡單的辦法逆向看一看它調用了那些函數就好了。
第三步、替換IAT表中原來函數地址,替換前先保存原地址,備份一下,而後把本身函數地址填充上去便可。函數

那麼替換這些能幹一些什麼事情呢?看兩張圖
結束進程失敗:
HOOK這是一種思想
掛起進程失敗:
HOOK這是一種思想
360進程用procexp.exe或則任務管理器沒法結束沒法掛起呢?雖然不必定用iathook,可是用iathook是能夠作到的。
 上一篇博客寫的雙進程,先掛起單個進程,就能夠破掉雙進程。hook能夠保護你不被掛起,不被結束,比起雙進程守護更爲穩定實用,一樣複雜程度也要高不少。工具

改進後的雙進程保護程序:
先來看看這個功能:
HOOK這是一種思想性能

 基於mfc窗口,拖拽須要保護的可執行文件。可是這個進程是能夠被結束的,利用線程回調檢測被保護的進程狀態,若是被結束,馬上新建立新的進程,而後使用等待函數等待響應,這樣就不會一直循環影響系統性能
 這裏沒有用任何的hook知識,用到了建立快照,3環的進程遍歷,以及建立線程回調線程回調好處不影響當前進程的操做流程,並且暫停保護功能只須要將線程掛起便可、開啓保護功能只須要將該線程喚醒,大大的節省了代碼量及運行效率。(如下代碼未用這種思路正常關閉線程)
 仍是有一些學習價值,因此把代碼貼上來,相關的地方都給了詳細的註釋,這裏再也不囉嗦。學習

代碼實現以下:
須要類中聲明、定義的變量及函數:this

// This Process True?
    BOOL IsCurrentProcessTrue();

    // CallbackFunctionHandle
    HANDLE m_Handle = NULL;

    // DriverObject
    HANDLE hDriver = INVALID_HANDLE_VALUE;

    // SavePid
    static CString g_PathValue;

    // GetProcessFileName
    static CString g_FilePath;

主要實現代碼:加密

// The CallBack Function
DWORD WINAPI ThreadPrcCallBack(LPVOID lparameter)
{
    ProcessProtectMaster *pDlg = (ProcessProtectMaster*)lparameter;

    STARTUPINFO g_si = {};

    PROCESS_INFORMATION g_pi = {};

    while (true)
    {
        // 若是遍歷進程發現Pid爲假(開啓新的進程)
        if (!pDlg->IsCurrentProcessTrue())
        {
            CreateProcess(pDlg->g_FilePath, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &g_si, &g_pi);

            WaitForSingleObject(g_pi.hProcess, INFINITE);

            CloseHandle(g_pi.hProcess);

            CloseHandle(g_pi.hThread);
        }
    }

    return 1;
}

// Is Process True?
BOOL ProcessProtectMaster::IsCurrentProcessTrue()
{
    HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hProcess == INVALID_HANDLE_VALUE)
    {
        AfxMessageBox(L"建立快照失敗");

        return FALSE; 
    }

    PROCESSENTRY32W p_32 = { sizeof(PROCESSENTRY32W) };

    if (!Process32First(hProcess, &p_32))
    {
        AfxMessageBox(L"Process32First falure!");
        CloseHandle(hProcess);
        return FALSE;
    }

    do{
        // 經過進程句柄獲取文件映像路徑
        // GetProcessImageFileName(hProcess, Pathbuf, MAX_PATH);
        // 強轉CString對比能夠用==
        CString temp = p_32.szExeFile;
        // 若是檢測到有被保護進程則返回爲真
        if (g_PathValue == temp)
            return TRUE;

    } while (Process32Next(hProcess, &p_32));

    // 沒有檢測到被保護進程爲假
    return FALSE;
}

// Start Process_Protect
void ProcessProtectMaster::OnBnClickedButton1()
{
    HANDLE hProcess = INVALID_HANDLE_VALUE;

    // 1. 接收輸入的PID
    UpdateData();

    // 1.1 把獲取的PID保存在靜態變量中(回調函數會用)
    g_FilePath = m_Edit;

    // 1.2 獲取文件名
    int nPos = g_FilePath.ReverseFind(_T('\\'));

    g_PathValue = g_FilePath.Mid(nPos + 1);

    // 2. 判斷當前進程是否有效
    if (!IsCurrentProcessTrue())
    {
        AfxMessageBox(L"Process Flase");

        return;
    }

    // 3.顯示開啓保護進程
    m_ShowValue.SetWindowTextW(L"已開啓保護");

    // 4. 保護當前PID(一直檢測PID,當進程被結束當即打開新的進程)
    m_Handle = CreateThread(NULL, NULL, ThreadPrcCallBack, (LPVOID)this, NULL, NULL);

}

// Stop Process_Protect
void ProcessProtectMaster::OnBnClickedButton2()
{
    // 取消保護
    DWORD nRet = TerminateThread(m_Handle, NULL);

    if (nRet)
    {
        AfxMessageBox(L"進程守護關閉");

        m_StatucShow = "未啓用";

        // 關閉狀態更新到窗口 
        UpdateData(FALSE);
    }
    else
        // 獲取回調線程的pid
        // DWORD t_Pid = GetThreadId(m_Handle);
        // 能夠cmd Kill -9 pid
        AfxMessageBox(L"請從新嘗試");

}

// The Response File Receive
void ProcessProtectMaster::OnDropFiles(HDROP hDropInfo)
{
    // 1.得到拖拽數目
    int DropCount = DragQueryFile(hDropInfo, -1, NULL, 0);

    // 2.保存獲取的路徑信息
    char wcStr[MAX_PATH] = {};

    CString str;

    for (int i = 0; i < DropCount; i++)
    {
        // 3.記得清空字符串
        wcStr[0] = 0;

        // 4.獲取路徑名
        DragQueryFileA(hDropInfo, i, wcStr, MAX_PATH);

        str = wcStr;
    }

    // 直接用控件綁定變量會出現緩衝區太小問題
    m_Edit = str;

    UpdateData(FALSE);

    // 5.釋放內存
    DragFinish(hDropInfo);

    CDialogEx::OnDropFiles(hDropInfo);
}

HOOK這是一種思想

 關於這兩個功能一個是IAThook,一個是ssdthook。一個三環,一個零環,Hook思想是不分三環仍是零環的,零環也一樣有iathook、inlinehook,他並非三環的專屬。下次博客更新內容是與windows內核一些東西,順帶把hook源碼講解一下與你們分享。線程

相關文章
相關標籤/搜索