2013-04-29 66 views
14

我正在做一個所謂的'噓鉤'。實際上它改變了內存區域的權限,並在訪問時捕獲異常,因此可以掛鉤該功能。設置單步陷阱可用贏7?

它採用了單步陷阱,看起來像:

info->ContextRecord->EFlags |= 0x100; 

恢復保護PAGE_NOACCESS

該應用程序在win xp上運行良好,但不像win 7那樣運行得很好。它在win 7上剛被凍結。我非常懷疑這是因爲'設置單步陷阱'的原因,但我不確定。

Click here到源包的直接下載鏈接

+3

只需按正常方式掛接該功能即可。這些瘋狂的技術很可能會將您的代碼標記爲惡意軟件。 – 2013-05-07 19:38:53

+0

你是否以管理員身份啓動該程序? Windows 7爲程序權限添加了安全級別煩惱級別。您可以通過設置鏈接器 - >清單文件 - > UAC執行級別 - > requireAdmin – typ1232 2013-05-08 15:55:32

回答

11

短的答案:

是單步標誌是x86 achitecture的一部分,並且還仍然在視窗7經由處理器的EFLAGS組件實現上下文。

我設法下載你的項目,一切工作正常,無需在UAC關閉的Windows 8上修改。所以它也可以在Windows 7上運行。當啓動VEH Hooking Test.exe它顯示兩個消息框,每獲得一個MessageBoxA控制檯輸出後,所以鉤子工作。也許嘗試在Windows 7上以管理員身份啓動該程序?


龍答:

SEH代表結構化異常處理,但你所描述聽起來更像VEH - 向量異常處理。

VEH掛鉤是一種非常慢的掛鉤方法,因此它不能真正用於性能關鍵的掛鉤,例如圖形掛鉤,例如您的掛鉤每秒觸及多次。它通常用於一次性掛鉤。 VEH掛鉤的目的是非常隱蔽。在別人的代碼中沒有寫入內存,您不必使用調試寄存器。


以下是我將如何使用C++實現它。

首先你必須註冊一個向量的異常處理程序。這是該進程的全局異常處理程序。每個拋出的未處理異常都會被這個處理程序捕獲。

PVOID pExHandler = AddVectoredExceptionHandler(1, VectoredHandler); 

之後,你應該設置頁面,在這裏您HOOK_LOCATION(地址掛鉤)的內存保護是我使用新的保護是PAGE_EXECUTE_READ|PAGE_GUARD。保護頁面會導致訪問異常,並在此後自動移除防護保護。這個異常不會被任何人處理,所以它會落入我們的嚮導處理程序。拋出異常之後,頁面可以再次訪問。 (請參閱Creating Guard Pages

內存只能在頁面中保護(通常爲0x1000字節長)。這就是爲什麼我們不僅可以保護掛鉤位置並且具有巨大的性能開銷。

DWORD orgProt; 
VirtualProtect(HOOK_LOCATION, 1, PAGE_EXECUTE_READ|PAGE_GUARD, &orgProt); 

現在爲我們的異常處理程序。這是如何看起來像:

LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS exc) 
{ 
    if (exc->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) 
    { 
     // guard page exeption occured. guard page protection is gone now 

     if (HOOK_LOCATION == reinterpret_cast<long*>(exc->ContextRecord->Eip)) { 
      // hook location was hit! call any hook callbacks here 
     } else { 
      // hook was not hit and has to be refreshed. set single-step flag 
      exc->ContextRecord->EFlags |= 0x100; 
     } 

     return EXCEPTION_CONTINUE_EXECUTION; 
    } 

    if (exc->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) 
    { 
     // single-step exeption occured. single-step flag is cleared now 

     // set guard page protection 
     DWORD oldProt; 
     VirtualProtect(HOOK_LOCATION, 1, PAGE_EXECUTE_READ|PAGE_GUARD, &oldProt); 

     return EXCEPTION_CONTINUE_EXECUTION; 
    } 

    return EXCEPTION_CONTINUE_SEARCH; 
} 

如果代碼運行到受保護的內存頁面,它會拋出守衛頁違規。我們檢查我們是否在掛鉤位置。如果我們是一切都很好,我們可以調用鉤子回調。如果我們不在正確的位置,我們需要重新保護代碼,但是如果我們現在要做,我們就無法前進,並且始終在同一位置發生異常並導致應用程序死鎖。所以我們設置處理器單步標誌。

現在當接收到單步異常時,我們可以重新設置防護保護,因爲我們是通過一條指令來進行的。這就是我們可以始終保護目標頁面並且不會錯過任何鉤子命中的原因。

成本是在目標頁面中執行的每條指令的兩個例外和一個頁面保護。不要試圖用附加的調試器來做到這一點。它會發瘋。

對於一個實際的實現,你可能需要同步對象來擺脫鉤子而不會崩潰程序和更好的掛鉤管理。

我真的很喜歡這個聰明的機制,並希望有些人瞭解一點。

+0

來請求權限。我不確定這是否回答OP問題,但感謝您的解釋,我喜歡讀它! – 2013-05-08 15:38:39

+0

@ dema80感謝您的反饋。我實際上設法猜測現在在哪裏下載文件。一切工作正常我在Windows 6.x – typ1232 2013-05-08 15:52:43

+0

@ typ1232我修改了我的問題,添加一個直接下載鏈接到源,抱歉給您帶來不便 – 2013-05-09 01:51:36