linux下注入so之ptrace

2021-06-09 04:01:42 字數 4231 閱讀 2175

注入so,也就是讓另乙個正在執行的程序載入我們指定的so,之後我們的so裡面的**就可以自動執行,這個主要是用來進行api攔截的。windows下的api攔截非常方便,而linux下的就比較複雜。

如果去網上搜,基本上找到的是這個是2023年的,它的思路是使用ptrace,attach目標程序,然後搜尋目標程序符號表,找到_dl_open的位址,儲存暫存器,然後修改暫存器,設定_dl_open函式的引數,執行_dl_open函式。還有一種思路是在目標程序申請一塊自由空間,當然這個也是要搜尋符號表找到malloc等的位址,然後在申請到的空間寫入shellcode。主意這裡不要隨意的將shellcode寫入bss段等。關於shellcode的編寫這個就涉及到彙編了。

可是隨著linux核心版本的改變,一些函式或者實現機制變了,上文中提到的搜尋_dl_open已經行不通了。我這幾天找到了乙個老外寫的c庫,叫hotpatch。位址

關於ptrace 形式

#include

int ptrace(int request, int pid, int addr, int data); 描述

ptrace 提供了一種父程序可以控制子程序執行,並可以檢查和改變它的核心image。它主要用於實現斷點除錯。乙個被跟蹤的程序執行中,直到發生乙個訊號。則程序被中止,並且通知其父程序。在程序中止的狀態下,程序的記憶體空間可以被讀寫。父程序還可以使子程序繼續執行,並選擇是否是否忽略引起中止的訊號。

request引數決定了系統呼叫的功能:

ptrace_traceme

本程序被其父程序所跟蹤。其父程序應該希望跟蹤子程序。

ptrace_peektext, ptrace_peekdata

從記憶體位址中讀取乙個位元組,記憶體位址由addr給出。

ptrace_peekusr

從user區域中讀取乙個位元組,偏移量為addr。

ptrace_poketext, ptrace_pokedata

往記憶體位址中寫入乙個位元組。記憶體位址由addr給出。

ptrace_pokeusr

往user區域中寫入乙個位元組。偏移量為addr。

ptrace_syscall, ptrace_cont

重新執行。

ptrace_kill

殺掉子程序,使它退出。

ptrace_singlestep

設定單步執行標誌

ptrace_attach

跟蹤指定pid 程序。

ptrace_detach

結束跟蹤

intel386特有:

ptrace_getregs

讀取暫存器

ptrace_setregs

設定暫存器

ptrace_getfpregs

讀取浮點暫存器

ptrace_setfpregs

設定浮點暫存器

init程序不可以使用此函式

返回值

成功返回0。錯誤返回-1。errno被設定。

錯誤

eperm

特殊程序不可以被跟蹤或程序已經被跟蹤。

esrch

指定的程序不存在

eio請求非法

ptrace系統函式。 ptrace提供了一種使父程序得以監視和控制其它程序的方式,它還能夠改變子程序中的暫存器和核心映像,因而可以實現斷點除錯和系統呼叫的跟蹤。使用ptrace,你可以在使用者層攔截和修改系統呼叫(sys call).

形式:ptrace(ptrace_traceme,0 ,0 ,0)

描述:本程序被其父程序所跟蹤。其父程序應該希望跟蹤子程序。

形式:ptrace(ptrace_peektext, pid, addr, data)

ptrace(ptrace_peekdata, pid, addr, data)

描述:從記憶體位址中讀取乙個位元組,pid表示被跟蹤的子程序,記憶體位址由addr給出,data為使用者變數位址用於返回讀到的資料。在linux(i386)中使用者**段與使用者資料段重合所以讀取**段和資料段資料處理是一樣的。

形式:ptrace(ptrace_poketext, pid, addr, data)

ptrace(ptrace_pokedata, pid, addr, data)

描述:往記憶體位址中寫入乙個位元組。pid表示被跟蹤的子程序,記憶體位址由addr給出,data為所要寫入的資料。

形式:ptrace(ptrace_peekusr, pid, addr, data)

