ถ่ายโอนหน่วยความจำของกระบวนการ linux ไปยังไฟล์


52

เป็นไปได้ที่จะถ่ายโอนข้อมูลหน่วยความจำปัจจุบันที่จัดสรรสำหรับกระบวนการ (โดย PID) ไปยังไฟล์หรือไม่? หรืออ่านมันอย่างใด?



1
คุณอาจต้องการอ่านsuperuser.com/questions/236390/…และใช้ gcore แทน
Simon A. Eugster

คำตอบ:


46

ฉันไม่แน่ใจว่าคุณถ่ายโอนข้อมูลหน่วยความจำทั้งหมดไปยังไฟล์โดยไม่ทำเช่นนี้ซ้ำ ๆ ได้อย่างไร (ถ้าใครรู้วิธีอัตโนมัติเพื่อให้ gdb ทำสิ่งนี้โปรดแจ้งให้เราทราบ) แต่การทำงานต่อไปนี้สำหรับหน่วยความจำชุดใดชุดหนึ่ง pid:

$ cat /proc/[pid]/maps

สิ่งนี้จะอยู่ในรูปแบบ (ตัวอย่าง):

00400000-00421000 r-xp 00000000 08:01 592398                             /usr/libexec/dovecot/pop3-login
00621000-00622000 rw-p 00021000 08:01 592398                             /usr/libexec/dovecot/pop3-login
00622000-0066a000 rw-p 00622000 00:00 0                                  [heap]
3e73200000-3e7321c000 r-xp 00000000 08:01 229378                         /lib64/ld-2.5.so
3e7341b000-3e7341c000 r--p 0001b000 08:01 229378                         /lib64/ld-2.5.so

เลือกหน่วยความจำหนึ่งชุด (เช่น 00621000-00622000) จากนั้นใช้ gdb เป็นรูทเพื่อแนบกับกระบวนการและดัมพ์หน่วยความจำนั้น:

$ gdb --pid [pid]
(gdb) dump memory /root/output 0x00621000 0x00622000

จากนั้นวิเคราะห์ / รูท / เอาท์พุทด้วยคำสั่ง strings ยิ่งคุณต้องการ PuTTY ให้ทั่วหน้าจอของคุณน้อยลง


1
มีวิธีการทำเช่นนี้เพียงแค่ bash / sh โดยไม่ต้อง gdb?
Programming4life

3
@ Programming4life gcore (1)
julian

51

ฉันได้สร้างสคริปต์ที่ทำให้งานนี้สำเร็จ

ความคิดนี้มาจากคำตอบของ James Lawrie และโพสต์นี้: http://www.linuxforums.org/forum/programming-scripting/52375-reading-memory-other-processes.html ที่ http://www.linuxforums.org/forum/programming-scripting

#!/bin/bash

grep rw-p /proc/$1/maps \
| sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p' \
| while read start stop; do \
    gdb --batch --pid $1 -ex \
        "dump memory $1-$start-$stop.dump 0x$start 0x$stop"; \
done

ใส่สิ่งนี้ลงในไฟล์ (เช่น "dump-all-memory-of-pid.sh") และทำให้มันปฏิบัติการได้

การใช้งาน: ./dump-all-memory-of-pid.sh [pid]

เอาต์พุตถูกพิมพ์ไปยังไฟล์ที่มีชื่อ: pid-startaddress-stopaddress.dump

อ้างอิง: gdb


2
น่ากลัว! เพิ่งใช้มันเพื่อค้นหาว่าสคริปต์ใดที่อินสแตนซ์ทุบตีลึกลับกำลังทำงานอยู่
เบีย

เหตุใดคุณจึง grepping และช่วงการถ่ายโอนข้อมูลที่มีrw-pสิทธิ์เท่านั้น
mxmlnkn

@mxmlnkn นั่นคือ data ( rw-p) ช่วงอื่น ๆ สำหรับ code ( r-xp) ถ้าคุณต้องการถ่ายโอนข้อมูลของทั้งสองแล้วไปข้างหน้าและการแลกเปลี่ยนสำหรับเช่นgrep cat
A. Nilsson

39

ลอง

    gcore $pid

โดยที่$pidเป็นจำนวนจริงของ pid; สำหรับข้อมูลเพิ่มเติมดู:info gcore

อาจใช้เวลาสักครู่เพื่อให้การถ่ายโอนข้อมูลเกิดขึ้นและหน่วยความจำบางอย่างอาจไม่สามารถอ่านได้ แต่ดีพอ ... โปรดทราบด้วยว่ามันสามารถสร้างไฟล์ขนาดใหญ่ได้ฉันเพิ่งสร้างไฟล์ขนาด 2GB ขึ้นมา ..


