2009-06-05 41 views
7

我正在尋找一種有效的方法來訪問(對於讀取和寫入操作)我的ptraced子進程的內存空間。被訪問塊的大小可能會從幾個字節到幾兆字節大小不等,因此使用和PTRACE_POKEDATA的ptrace調用,每次只讀取一個字,並在每次調用它時切換上下文似乎是毫無意義的浪費資源。然而,我能找到的唯一一種替代解決方案是/proc/<pid>/mem文件,但它早已成爲只讀文件。低開銷的方式來訪問被跟蹤進程的內存空間?

是否有任何其他(相對簡單)的方式來完成這項工作?理想的解決方案是以某種方式共享我的子進程的地址空間和它的父進程,然後使用簡單的memcpy調用來雙向複製我需要的數據,但是我沒有線索如何做以及從哪裏開始。

任何想法?

+0

您想查看任何內存信息或想要分享的特定數據段?我的意思是,你想要訪問整個內存空間? – LB40 2009-06-06 02:00:32

+0

我想訪問每次啓動程序時其位置,長度和數量都不相同的特定數據段。但爲此,我認爲訪問被跟蹤進程的整個內存空間是讀取和修改它們的最自然,最簡單的方式。 – vovick 2009-06-06 07:00:47

回答

1

你是否在控制子進程及其源代碼?如果是這樣,你可以考慮使用Shared memory

4

如果這是Linux(標籤顯示它是),則可以使用clone()CLONE_VM標誌共享子項的全部地址空間。由於這兩個進程共享相同的VM空間,因此所有修改都將在兩者之間立即可見,並且基本上沒有開銷。

這意味着你不能再在exec()在孩子;因爲它將取代這兩個進程的虛擬機空間。

0

如果你在控制子進程,也許你可以添加一個調試接口,允許你寫入有問題的內存?

1

考慮在ptraced進程中注入一些調試函數並通過ptrace_setregs調用它。就像gdb如何運行ptraced進程的任何函數一樣。

你也可以嘗試通過LD_PRELOAD注入一些代碼到進程中。你甚至可以嘗試使用信號在沒有ptrace的情況下工作。

upd1: Gdb注入或「劣等函數調用」相當複雜。見功能call_function_by_hand文件GDB-6.6.50.20070809> GDB> infcall.c這裏:http://sources.debian.net/src/gdb/7.6.2-1/gdb/infcall.c?hl=462#L462

/* All this stuff with a dummy frame may seem unnecessarily complicated 
    (why not just save registers in GDB?). The purpose of pushing a dummy 
    frame which looks just like a real frame is so that if you call a 
    function and then hit a breakpoint (get a signal, etc), "backtrace" 
    will look right. Whether the backtrace needs to actually show the 
    stack at the time the inferior function was called is debatable, but 
    it certainly needs to not display garbage. So if you are contemplating 
    making dummy frames be different from normal frames, consider that. */ 

/* Perform a function call in the inferior. 
    ARGS is a vector of values of arguments (NARGS of them). 
    FUNCTION is a value, the function to be called. 
    Returns a value representing what the function returned. 
    May fail to return, if a breakpoint or signal is hit 
    during the execution of the function. 

    ARGS is modified to contain coerced values. */ 

struct value * 
call_function_by_hand (struct value *function, int nargs, struct value **args) 
{ 
... 
    frame = get_current_frame(); 
    gdbarch = get_frame_arch (frame); 

    if (!gdbarch_push_dummy_call_p (gdbarch)) 
    error (_("This target does not support function calls.")); 

    /* A cleanup for the inferior status. 
    This is only needed while we're preparing the inferior function call. */ 
    inf_status = save_infcall_control_state(); 
    inf_status_cleanup 
    = make_cleanup_restore_infcall_control_state (inf_status); 

    /* Save the caller's registers and other state associated with the 
    inferior itself so that they can be restored once the 
    callee returns. To allow nested calls the registers are (further 
    down) pushed onto a dummy frame stack. Include a cleanup (which 
    is tossed once the regcache has been pushed). */ 
    caller_state = save_infcall_suspend_state(); 
    make_cleanup_restore_infcall_suspend_state (caller_state); 
... 
    sp = push_dummy_code (gdbarch, sp, funaddr, args, nargs, 
        target_values_type, &real_pc, &bp_addr, 
        get_current_regcache()); 
... pass args ... 
    /* Create the dummy stack frame. Pass in the call dummy address as, 
    presumably, the ABI code knows where, in the call dummy, the 
    return address should be pointed. */ 
    sp = gdbarch_push_dummy_call (gdbarch, function, get_current_regcache(), 
       bp_addr, nargs, args, 
       sp, struct_return, struct_addr); 
... 
    /* Everything's ready, push all the info needed to restore the 
    caller (and identify the dummy-frame) onto the dummy-frame 
    stack. */ 
    dummy_frame_push (caller_state, &dummy_id); 
... 
    /* Run the inferior until it stops. */ 

    e = run_inferior_call (tp, real_pc); 
    } 
0

閱讀,最好的辦法是解析/proc/<pid>/maps文件感興趣的內存區域的虛擬地址。

然後,您可以通過打開/proc/<pid>/mem來閱讀這些內容,並在感興趣的區域執行帶有大緩衝區的read()調用。對於編寫,我還沒有找到一個簡單的方法來編寫整個塊,我相信這與鎖過程和子進程的穩定性有關,通過調用ptrace()可以保證這一點,但直接訪問另一個進程'記憶不能。我通常在ptrace(PTRACE_POKEDATA, ...)附近寫一個封裝來鏡像Windows'WriteProcessMemory()

0

克隆或mmap是你在找什麼。 mmap兩個進程之間的臨時文件,並使用該內存空間來回傳遞數據。