色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

x86_64運行時動態替換函數的hotpatch機制

Linux閱碼場 ? 來源:未知 ? 作者:李倩 ? 2018-11-26 16:32 ? 次閱讀

晚上回去有朋友在朋友圈回復了我關于 “函數開頭5字節跳轉” 的事。今天正好要確認一個與此相關的細節,就順便又把這問題重新擼了一遍。

其實起初我也很納悶,以前不都是0x55開頭的指令嗎?怎么現在這種call self或者lea 0x0(%rsp),%rsp套路卻都成了慣例。…

關于5字節跳轉,說的是下面的情況:

請注意函數最開頭的5個字節:

可見,它實際上call的是緊接著它下面的地址,所以說這個5字節的call指令其實是 沒有用 的!

仔細看一下這5個字節,思考一下它到底有什么用。

我們可以任意將它替換成 jmp $4字節相對偏移

這樣,代碼指令流就會進入我們自己的HOOK函數里了。

當然了,關于 “e8 00 00 00 00 callq …” 這個有很多話可以講,比如和Link相聯系的時候就比較有意思了,它可是作為一個樁指令存在。這個和HOOK無關,也不再說太多。

讓我覺得最有意思的是,昨天那位朋友提到了微軟的/hotpatch編譯選項,我大致看了一下:

/hotpatch (Create Hotpatchable Image):https://docs.microsoft.com/en-us/cpp/build/reference/hotpatch-create-hotpatchable-image?view=vs-2017

When /hotpatch is used in a compilation, the compiler ensures that first instruction of each function is at least two bytes, which is required for hot patching.

這是一個很有意思的選項,其實編譯器提供這個機制也是舉手之勞吧,雖然簡單,但它確實為程序員HOOK運行中的函數提供了很大的方便。

/hotpatch的實質其實就是在函數的開頭和結尾填充了一些無關緊要的指令,方便HOOK來用自己的jmp指令覆蓋這個無關緊要的指令。比如下面是一個函數的開頭:

0x90代表一個nop指令,即 “什么也不做”的意思,如此一來,程序員便非常容易將類似下面的指令插入到函數開頭了:

無需任何額外的指令保存動作。

既然微軟的編譯器有這個功能可用,GCC有沒有呢?看了GCC的manual,發現了一個-mhotpatch=x,y的選項,但是在x86平臺不能用,還是比較不爽的。

后來發現了在編寫函數的時候,可以加上下面的屬性,然后編譯器就可以將其編譯成帶有填充的指令了:

那么,簡單來用一下,看看效果咯。

由于時間并不是很多,我也沒有那么多精力去應對不斷的panic,所以這次準備在用戶態搞。

由于用戶態可以直接使用mprotect函數更改內存的使用權限,所以就不需要那個stub函數了。今天的這個例子,原理圖如下:

加上ms_hook_prologue屬性修飾的函數,編譯好了之后,你會在函數最開頭兩行找到下面的廢指令:

隨意替換之就好。所以對于這個例子,上面圖示里的n的值就是5.

此外,上圖中,我們的一個指令buffer不再是一個stub函數,而真的就是一塊分配的內存,所以我們需要給它加上EXEC權限,不然會segment fault。這個在內核模塊中是不能直接做的,因為分配帶有EXEC權限的module_alloc并沒有導出,所以如若想用它,則必須通過kallsyms_lookup_name的內省方式來做。

再一個需要注意的是,由于指令buffer是在堆上分配的,在64位系統上,它的位置和函數代碼的位置之差會超過4個字節界定的相對偏移,所以就不能用0xe9+4字節相對偏移來jmp了,而要通過64位絕對地址來跳轉了,指令如下:

好了,說了這么多,該上代碼了:

結果當然是先調用自己的hook函數,然后再調用原始函數咯:

為什么不用kprobe機制呢?kprobe的原理是 為了靈活性,使用int 3指令替換被hook的指令。 這樣就可以任意編寫pre/post回調函數了,但是我們也能看出來,通過int方式來hook,對效率的影響是不能忽略,特別是對于那些頻繁被調用的函數,kprobe更加不可行。

