• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-159  評論-223  文章-30  trackbacks-0
            描述
               攔截Linux動態(tài)庫API的常規(guī)方法,是基于動態(tài)符號鏈接覆蓋技術(shù)實現(xiàn)的,基本步驟是
                1. 重命名要攔截的目標(biāo)動態(tài)庫。
                2. 創(chuàng)建新的同名動態(tài)庫,定義要攔截的同名API,在API內(nèi)部調(diào)用原動態(tài)庫對應(yīng)的API。這里的同名是指與重命名前動態(tài)庫前的名稱相同。
               顯而易見,如果要攔截多個不同動態(tài)庫中的API,那么必須創(chuàng)建多個對應(yīng)的同名動態(tài)庫,這樣一來不僅繁瑣低效,還必須被優(yōu)先鏈接到客戶二進(jìn)制程序中(根據(jù)動態(tài)庫鏈接原理,對重復(fù)ABI符號的處理是選擇優(yōu)先鏈接的那個動態(tài)庫)。 另外在鉤子函數(shù)的實現(xiàn)中,若某調(diào)用鏈調(diào)用到了原API,則會引起死循環(huán)而崩潰。本方法通過直接修改ELF文件中的動態(tài)庫API入口表項,解決了常規(guī)方法的上述問題。

            特點
               1. 不依賴于動態(tài)庫鏈接順序。
               2. 能攔截多個不同動態(tài)庫中的多個API。
               3. 支持運行時動態(tài)鏈接的攔截。
               4. 鉤子函數(shù)內(nèi)的實現(xiàn)體,若調(diào)用到原API,則不會死循環(huán)。


            實現(xiàn)
               攔截映射表
                  為了支持特點2和3,建立了一個攔截映射表,這個映射表有2級。第1級為ELF文件到它的API鉤子映射表,鍵為ELF文件句柄,值為API鉤子映射表;第2級為API到它的鉤子函數(shù)映射表,鍵為API名稱,值為包含最老原函數(shù)地址和最新鉤子函數(shù)地址的結(jié)構(gòu)體,如下圖
                  當(dāng)最先打開ELF文件成功時,會在第1級映射表中插入記錄;反之當(dāng)最后關(guān)閉同一ELF文件時,就會從中移除對應(yīng)的記錄。當(dāng)?shù)谝淮螔煦^動態(tài)庫API時,就會在第2級映射表插入記錄;反之卸鉤同一API時,就會從中刪除對應(yīng)的記錄。

               計算ELF文件的映像基地址
                  計算映像基地址是為了得到ELF中動態(tài)符號表和重定位鏈接過程表的內(nèi)容,因為這些表的位置都是相對于基地址的偏移量,該算法在打開ELF文件時執(zhí)行,如下圖
                  EXE文件為可執(zhí)行文件,DYN文件為動態(tài)庫。對于可執(zhí)行文件,映射基地址為可執(zhí)行裝載段的虛擬地址;對于動態(tài)庫,可通過任一API的地址減去它的偏移量得到,任一API的地址可通過調(diào)用libdl.so庫API dlsym得到,偏移量通過查詢動態(tài)鏈接符號表得到。

               打開ELF文件
                  為了支持特點2即攔截不同動態(tài)庫的多個API,節(jié)省每次掛鉤API前要打開并讀文件的開銷,獨立提供了打開ELF文件的接口操作,流程如下圖
                  若輸入ELF文件名為空,則表示打開當(dāng)前進(jìn)程的可執(zhí)行文件,此時要從偽文件系統(tǒng)/proc/self/exe讀取文件路徑名,以正確調(diào)用系統(tǒng)調(diào)用open。當(dāng)同一ELF文件被多次打開時,只須遞增結(jié)構(gòu)elf的引用計數(shù)。

               掛鉤API
                  當(dāng)打開ELF文件后,就可掛鉤API了,流程如下圖
                  當(dāng)?shù)谝淮螔煦^時,需要保存原函數(shù)以供后面卸鉤;第二次以后繼續(xù)掛鉤同一API時,更新鉤子函數(shù),但原函數(shù)不變。   
               
               卸鉤API
                  當(dāng)打開ELF文件后,就可卸鉤API了,流程如下圖

               關(guān)閉ELF文件
                  因為提供了打開ELF文件的接口操作,所以得配有關(guān)閉ELF文件的接口操作。當(dāng)不需要掛鉤API的時候,就可以關(guān)閉ELF文件了,流程如下圖


            運行時動態(tài)攔截裝置
               在初始化模塊中打開當(dāng)前可執(zhí)行文件,掛鉤libdl.so庫的API dlopen和dlsym;在轉(zhuǎn)換模塊中,按動態(tài)庫句柄和API名稱在攔截映射表中查找鉤子函數(shù),若找到則返回鉤子函數(shù),否則返回調(diào)用dlsym的結(jié)果;在銷毀模塊中,卸鉤dlopen和dlsym。
            當(dāng)動態(tài)庫被進(jìn)程加載的時候,會調(diào)用初始化模塊;當(dāng)被進(jìn)程卸載或進(jìn)程退出的時候,會調(diào)用銷毀模塊;當(dāng)通過dlsym調(diào)用API時,則會在dlsym的鉤子函數(shù)中調(diào)用轉(zhuǎn)換模塊。通過環(huán)境變量LD_PRELOAD將動態(tài)庫libhookapi.so設(shè)為預(yù)加載庫,這樣就能攔截到所有進(jìn)程對dlopen及dlsym的調(diào)用,進(jìn)而攔截到已掛鉤動態(tài)庫API的調(diào)用。
            posted on 2016-08-25 11:10 春秋十二月 閱讀(2274) 評論(0)  編輯 收藏 引用 所屬分類: System
            69国产成人综合久久精品| 免费无码国产欧美久久18| 久久精品蜜芽亚洲国产AV| 精品综合久久久久久97超人| 久久精品国产精品青草| 久久无码精品一区二区三区| 婷婷久久久亚洲欧洲日产国码AV| 久久国产精品一区二区| 久久综合亚洲色HEZYO社区| 国产婷婷成人久久Av免费高清| 久久久久这里只有精品 | 久久综合亚洲色HEZYO国产 | 久久国产精品一国产精品金尊 | 久久精品中文字幕无码绿巨人| 亚洲精品国产成人99久久| 人人狠狠综合久久亚洲| 国产精品久久影院| 国产精品99久久久久久宅男小说| 久久天堂电影网| 久久ww精品w免费人成| 精品伊人久久久| 久久青青草原精品国产软件| 久久99国产精品久久99| 久久久久久亚洲Av无码精品专口 | 久久久久亚洲av成人无码电影| 国产亚洲色婷婷久久99精品| 2019久久久高清456| 热久久国产欧美一区二区精品 | 国产精品久久久久久一区二区三区| 手机看片久久高清国产日韩| 99久久国产综合精品五月天喷水| 精品国产福利久久久| 久久精品水蜜桃av综合天堂| 久久99九九国产免费看小说| 亚洲午夜无码久久久久小说| 久久天天躁狠狠躁夜夜2020老熟妇| 久久国产精品成人免费| 青青草国产精品久久| 国产69精品久久久久9999| 久久影视综合亚洲| 久久人妻无码中文字幕|