多线程inline hook
生活随笔
收集整理的這篇文章主要介紹了
多线程inline hook
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
當要hook的代碼不停地被其他線程調用時,直接memset改代碼是不行的,程序會崩,這時有一種簡單的辦法來解決這個問題,就是使用 InterlockedExchange64 宏。
https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedexchange64
這個宏做的事情就是復制,但是它是“原子賦值”,因此不用擔心線程互斥問題。我猜這個宏底層實現原理可能是給要寫的內存設置了一個互斥體之類的東西,或者是把其他訪問這個地址的線程先掛起了。
下面是演示代碼,這個代碼是我寫的泰拉瑞亞輔助里面摳出來的。
// 設置HOOK的函數,將originalCodeAddr處的originalSize個字節替換成5字節的JMP,跳轉到newCodeAddr BOOL SetInlineHook(DWORD originalCodeAddr, DWORD originalSize, DWORD newCodeAddr) {if (originalCodeAddr == 0 || originalSize < 5 || originalSize > 8 || newCodeAddr == 0){return FALSE;} // 設置內存寫權限DWORD dwOldProtectFlag;BOOL bRet = VirtualProtect((LPVOID)originalCodeAddr, originalSize, PAGE_EXECUTE_READWRITE, &dwOldProtectFlag);if (!bRet){return FALSE;}// 計算E9 JMP后面的4字節 = 要跳轉的地址 - CALL的下一條指令的地址DWORD dwJmpCode = newCodeAddr - (originalCodeAddr + 5);// 構造替換的8字節BYTE bReplace[8] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };//全部用NOP替換 bReplace[0] = 0xE9; // JMP*(PDWORD)(&(bReplace[1])) = dwJmpCode;memcpy((LPVOID)((DWORD)bReplace + originalSize), (LPVOID)(originalCodeAddr + originalSize), 8 - originalSize);LONG64 llReplace;memcpy(&llReplace, bReplace, 8);// 原子操作hookInterlockedExchange64((LONG64 volatile *)originalCodeAddr, llReplace);// 恢復內存屬性VirtualProtect((LPVOID)originalCodeAddr, originalSize, dwOldProtectFlag, &dwOldProtectFlag);return TRUE; }總結
以上是生活随笔為你收集整理的多线程inline hook的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用AheadLib生成DLL劫持代码
- 下一篇: TLS调试检测和反调试