描述:從user區域中讀取乙個位元組,pid表示被跟蹤的子程序,user區域位址由addr給出,data為使用者變數位址用於返回讀到的資料。user結構為core檔案的前面一部分,它描述了程序中止時的一些狀態,如:暫存器值,**、資料段大小,**、資料段開始位址等。在linux(i386)中通過ptrace_peekuser和ptrace_pokeusr可以訪問user結構的資料有暫存器和除錯暫存器。

形式:ptrace(ptrace_pokeusr, pid, addr, data)

描述:往user區域中寫入乙個位元組,pid表示被跟蹤的子程序,user區域位址由addr給出,data為需寫入的資料。

形式:ptrace(ptrace_cont, pid, 0, signal)

描述:繼續執行。pid表示被跟蹤的子程序,signal為0則忽略引起除錯程序中止的訊號,若不為0則繼續處理訊號signal。

形式:ptrace(ptrace_sys, pid, 0, signal)

描述:繼續執行。pid表示被跟蹤的子程序,signal為0則忽略引起除錯程序中止的訊號,若不為0則繼續處理訊號signal。與ptrace_cont不同的是進行系統呼叫跟蹤。在被跟蹤程序繼續執行直到呼叫系統呼叫開始或結束時,被跟蹤程序被中止,並通知父程序。

形式:ptrace(ptrace_kill,pid)

描述:殺掉子程序,使它退出。pid表示被跟蹤的子程序。

形式:ptrace(ptrace_kill, pid, 0, signle)

描述:設定單步執行標誌,單步執行一條指令。pid表示被跟蹤的子程序。signal為0則忽略引起除錯程序中止的訊號,若不為0則繼續處理訊號signal。當被跟蹤程序單步執行完乙個指令後,被跟蹤程序被中止,並通知父程序。

形式:ptrace(ptrace_attach,pid)

描述:跟蹤指定pid 程序。pid表示被跟蹤程序。被跟蹤程序將成為當前程序的子程序,並進入中止狀態。

形式:ptrace(ptrace_detach,pid)

描述:結束跟蹤。 pid表示被跟蹤的子程序。結束跟蹤後被跟蹤程序將繼續執行。

形式:ptrace(ptrace_getregs, pid, 0, data)

描述:讀取暫存器值,pid表示被跟蹤的子程序,data為使用者變數位址用於返回讀到的資料。此功能將讀取所有17個基本暫存器的值。

形式:ptrace(ptrace_setregs, pid, 0, data)

描述:設定暫存器值,pid表示被跟蹤的子程序,data為使用者資料位址。此功能將設定所有17個基本暫存器的值。

形式:ptrace(ptrace_getfpregs, pid, 0, data)

描述:讀取浮點暫存器值,pid表示被跟蹤的子程序,data為使用者變數位址用於返回讀到的資料。此功能將讀取所有浮點協處理器387的所有暫存器的值。

形式:ptrace(ptrace_setregs, pid, 0, data)

描述:設定浮點暫存器值,pid表示被跟蹤的子程序,data為使用者資料位址。此功能將設定所有浮點協處理器387的所有暫存器的值。

呼叫webservice服務介面下注入屬性的問題

開發類似webservice介面時,尤其是調取服務端暴露介面時,由於服務端其他內部介面是不受spring託管的,往往通過ioc或註解的方式不能注入,那麼可以通過手動bean注入的方式。webservice public inte ce autoreqservicewebservice暴露介面 web...

多實現類下注入指定的物件

當使用 autowired的時候,如果注入的物件是乙個介面的有多個實現,會報錯,找不到對應的bean 因為它沒法區分是哪個。報錯因為mqconsumer有多個實現 原因是 autowired 的注入方式是 bytype 注入,當要注入的型別在容器中存在多個時,spring是不知道要引入哪個實現類的 ...

Linux下註冊Apache與MySQL為系統服務

linux下註冊apache與mysql為系統服務 apache加入到系統服務裡面 cp 安裝目錄下 apache bin apachectl etc rc.d init.d httpd 修改httpd 在檔案頭部加入如下內容 儲存 在打入 chkconfig add httpd mysql加入到系...