haypo / python-ptrace
python-ptrace is a debugger using ptrace (Linux, BSD and Darwin system call to trace processes) written in Python. python-ptrace is an opensource project (contribute!) written in Python under GNU GPLv2 license.
Clone this repository (size: 221.4 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/haypo/python-ptrace/
| commit 100: | 8eb4b12d1fd9 |
| parent 99: | 553f2655e3dc |
| branch: | default |
MemoryMapping.search():
* reuse process.readBytes() which is fast and portable
* convert function to a generator
Changed (Δ125 bytes):
raw changeset »
ptrace/debugger/memory_mapping.py (13 lines added, 19 lines removed)
Up to file-list ptrace/debugger/memory_mapping.py:
| … | … | @@ -4,6 +4,7 @@ if HAS_PROC: |
4 |
4 |
from ptrace.debugger.process_error import ProcessError |
5 |
5 |
from ptrace.ctypes_tools import formatAddress |
6 |
6 |
import re |
7 |
from weakref import ref |
|
7 |
8 |
|
8 |
9 |
PROC_MAP_REGEX = re.compile( |
9 |
10 |
# Address range: '08048000-080b0000 ' |
| … | … | @@ -31,7 +32,7 @@ class MemoryMapping: |
31 |
32 |
- major_device / minor_device (int): major / minor device number |
32 |
33 |
- inode (int) |
33 |
34 |
- pathname (str) |
34 |
- |
|
35 |
- _process: weak reference to the process |
|
35 |
36 |
|
36 |
37 |
Operations: |
37 |
38 |
- "address in mapping" checks the address is in the mapping. |
| … | … | @@ -40,7 +41,8 @@ class MemoryMapping: |
40 |
41 |
- "repr(mapping)" create a string representation of the mapping, |
41 |
42 |
useful in list contexts |
42 |
43 |
""" |
43 |
def __init__(self, |
|
44 |
def __init__(self, process, start, end, permissions, offset, major_device, minor_device, inode, pathname): |
|
45 |
self._process = ref(process) |
|
44 |
46 |
self.start = start |
45 |
47 |
self.end = end |
46 |
48 |
self.permissions = permissions |
| … | … | @@ -49,7 +51,6 @@ class MemoryMapping: |
49 |
51 |
self.minor_device = minor_device |
50 |
52 |
self.inode = inode |
51 |
53 |
self.pathname = pathname |
52 |
self.pid = pid |
|
53 |
54 |
|
54 |
55 |
def __contains__(self, address): |
55 |
56 |
return self.start <= address < self.end |
| … | … | @@ -60,28 +61,20 @@ class MemoryMapping: |
60 |
61 |
text += " => %s" % self.pathname |
61 |
62 |
text += " (%s)" % self.permissions |
62 |
63 |
return text |
63 |
||
64 |
__repr__ = __str__ |
|
65 |
||
64 |
66 |
def search(self, bytestr): |
65 |
|
|
67 |
process = self._process() |
|
66 |
68 |
bytestr_len = len(bytestr) |
67 |
proc_mem = open("/proc/%i/mem" % self.pid, "r") |
|
68 |
proc_mem.seek(self.start) |
|
69 |
69 |
covered = self.start |
70 |
data = proc |
|
70 |
data = process.readBytes(self.start, self.end - self.start) |
|
71 |
71 |
while (data != ""): |
72 |
72 |
offset = data.find(bytestr) |
73 |
73 |
if (offset == -1): |
74 |
74 |
break |
75 |
else: |
|
76 |
retlist.append(offset + covered) |
|
77 |
covered += offset + bytestr_len |
|
78 |
proc_mem.seek(covered) |
|
79 |
data = proc_mem.read(self.end - covered) |
|
80 |
proc_mem.close() |
|
81 |
return retlist |
|
82 |
||
83 |
def __repr__(self): |
|
84 |
return self.__str__() |
|
75 |
yield (offset + covered) |
|
76 |
covered += offset + bytestr_len |
|
77 |
data = process.readBytes(covered, self.end - covered) |
|
85 |
78 |
|
86 |
79 |
def readProcessMappings(process): |
87 |
80 |
""" |
| … | … | @@ -106,6 +99,7 @@ def readProcessMappings(process): |
106 |
99 |
if not match: |
107 |
100 |
raise ProcessError(process, "Unable to parse memoy mapping: %r" % line) |
108 |
101 |
map = MemoryMapping( |
102 |
process, |
|
109 |
103 |
int(match.group(1), 16), |
110 |
104 |
int(match.group(2), 16), |
111 |
105 |
match.group(3), |
| … | … | @@ -113,7 +107,7 @@ def readProcessMappings(process): |
113 |
107 |
int(match.group(5), 16), |
114 |
108 |
int(match.group(6), 16), |
115 |
109 |
int(match.group(7)), |
116 |
match.group(8) |
|
110 |
match.group(8)) |
|
117 |
111 |
maps.append(map) |
118 |
112 |
finally: |
119 |
113 |
mapsfile.close() |