kprobe非常適合做問題排查,熱點分析,但不好在生產環境跑的。

其實,本文所描述的hotpatch原理還可以做的更好些,達到 在任意點插入自己的邏輯的目的,包括在函數的內部。 這樣可以達到和kprobe相同的效果。當然,這需要對運行中的二進制指令序列做相對周密詳細的分析。

這里還有一篇關于hotpatch的文章,比我這篇好,可以看一下:

Hotpatching a C Function on x86 :https://nullprogram.com/blog/2016/03/31/

補充說明一下,朋友圈有高手最新評論,讓我又知道了些新東西:

nop指令的實現方式有很多種,比如mov edi edi。可能很多平臺并沒有類似獨立的0x90指令吧。不過既然有,那還是0x90純粹些。

kprobe也不全部一來int 3,只有return hook的場景才依賴int 3,其它的也可以做jmp hook。

線程安全,原子化操作也是生產環境必須考慮的,不然就是玩具。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 函數
    +關注

    關注

    3

    文章

    4344

    瀏覽量

    62862
  • 編譯器
    +關注

    關注

    1

    文章

    1642

    瀏覽量

    49224

原文標題:x86_64運行時動態替換函數的hotpatch機制

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    如何縮短Vivado的運行時

    在Vivado Implementation階段,有時是有必要分析一下什么原因導致運行時間(runtime)過長,從而找到一些方法來縮短運行時間。
    的頭像 發表于 05-29 14:37 ?1.4w次閱讀
    如何縮短Vivado的<b class='flag-5'>運行時</b>間

    函數運行時異常

    。是否有任何機構知道什么可能導致運行時錯誤運行時異常@ PC地址0x9D017CA0?函數:在C:/Microchip/Hyrn/V2Y03B/Frrase/GFX/LIBARARI/
    發表于 03-20 13:41

    在arm64x86服務器上運行的耗時來發現Docker在arm64架構下的性能問題

    間整理成表格。通過比較相同測試用例在arm64x86機器上的運行時間,可以發現潛在的性能問題。下圖即是數據表格的一部分。“Test case”豎列是測試用例所在文件和名字,“Qualcomm”列是在
    發表于 07-12 15:48

    如何為x86_64目標編譯88W9098?

    x86_64 目標編譯 88W9098
    發表于 04-21 08:52

    FPGA運行時重構的延遲隱藏機制研究與實現

    FPGA運行時重構的延遲隱藏機制研究與實現_劉偉
    發表于 01-07 19:08 ?0次下載

    紫金橋組態軟件新的功能_運行時組態

    運行時組態是組態軟件新近提出的新的概念。運行時組態是在運行環境下對已有工程進行修改,添加新的功能。它不同于在線組態,在線組態是在工程運行的同時,進入組態環境,在組態環境中對工程進行修改
    發表于 10-13 16:17 ?2次下載
    紫金橋組態軟件新的功能_<b class='flag-5'>運行時</b>組態

    x86_64函數調用慣例及其棧幀

    從下圖可見,x86_64架構取消了傳統的中斷形式的系統調用,使用syscall指令實現系統調用。并且存放參數的寄存器也有所變化。execve的系統調用號也從0xb變為了0x3b
    的頭像 發表于 05-01 16:41 ?5107次閱讀
    <b class='flag-5'>x86_64</b><b class='flag-5'>函數</b>調用慣例及其棧幀

    基于STM32單片機通過使用宏assert_param來實現運行時間檢測

    固件函數庫通過檢查庫函書的輸入來實現運行時間錯誤偵測。通過使用宏assert_param來實現運行時間檢測。所有要求輸入參數的函數都使用這個宏。它可以檢查輸入參數是否在允許的范圍之內。
    發表于 10-22 15:12 ?1458次閱讀
    基于STM32單片機通過使用宏assert_param來實現<b class='flag-5'>運行時</b>間檢測

    Xilinx SDAccel開發環境在X86_64位工作站的運行情況

    本視頻演示了SDAccel開發環境在一個標準X86_64位工作站上運行的情況,以展示其為您所帶來的生產力的提升;以及該開發環境對OpenCL,C,C ++等等支持情況。該工作站包含一個 Alpha Data的ADM-PCIE-7V3加速卡。
    的頭像 發表于 11-27 06:45 ?2278次閱讀

    友善之臂T4成為計算性能與X86_64不分伯仲的ARM

    一直以來,小伙伴們都有這樣的觀念,X86_64處理器的強項是每個核心的多線程能力;ARM Cortex A系列內核處理器的強項是堆核心,一般是依靠多核而不是單核多線程。
    發表于 04-19 15:33 ?4079次閱讀

    Go運行時:4年之后

    自 2018 年以來,Go GC,以及更廣泛的 Go 運行時,一直在穩步改進。近日,Go 社區總結了 4 年來 Go 運行時的一些重要變化。
    的頭像 發表于 11-30 16:21 ?860次閱讀

    ch32v307記錄程序運行時

    ch32v307記錄程序運行時間 在程序開發中,很重要的一項任務就是對程序的運行時間進行評估。對于大型的程序系統來說,它們通常需要處理大量的數據或進行復雜的計算操作。因此,如果程序的運行時間過長
    的頭像 發表于 08-22 15:53 ?940次閱讀

    Xilinx運行時(XRT)發行說明

    電子發燒友網站提供《Xilinx運行時(XRT)發行說明.pdf》資料免費下載
    發表于 09-14 10:01 ?0次下載
    Xilinx<b class='flag-5'>運行時</b>(XRT)發行說明

    如何保證它們容器運行時的安全?

    緊密耦合的容器運行時繼承了主機操作系統的安全態勢和攻擊面。運行時或主機內核中的任何漏洞及其利用都會成為攻擊者的潛在切入點。
    的頭像 發表于 11-03 15:24 ?702次閱讀

    jvm運行時內存區域劃分

    JVM是Java Virtual Machine(Java虛擬機)的縮寫,它是Java編程語言的運行環境。JVM的主要功能是將Java源代碼轉換為機器代碼,并且在運行時管理Java程序的內存。JVM
    的頭像 發表于 12-05 14:08 ?556次閱讀
    主站蜘蛛池模板: 医生含着我的奶边摸边做| 亚洲 欧美 中文 日韩 另类| 天堂无码人妻精品AV一区| yellow免费| 同桌上课把奶露出来给我玩| 爆乳啪啪无码成人二区亚洲欧美| 美国特级成人毛片| 97免费在线视频| 欧美精品乱码99久久蜜桃| 中文字幕日本在线mv视频精品| 久久免费看少妇高潮A片JA| 一本道久在线综合道| 娇小亚裔被两个黑人| 亚洲妈妈精品一区二区三区| 黄色三级三级三级免费看| 一二三四在线视频社区8| 久热人人综合人人九九精品视频| 2019久久视频这里有精品15| 成年人国产视频| 日韩欧美视频一区二区| 国产h视频在线观看网站免费| 久久亚洲国产精品亚洲| 中国jjzz| 免费人妻AV无码专区五月| www.青青草.com| 十分钟免费视频大全在线观看| 国产精品福利片| 久久99精品国产麻豆婷婷| 阿离被扒开双腿疯狂输出| 99视频在线观看免费| 中文人妻熟妇精品乱又伧| 亚洲视频在线观看| 亚洲国产高清视频在线观看| 我的好妈妈8高清在线观看WWW| 肉欲横流(NP高H)| 久久国产精品永久网站| 国产一区二区内射最近更新| 国产精品欧美亚洲| 国产精品嫩草影院| 国产欧美日韩精品a在线观看高清| 国产99久久九九精品无码不卡|