[英]Ptrace - communication with child process
我想以下列方式使用ptrace
(偽代碼):
孩子:
foo();
now that foo is done parent should use ptrace to change things
parent did what he wanted to do
bar();
家長:
pid = fork();
if (pid == 0)
//child
exec(child_program)
else
//parent
attach ptrace
let child run
use ptrace to modify it's data
let child continue
孩子應該如何與父母溝通它已完成foo
並准備好進行修改? raise(SIGSTOP)
也許?
父母應該如何等待孩子運行foo
?
我認為我們可以假設在使用pthread
之前沒有引發 SIGSTOP。
編輯:
您可以使用信號量讓父sem_overview
等待子sem_overview
(請參閱 Linux 手冊頁中的sem_overview
)並執行您需要執行的操作。 您可以使用sem_open
創建一個命名信號量,並讓子sem_open
在父sem_open
等待它,讓子sem_open
在完成上述任務后通知信號量。
或者,讓被跟蹤的子進程使用斷點指令,該指令將通過SIGTRAP
停止它,允許您wait
它,然后執行您需要執行的操作。 我相信 GDB 使用類似的方法進行調試(修補指令)。 如果您使用的是 x86,以下代碼應該適用於在您的代碼中發出斷點指令:
asm volatile ("int3;")
我還可以建議使用process_vm_writev
而不是ptrace
函數來寫入進程內存( PTRACE_POKETEXT
),因為它們可以對進程內存進行批量讀取/寫入。
為了進一步參考,我認為debuggers_part2_code是一個很好的例子,說明如何推出自己的調試工具。
你說你想在執行的某個時刻修改他跟蹤進程的寄存器。 您可能應該嘗試澄清您的問題,因為它並不清楚您真正想要實現的目標:首先為什么要修改寄存器。 您希望在寄存器中找到什么? 為什么要更改這些值?
您確定不想與套接字和/或共享內存通信嗎? 您可能應該提供一個更詳細的示例來解釋您要做什么。
您在跟蹤的過程中有此代碼:
foo();
// You want to modify something there.
bar();
在foo()
和bar()
,真的不清楚寄存器中的內容。 假設我們使用的是 x86_64。
如果在foo
返回時中斷:
EAX 包含foo
的返回值(如果有),無論如何它在調用者中被忽略(因此修改它沒有多大意義);
被調用者保存的寄存器可能包含來自調用者的一些值,但您必須弄亂 DWARF 信息以試圖從中獲得一些意義;
調用者保存的寄存器將不包含任何有用的內容(但您可以使用 DWARF 展開信息來查找其他一些在調用者中有意義的數據)。
在bar
的調用位置(在調用者中或在bar
的開頭)中斷對您來說可能更有趣,因為您可以訪問bar
的參數。 您可以在跟蹤器進程中修改它們,如果需要,您甚至可以強制使用一個值進行返回調用。
另一種解決方案是發出信號:
foo();
raise(SIGTRAP);
bar();
和以前一樣,不清楚寄存器中的內容,您可能必須使用 DWARF 來嘗試定位感興趣的數據(可能有效也可能無效)。
一個(可能)更干凈的解決方案是通過指令引發異常:
int $3
問題是如果你的程序沒有在跟蹤器下運行,它就會死掉。
一個更簡潔的解決方案是在foo
和bar
之間添加另一個函數:
foo();
int res = delegate_to_tracer(x, y, z);
bar();
其中delegate_to_tracer
可以存根為:
int delegate_to_tracer(int x, int y, int z)
{
// No-op implementation used when there is no tracer:
return 0;
}
您現在可以在此函數的開頭添加一個斷點,以便在跟蹤器中處理它的功能:
您可以訪問參數;
你可以修改它們;
您可以使用給定的返回值強制返回。
另一個類似的解決方案是使用靜態跟蹤點( SDT , UST ),但嘗試修改它們的數據可能沒有多大意義。
您可以使用系統調用來與跟蹤器通信:
要么使用未使用的系統調用( NR_tuxcall
?)
要么使用一個未使用的系統調用號(但它可能會在某個時候被使用);
或者通過蹲一個現有的。
這個想法是,如果它不在您的跟蹤器下運行,系統調用將因SIGSYS
(或其他)而失敗。 但是,在您的跟蹤器下,您將攔截系統調用並自行處理。
進行 tuxcall:
movq $184, %rax # tuxcall
movq $42, %edi # param1
syscall
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.