/proc/$pid/maps
/proc/$pid/mem$ pid හි මතකයේ අන්තර්ගතය ක්රියාවලියේදී මෙන් සිතියම් ගත කර ඇති බව පෙන්වයි, එනම්, ව්යාජ ගොනුවේ ඕෆ්සෙට් x හි බයිට් ක්රියාවලියෙහි x ලිපිනයෙහි ඇති බයිටයට සමාන වේ. ක්රියාවලිය තුළ ලිපිනයක් සිතියම් ගත නොකළේ නම්, ගොනුවේ අනුරූප ඕෆ්සෙට් එකෙන් කියවීම EIO(ආදාන / ප්රතිදාන දෝෂය). නිදසුනක් ලෙස, ක්රියාවලියක පළමු පිටුව කිසි විටෙකත් සිතියම් ගත නොකිරීම නිසා (එමඟින් NULLදර්ශකය අවලංගු කිරීම අනපේක්ෂිත ලෙස සත්ය මතකයට ප්රවේශ වීමට වඩා පිරිසිදු ලෙස අසමත් වේ), පළමු බයිටය කියවීමෙන් /proc/$pid/memසෑම විටම I / O දෝෂයක් ඇතිවේ.
ක්රියාවලි මතකයේ සිතියම් ගත කර ඇති කොටස් මොනවාදැයි සොයා ගැනීමට මාර්ගය කියවීමයි /proc/$pid/maps. මෙම ගොනුවේ සිතියම් ගත කළ කලාපයකට එක් පේළියක් ඇත, මේ ආකාරයට:
08048000-08054000 r-xp 00000000 08:01 828061 /bin/cat
08c9b000-08cbc000 rw-p 00000000 00:00 0 [heap]
පළමු අංක දෙක කලාපයේ මායිම් වේ (පළමු බයිටයේ ලිපිනයන් සහ අන්තිමට පසු බයිට්, හෙක්සා වලින්). ඊළඟ තීරුවේ අවසරයන් අඩංගු වේ, පසුව මෙය ගොනු සිතියම්ගත කිරීමක් නම් ගොනුව පිළිබඳ තොරතුරු (ඕෆ්සෙට්, උපාංගය, ඉනෝඩ් සහ නම) ඇත. වැඩි විස්තර සඳහා proc(5)man පිටුව හෝ අවබෝධය ලිනක්ස් / proc / id / සිතියම් බලන්න.
මෙන්න එහි මතකයේ අන්තර්ගතය ඉවත ලන සංකල්ප-සනාථ කිරීමේ පිටපතක්.
#! /usr/bin/env python
import re
maps_file = open("/proc/self/maps", 'r')
mem_file = open("/proc/self/mem", 'r', 0)
for line in maps_file.readlines(): # for each mapped region
m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', line)
if m.group(3) == 'r': # if this is a readable region
start = int(m.group(1), 16)
end = int(m.group(2), 16)
mem_file.seek(start) # seek to region start
chunk = mem_file.read(end - start) # read region contents
print chunk, # dump contents to standard output
maps_file.close()
mem_file.close()
/proc/$pid/mem
ඔබ memවෙනත් ක්රියාවලියක ව්යාජ ගොනුවෙන් කියවීමට උත්සාහ කරන්නේ නම් , එය ක්රියා නොකරයි: ඔබට ESRCH(එවැනි ක්රියාවලියක් නොමැත) දෝෂයක් ලැබේ.
/proc/$pid/mem( r--------) මත ඇති අවසරය කුමක් විය යුතුද යන්නට වඩා ලිබරල් ය. නිදසුනක් ලෙස, ඔබට සැකසුම් ක්රියාවලියක මතකය කියවීමට නොහැකි විය යුතුය. තවද, ක්රියාවලිය වෙනස් කරන අතරතුර ක්රියාවලියක මතකය කියවීමට උත්සාහ කිරීම පා the කයාට මතකය පිළිබඳ නොගැලපෙන දෘෂ්ටියක් ලබා දිය හැකි අතර වඩාත් නරක අතට, ලිනක්ස් කර්නලයේ පැරණි අනුවාදයන් සොයාගත හැකි ධාවන තත්වයන් තිබුණි ( මෙම lkml නූලට අනුව , මම වුවද විස්තර දන්නේ නැහැ). එබැවින් අමතර චෙක්පත් අවශ්ය වේ:
- කියවීමට අවශ්ය
/proc/$pid/memක්රියාවලිය ධජය ptraceසමඟ භාවිතා කරන ක්රියාවලියට අනුයුක්ත කළ යුතුය PTRACE_ATTACH. ක්රියාවලියක් නිදොස්කරණය කිරීම ආරම්භ කරන විට නිදොස් කරන්නන් කරන්නේ මෙයයි; එය straceක්රියාවලියක පද්ධති ඇමතුම් සඳහා කරන දේ ද වේ. පා /proc/$pid/memread කයා කියවීම අවසන් කළ පසු , එය ධජය ptraceසමඟ ඇමතීමෙන් වෙන් විය යුතුය PTRACE_DETACH.
- නිරීක්ෂණය කළ ක්රියාවලිය ක්රියාත්මක නොවිය යුතුය. සාමාන්යයෙන් ඇමතීමෙන්
ptrace(PTRACE_ATTACH, …)ඉලක්ක ක්රියාවලිය නවත්වනු ඇත (එය සං STOPsignal ාවක් යවයි ), නමුත් ධාවන තත්වයක් ඇත (සං signal ා භාරදීම අසමමුහුර්ත වේ), එබැවින් ට්රේසරය ඇමතිය යුතුය wait(ලේඛනගත කර ඇති පරිදි ptrace(2)).
මූලයක් ලෙස ක්රියාත්මක වන ක්රියාවලියකට ඕනෑම ක්රියාවලියක මතකය ඇමතීමට අවශ්ය නොවී කියවිය හැකිය ptrace, නමුත් නිරීක්ෂණය කළ ක්රියාවලිය නැවැත්විය යුතුය, නැතහොත් කියවීම තවමත් නැවත පැමිණේ ESRCH.
Linux කර්නලය ප්රභවය දී, දී එක්-ක්රියාවලිය ඇතුළත් කිරීම් ලබා කේතය /procවන්නේ fs/proc/base.c, සහ කියවීමට මෙම උත්සවයට /proc/$pid/memකියන්නේ mem_read. අතිරේක චෙක්පත සිදු කරනු ලබන්නේ check_mem_permission.
ක්රියාවලියකට ඇමිණීමට සහ එහි memගොනුව කියවීමට සාම්පල සී කේත කිහිපයක් මෙන්න (දෝෂ පරීක්ෂා කිරීම මඟ හැරී ඇත):
sprintf(mem_file_name, "/proc/%d/mem", pid);
mem_fd = open(mem_file_name, O_RDONLY);
ptrace(PTRACE_ATTACH, pid, NULL, NULL);
waitpid(pid, NULL, 0);
lseek(mem_fd, offset, SEEK_SET);
read(mem_fd, buf, _SC_PAGE_SIZE);
ptrace(PTRACE_DETACH, pid, NULL, NULL);
මම දැනටමත් /proc/$pid/memවෙනත් ත්රෙඩ් එකකට දැමීම සඳහා සංකල්ප සනාථ කිරීමේ පිටපතක් පළ කර ඇත්තෙමි .