日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

多线程inline hook

發(fā)布時(shí)間:2025/3/21 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程inline hook 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

當(dāng)要hook的代碼不停地被其他線程調(diào)用時(shí),直接memset改代碼是不行的,程序會(huì)崩,這時(shí)有一種簡(jiǎn)單的辦法來解決這個(gè)問題,就是使用 InterlockedExchange64 宏。
https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedexchange64
這個(gè)宏做的事情就是復(fù)制,但是它是“原子賦值”,因此不用擔(dān)心線程互斥問題。我猜這個(gè)宏底層實(shí)現(xiàn)原理可能是給要寫的內(nèi)存設(shè)置了一個(gè)互斥體之類的東西,或者是把其他訪問這個(gè)地址的線程先掛起了。

下面是演示代碼,這個(gè)代碼是我寫的泰拉瑞亞輔助里面摳出來的。

// 設(shè)置HOOK的函數(shù),將originalCodeAddr處的originalSize個(gè)字節(jié)替換成5字節(jié)的JMP,跳轉(zhuǎn)到newCodeAddr BOOL SetInlineHook(DWORD originalCodeAddr, DWORD originalSize, DWORD newCodeAddr) {if (originalCodeAddr == 0 || originalSize < 5 || originalSize > 8 || newCodeAddr == 0){return FALSE;} // 設(shè)置內(nèi)存寫權(quán)限DWORD dwOldProtectFlag;BOOL bRet = VirtualProtect((LPVOID)originalCodeAddr, originalSize, PAGE_EXECUTE_READWRITE, &dwOldProtectFlag);if (!bRet){return FALSE;}// 計(jì)算E9 JMP后面的4字節(jié) = 要跳轉(zhuǎn)的地址 - CALL的下一條指令的地址DWORD dwJmpCode = newCodeAddr - (originalCodeAddr + 5);// 構(gòu)造替換的8字節(jié)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);// 恢復(fù)內(nèi)存屬性VirtualProtect((LPVOID)originalCodeAddr, originalSize, dwOldProtectFlag, &dwOldProtectFlag);return TRUE; }

總結(jié)

以上是生活随笔為你收集整理的多线程inline hook的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。