1
ถูกgcoreทิ้งไฟล์เบาบาง?
CMCDragonkai

3

man proc พูดว่า:

/ proc / [pid] / mem ไฟล์นี้สามารถใช้เพื่อเข้าถึงหน้าของหน่วยความจำของกระบวนการผ่าน open (2), read (2), และ lseek (2)

อาจช่วยคุณได้


1
ไม่เพียงพอการอ่านกระบวนการอื่นต้องการการรวมกันของ / proc / <pid> / {mem, * maps}, ptrace และการจัดการสัญญาณบางอย่างเพื่อหลีกเลี่ยงการแขวนกระบวนการเป้าหมาย
Tobu

@Tobu แท้จริง ผมเขียนสคริปต์หลักฐานของแนวคิด
Gilles 'หยุดความชั่วร้าย'

3

ฉันสร้างโปรแกรมของตัวเองเพื่อถ่ายโอนข้อมูลหน่วยความจำในกระบวนการทั้งหมดเช่นกันมันอยู่ใน C เพื่อให้สามารถคอมไพล์ข้ามไปยัง Android ซึ่งเป็นสิ่งที่ฉันต้องการ

คุณสามารถระบุที่อยู่ IP และพอร์ต tcp ได้ รหัสที่มาที่นี่


2

วิธีทุบตีบริสุทธิ์:

procdump () 
{ 
    cat /proc/$1/maps | grep "rw-p" | awk '{print $1}' | ( IFS="-"
    while read a b; do
        count=$(( bd-ad ))
        ad=$(printf "%llu" "0x$a")
        bd=$(printf "%llu" "0x$b")
        dd if=/proc/$1/mem bs=1 skip=$ad count=$count of=$1_mem_$a.bin
    done )
}

การใช้งาน: procdump PID

สำหรับดัมพ์ที่สะอาดกว่า:

procdump () 
{ 
    cat /proc/$1/maps | grep -Fv ".so" | grep " 0 " | awk '{print $1}' | ( IFS="-"
    while read a b; do
        ad=$(printf "%llu" "0x$a")
        bd=$(printf "%llu" "0x$b")
        dd if=/proc/$1/mem bs=1 skip=$ad count=$(( bd-ad )) of=$1_mem_$a.bin
    done )
}

ดังนั้นจากสิ่งที่ฉันเข้าใจความคิดเบื้องหลังการถ่ายโอนข้อมูลตัวล้างข้อมูลคือไฟล์ในหน่วยความจำเท่านั้นที่มีขนาดที่แนบมากับพื้นที่หน่วยความจำในทางตรงกันข้ามกับหน่วยความจำแอปพลิเคชันจริงซึ่งมีขนาด 0 (เนื่องจากขนาดที่ใช้จริง OS)
mxmlnkn

สิ่งหนึ่งที่ฉันมีกับสคริปต์นี้คือขนาดของ 1 บล็อกนำไปสู่แบนด์วิดท์ที่ช้าเกิน ~ 30kB / s เมื่อเทียบกับการใช้บล็อกเท่ากับขนาดหน้า (4096 สำหรับฉัน) ที่ฉันได้รับ ~ 100MB / s! ดูที่นี่ getconf PAGESIZEจะใช้ในการรับขนาดหน้าจากนั้นที่อยู่และจำนวนจะถูกหารด้วย
mxmlnkn

1

เครื่องมือในการดัมพ์กระบวนการไปยังเอาต์พุตมาตรฐาน pcat / memdump:


อันนี้ล้าสมัย (ลบออกตามคำขอของผู้ดูแล); ฉันติดตั้งแพคเกจเก่าแล้วและมันล้มเหลวด้วย "ข้อผิดพลาดอินพุต / เอาต์พุตคุณใช้ GCC กับไฟล์ส่วนหัวของเครื่องอื่นหรือไม่"
Tobu


0

ถ้าคุณต้องการที่จะถ่ายโอนข้อมูลหน่วยความจำส่วนที่แยกต่างหากจากกระบวนการทำงานโดยไม่ต้องสร้างไฟล์หลักขนาดใหญ่ (พูดด้วย gcore) คุณสามารถใช้เครื่องมือขนาดเล็กจากที่นี่ นอกจากนี้ยังมีหนึ่งบรรทัดใน README หากคุณต้องการถ่ายโอนเซ็กเมนต์ที่อ่านได้ทั้งหมดเป็นไฟล์แยกต่างหาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.