1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 """
32 Process instrumentation.
33
34 @group Instrumentation:
35 Process
36 """
37
38 from __future__ import with_statement
39
40
41
42
43
44
45
46 __revision__ = "$Id: process.py 1299 2013-12-20 09:30:55Z qvasimodo $"
47
48 __all__ = ['Process']
49
50 import win32
51 from textio import HexDump, HexInput
52 from util import Regenerator, PathOperations, MemoryAddresses
53 from module import Module, _ModuleContainer
54 from thread import Thread, _ThreadContainer
55 from window import Window
56 from search import Search, \
57 Pattern, BytePattern, TextPattern, RegExpPattern, HexPattern
58 from disasm import Disassembler
59
60 import re
61 import os
62 import os.path
63 import ctypes
64 import struct
65 import warnings
66 import traceback
67
68
69 System = None
70
71
72
73
74
75
76
77
78
79
80 -class Process (_ThreadContainer, _ModuleContainer):
81 """
82 Interface to a process. Contains threads and modules snapshots.
83
84 @group Properties:
85 get_pid, is_alive, is_debugged, is_wow64, get_arch, get_bits,
86 get_filename, get_exit_code,
87 get_start_time, get_exit_time, get_running_time,
88 get_services, get_dep_policy, get_peb, get_peb_address,
89 get_entry_point, get_main_module, get_image_base, get_image_name,
90 get_command_line, get_environment,
91 get_command_line_block,
92 get_environment_block, get_environment_variables,
93 get_handle, open_handle, close_handle
94
95 @group Instrumentation:
96 kill, wait, suspend, resume, inject_code, inject_dll, clean_exit
97
98 @group Disassembly:
99 disassemble, disassemble_around, disassemble_around_pc,
100 disassemble_string, disassemble_instruction, disassemble_current
101
102 @group Debugging:
103 flush_instruction_cache, debug_break, peek_pointers_in_data
104
105 @group Memory mapping:
106 take_memory_snapshot, generate_memory_snapshot, iter_memory_snapshot,
107 restore_memory_snapshot, get_memory_map, get_mapped_filenames,
108 generate_memory_map, iter_memory_map,
109 is_pointer, is_address_valid, is_address_free, is_address_reserved,
110 is_address_commited, is_address_guard, is_address_readable,
111 is_address_writeable, is_address_copy_on_write, is_address_executable,
112 is_address_executable_and_writeable,
113 is_buffer,
114 is_buffer_readable, is_buffer_writeable, is_buffer_executable,
115 is_buffer_executable_and_writeable, is_buffer_copy_on_write
116
117 @group Memory allocation:
118 malloc, free, mprotect, mquery
119
120 @group Memory read:
121 read, read_char, read_int, read_uint, read_float, read_double,
122 read_dword, read_qword, read_pointer, read_string, read_structure,
123 peek, peek_char, peek_int, peek_uint, peek_float, peek_double,
124 peek_dword, peek_qword, peek_pointer, peek_string
125
126 @group Memory write:
127 write, write_char, write_int, write_uint, write_float, write_double,
128 write_dword, write_qword, write_pointer,
129 poke, poke_char, poke_int, poke_uint, poke_float, poke_double,
130 poke_dword, poke_qword, poke_pointer
131
132 @group Memory search:
133 search, search_bytes, search_hexa, search_text, search_regexp, strings
134
135 @group Processes snapshot:
136 scan, clear, __contains__, __iter__, __len__
137
138 @group Deprecated:
139 get_environment_data, parse_environment_data
140
141 @type dwProcessId: int
142 @ivar dwProcessId: Global process ID. Use L{get_pid} instead.
143
144 @type hProcess: L{ProcessHandle}
145 @ivar hProcess: Handle to the process. Use L{get_handle} instead.
146
147 @type fileName: str
148 @ivar fileName: Filename of the main module. Use L{get_filename} instead.
149 """
150
151 - def __init__(self, dwProcessId, hProcess = None, fileName = None):
168
170 """
171 @rtype: int
172 @return: Process global ID.
173 """
174 return self.dwProcessId
175
177 """
178 @rtype: str
179 @return: Filename of the main module of the process.
180 """
181 if not self.fileName:
182 self.fileName = self.get_image_name()
183 return self.fileName
184
186 """
187 Opens a new handle to the process.
188
189 The new handle is stored in the L{hProcess} property.
190
191 @warn: Normally you should call L{get_handle} instead, since it's much
192 "smarter" and tries to reuse handles and merge access rights.
193
194 @type dwDesiredAccess: int
195 @param dwDesiredAccess: Desired access rights.
196 Defaults to L{win32.PROCESS_ALL_ACCESS}.
197 See: U{http://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx}
198
199 @raise WindowsError: It's not possible to open a handle to the process
200 with the requested access rights. This tipically happens because
201 the target process is a system process and the debugger is not
202 runnning with administrative rights.
203 """
204 hProcess = win32.OpenProcess(dwDesiredAccess, win32.FALSE, self.dwProcessId)
205
206 try:
207 self.close_handle()
208 except Exception, e:
209 warnings.warn(
210 "Failed to close process handle: %s" % traceback.format_exc())
211
212 self.hProcess = hProcess
213
215 """
216 Closes the handle to the process.
217
218 @note: Normally you don't need to call this method. All handles
219 created by I{WinAppDbg} are automatically closed when the garbage
220 collector claims them. So unless you've been tinkering with it,
221 setting L{hProcess} to C{None} should be enough.
222 """
223 try:
224 if hasattr(self.hProcess, 'close'):
225 self.hProcess.close()
226 elif self.hProcess not in (None, win32.INVALID_HANDLE_VALUE):
227 win32.CloseHandle(self.hProcess)
228 finally:
229 self.hProcess = None
230
232 """
233 Returns a handle to the process with I{at least} the access rights
234 requested.
235
236 @note:
237 If a handle was previously opened and has the required access
238 rights, it's reused. If not, a new handle is opened with the
239 combination of the old and new access rights.
240
241 @type dwDesiredAccess: int
242 @param dwDesiredAccess: Desired access rights.
243 Defaults to L{win32.PROCESS_ALL_ACCESS}.
244 See: U{http://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx}
245
246 @rtype: L{ProcessHandle}
247 @return: Handle to the process.
248
249 @raise WindowsError: It's not possible to open a handle to the process
250 with the requested access rights. This tipically happens because
251 the target process is a system process and the debugger is not
252 runnning with administrative rights.
253 """
254 if self.hProcess in (None, win32.INVALID_HANDLE_VALUE):
255 self.open_handle(dwDesiredAccess)
256 else:
257 dwAccess = self.hProcess.dwAccess
258 if (dwAccess | dwDesiredAccess) != dwAccess:
259 self.open_handle(dwAccess | dwDesiredAccess)
260 return self.hProcess
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
284 """
285 The same as: C{self.has_thread(anObject) or self.has_module(anObject)}
286
287 @type anObject: L{Thread}, L{Module} or int
288 @param anObject: Object to look for.
289 Can be a Thread, Module, thread global ID or module base address.
290
291 @rtype: bool
292 @return: C{True} if the requested object was found in the snapshot.
293 """
294 return _ThreadContainer.__contains__(self, anObject) or \
295 _ModuleContainer.__contains__(self, anObject)
296
298 """
299 @see: L{get_thread_count}, L{get_module_count}
300 @rtype: int
301 @return: Count of L{Thread} and L{Module} objects in this snapshot.
302 """
303 return _ThreadContainer.__len__(self) + \
304 _ModuleContainer.__len__(self)
305
307 """
308 Iterator object for L{Process} objects.
309 Iterates through L{Thread} objects first, L{Module} objects next.
310 """
311
313 """
314 @type container: L{Process}
315 @param container: L{Thread} and L{Module} container.
316 """
317 self.__container = container
318 self.__iterator = None
319 self.__state = 0
320
322 'x.__iter__() <==> iter(x)'
323 return self
324
326 'x.next() -> the next value, or raise StopIteration'
327 if self.__state == 0:
328 self.__iterator = self.__container.iter_threads()
329 self.__state = 1
330 if self.__state == 1:
331 try:
332 return self.__iterator.next()
333 except StopIteration:
334 self.__iterator = self.__container.iter_modules()
335 self.__state = 2
336 if self.__state == 2:
337 try:
338 return self.__iterator.next()
339 except StopIteration:
340 self.__iterator = None
341 self.__state = 3
342 raise StopIteration
343
345 """
346 @see: L{iter_threads}, L{iter_modules}
347 @rtype: iterator
348 @return: Iterator of L{Thread} and L{Module} objects in this snapshot.
349 All threads are iterated first, then all modules.
350 """
351 return self.__ThreadsAndModulesIterator(self)
352
353
354
355 - def wait(self, dwTimeout = None):
356 """
357 Waits for the process to finish executing.
358
359 @raise WindowsError: On error an exception is raised.
360 """
361 self.get_handle(win32.SYNCHRONIZE).wait(dwTimeout)
362
363 - def kill(self, dwExitCode = 0):
371
373 """
374 Suspends execution on all threads of the process.
375
376 @raise WindowsError: On error an exception is raised.
377 """
378 self.scan_threads()
379 suspended = list()
380 try:
381 for aThread in self.iter_threads():
382 aThread.suspend()
383 suspended.append(aThread)
384 except Exception:
385 for aThread in suspended:
386 try:
387 aThread.resume()
388 except Exception:
389 pass
390 raise
391
393 """
394 Resumes execution on all threads of the process.
395
396 @raise WindowsError: On error an exception is raised.
397 """
398 if self.get_thread_count() == 0:
399 self.scan_threads()
400 resumed = list()
401 try:
402 for aThread in self.iter_threads():
403 aThread.resume()
404 resumed.append(aThread)
405 except Exception:
406 for aThread in resumed:
407 try:
408 aThread.suspend()
409 except Exception:
410 pass
411 raise
412
414 """
415 Tries to determine if the process is being debugged by another process.
416 It may detect other debuggers besides WinAppDbg.
417
418 @rtype: bool
419 @return: C{True} if the process has a debugger attached.
420
421 @warning:
422 May return inaccurate results when some anti-debug techniques are
423 used by the target process.
424
425 @note: To know if a process currently being debugged by a L{Debug}
426 object, call L{Debug.is_debugee} instead.
427 """
428
429 hProcess = self.get_handle(win32.PROCESS_QUERY_INFORMATION)
430 return win32.CheckRemoteDebuggerPresent(hProcess)
431
433 """
434 @rtype: bool
435 @return: C{True} if the process is currently running.
436 """
437 try:
438 self.wait(0)
439 except WindowsError, e:
440 return e.winerror == win32.WAIT_TIMEOUT
441 return False
442
460
461
462
469
481
482
483
484
485 __hexa_parameter = re.compile('0x[0-9A-Fa-f]+')
486
488 """
489 Private method used when disassembling from process memory.
490
491 It has no return value because the list is modified in place. On return
492 all raw memory addresses are replaced by labels when possible.
493
494 @type disasm: list of tuple(int, int, str, str)
495 @param disasm: Output of one of the dissassembly functions.
496 """
497 for index in xrange(len(disasm)):
498 (address, size, text, dump) = disasm[index]
499 m = self.__hexa_parameter.search(text)
500 while m:
501 s, e = m.span()
502 value = text[s:e]
503 try:
504 label = self.get_label_at_address( int(value, 0x10) )
505 except Exception:
506 label = None
507 if label:
508 text = text[:s] + label + text[e:]
509 e = s + len(value)
510 m = self.__hexa_parameter.search(text, e)
511 disasm[index] = (address, size, text, dump)
512
514 """
515 Disassemble instructions from a block of binary code.
516
517 @type lpAddress: int
518 @param lpAddress: Memory address where the code was read from.
519
520 @type code: str
521 @param code: Binary code to disassemble.
522
523 @rtype: list of tuple( long, int, str, str )
524 @return: List of tuples. Each tuple represents an assembly instruction
525 and contains:
526 - Memory address of instruction.
527 - Size of instruction in bytes.
528 - Disassembly line of instruction.
529 - Hexadecimal dump of instruction.
530
531 @raise NotImplementedError:
532 No compatible disassembler was found for the current platform.
533 """
534 try:
535 disasm = self.__disasm
536 except AttributeError:
537 disasm = self.__disasm = Disassembler( self.get_arch() )
538 return disasm.decode(lpAddress, code)
539
541 """
542 Disassemble instructions from the address space of the process.
543
544 @type lpAddress: int
545 @param lpAddress: Memory address where to read the code from.
546
547 @type dwSize: int
548 @param dwSize: Size of binary code to disassemble.
549
550 @rtype: list of tuple( long, int, str, str )
551 @return: List of tuples. Each tuple represents an assembly instruction
552 and contains:
553 - Memory address of instruction.
554 - Size of instruction in bytes.
555 - Disassembly line of instruction.
556 - Hexadecimal dump of instruction.
557 """
558 data = self.read(lpAddress, dwSize)
559 disasm = self.disassemble_string(lpAddress, data)
560 self.__fixup_labels(disasm)
561 return disasm
562
563
564
566 """
567 Disassemble around the given address.
568
569 @type lpAddress: int
570 @param lpAddress: Memory address where to read the code from.
571
572 @type dwSize: int
573 @param dwSize: Delta offset.
574 Code will be read from lpAddress - dwSize to lpAddress + dwSize.
575
576 @rtype: list of tuple( long, int, str, str )
577 @return: List of tuples. Each tuple represents an assembly instruction
578 and contains:
579 - Memory address of instruction.
580 - Size of instruction in bytes.
581 - Disassembly line of instruction.
582 - Hexadecimal dump of instruction.
583 """
584 dwDelta = int(float(dwSize) / 2.0)
585 addr_1 = lpAddress - dwDelta
586 addr_2 = lpAddress
587 size_1 = dwDelta
588 size_2 = dwSize - dwDelta
589 data = self.read(addr_1, dwSize)
590 data_1 = data[:size_1]
591 data_2 = data[size_1:]
592 disasm_1 = self.disassemble_string(addr_1, data_1)
593 disasm_2 = self.disassemble_string(addr_2, data_2)
594 disasm = disasm_1 + disasm_2
595 self.__fixup_labels(disasm)
596 return disasm
597
599 """
600 Disassemble around the program counter of the given thread.
601
602 @type dwThreadId: int
603 @param dwThreadId: Global thread ID.
604 The program counter for this thread will be used as the disassembly
605 address.
606
607 @type dwSize: int
608 @param dwSize: Delta offset.
609 Code will be read from pc - dwSize to pc + dwSize.
610
611 @rtype: list of tuple( long, int, str, str )
612 @return: List of tuples. Each tuple represents an assembly instruction
613 and contains:
614 - Memory address of instruction.
615 - Size of instruction in bytes.
616 - Disassembly line of instruction.
617 - Hexadecimal dump of instruction.
618 """
619 aThread = self.get_thread(dwThreadId)
620 return self.disassemble_around(aThread.get_pc(), dwSize)
621
623 """
624 Disassemble the instruction at the given memory address.
625
626 @type lpAddress: int
627 @param lpAddress: Memory address where to read the code from.
628
629 @rtype: tuple( long, int, str, str )
630 @return: The tuple represents an assembly instruction
631 and contains:
632 - Memory address of instruction.
633 - Size of instruction in bytes.
634 - Disassembly line of instruction.
635 - Hexadecimal dump of instruction.
636 """
637 return self.disassemble(lpAddress, 15)[0]
638
640 """
641 Disassemble the instruction at the program counter of the given thread.
642
643 @type dwThreadId: int
644 @param dwThreadId: Global thread ID.
645 The program counter for this thread will be used as the disassembly
646 address.
647
648 @rtype: tuple( long, int, str, str )
649 @return: The tuple represents an assembly instruction
650 and contains:
651 - Memory address of instruction.
652 - Size of instruction in bytes.
653 - Disassembly line of instruction.
654 - Hexadecimal dump of instruction.
655 """
656 aThread = self.get_thread(dwThreadId)
657 return self.disassemble_instruction(aThread.get_pc())
658
659
660
662 """
663 Flush the instruction cache. This is required if the process memory is
664 modified and one or more threads are executing nearby the modified
665 memory region.
666
667 @see: U{http://blogs.msdn.com/oldnewthing/archive/2003/12/08/55954.aspx#55958}
668
669 @raise WindowsError: Raises exception on error.
670 """
671
672
673
674
675
676 win32.FlushInstructionCache( self.get_handle() )
677
679 """
680 Triggers the system breakpoint in the process.
681
682 @raise WindowsError: On error an exception is raised.
683 """
684
685
686
687 win32.DebugBreakProcess( self.get_handle() )
688
723
725 """
726 @rtype: str
727 @return: The architecture in which this process believes to be running.
728 For example, if running a 32 bit binary in a 64 bit machine, the
729 architecture returned by this method will be L{win32.ARCH_I386},
730 but the value of L{System.arch} will be L{win32.ARCH_AMD64}.
731 """
732
733
734 if win32.bits == 32 and not win32.wow64:
735 return win32.arch
736
737
738 if not self.is_wow64():
739 return win32.arch
740
741
742 if win32.arch == win32.ARCH_AMD64:
743 return win32.ARCH_I386
744
745
746 raise NotImplementedError()
747
749 """
750 @rtype: str
751 @return: The number of bits in which this process believes to be
752 running. For example, if running a 32 bit binary in a 64 bit
753 machine, the number of bits returned by this method will be C{32},
754 but the value of L{System.arch} will be C{64}.
755 """
756
757
758 if win32.bits == 32 and not win32.wow64:
759
760
761 return 32
762
763
764 if self.is_wow64():
765
766
767 return 32
768
769
770 return 64
771
772
773
774
775
776
791
810
830
831
832
837
839 """
840 Retrieves the list of system services that are currently running in
841 this process.
842
843 @see: L{System.get_services}
844
845 @rtype: list( L{win32.ServiceStatusProcessEntry} )
846 @return: List of service status descriptors.
847 """
848 self.__load_System_class()
849 pid = self.get_pid()
850 return [d for d in System.get_active_services() if d.ProcessId == pid]
851
852
853
855 """
856 Retrieves the DEP (Data Execution Prevention) policy for this process.
857
858 @note: This method is only available in Windows XP SP3 and above, and
859 only for 32 bit processes. It will fail in any other circumstance.
860
861 @see: U{http://msdn.microsoft.com/en-us/library/bb736297(v=vs.85).aspx}
862
863 @rtype: tuple(int, int)
864 @return:
865 The first member of the tuple is the DEP flags. It can be a
866 combination of the following values:
867 - 0: DEP is disabled for this process.
868 - 1: DEP is enabled for this process. (C{PROCESS_DEP_ENABLE})
869 - 2: DEP-ATL thunk emulation is disabled for this process.
870 (C{PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION})
871
872 The second member of the tuple is the permanent flag. If C{TRUE}
873 the DEP settings cannot be changed in runtime for this process.
874
875 @raise WindowsError: On error an exception is raised.
876 """
877 hProcess = self.get_handle(win32.PROCESS_QUERY_INFORMATION)
878 try:
879 return win32.kernel32.GetProcessDEPPolicy(hProcess)
880 except AttributeError:
881 msg = "This method is only available in Windows XP SP3 and above."
882 raise NotImplementedError(msg)
883
884
885
898
916
917 - def get_entry_point(self):
918 """
919 Alias to C{process.get_main_module().get_entry_point()}.
920
921 @rtype: int
922 @return: Address of the entry point of the main module.
923 """
924 return self.get_main_module().get_entry_point()
925
926 - def get_main_module(self):
927 """
928 @rtype: L{Module}
929 @return: Module object for the process main module.
930 """
931 return self.get_module(self.get_image_base())
932
934 """
935 @rtype: int
936 @return: Image base address for the process main module.
937 """
938 return self.get_peb().ImageBaseAddress
939
941 """
942 @rtype: int
943 @return: Filename of the process main module.
944
945 This method does it's best to retrieve the filename.
946 However sometimes this is not possible, so C{None} may
947 be returned instead.
948 """
949
950
951
952
953
954 mainModule = None
955 try:
956 mainModule = self.get_main_module()
957 name = mainModule.fileName
958 if not name:
959 name = None
960 except (KeyError, AttributeError, WindowsError):
961
962 name = None
963
964
965
966 if not name:
967 try:
968 hProcess = self.get_handle(
969 win32.PROCESS_QUERY_LIMITED_INFORMATION)
970 name = win32.QueryFullProcessImageName(hProcess)
971 except (AttributeError, WindowsError):
972
973 name = None
974
975
976
977
978
979
980 if not name:
981 try:
982 hProcess = self.get_handle(win32.PROCESS_QUERY_INFORMATION)
983 name = win32.GetProcessImageFileName(hProcess)
984 if name:
985 name = PathOperations.native_to_win32_pathname(name)
986 else:
987 name = None
988 except (AttributeError, WindowsError):
989
990 if not name:
991 name = None
992
993
994
995
996
997
998 if not name:
999 try:
1000 hProcess = self.get_handle( win32.PROCESS_VM_READ |
1001 win32.PROCESS_QUERY_INFORMATION )
1002 try:
1003 name = win32.GetModuleFileNameEx(hProcess)
1004 except WindowsError:
1005
1006 name = win32.GetModuleFileNameEx(
1007 hProcess, self.get_image_base())
1008 if name:
1009 name = PathOperations.native_to_win32_pathname(name)
1010 else:
1011 name = None
1012 except (AttributeError, WindowsError):
1013
1014 if not name:
1015 name = None
1016
1017
1018
1019
1020
1021
1022
1023 if not name:
1024 try:
1025 peb = self.get_peb()
1026 pp = self.read_structure(peb.ProcessParameters,
1027 win32.RTL_USER_PROCESS_PARAMETERS)
1028 s = pp.ImagePathName
1029 name = self.peek_string(s.Buffer,
1030 dwMaxSize=s.MaximumLength, fUnicode=True)
1031 if name:
1032 name = PathOperations.native_to_win32_pathname(name)
1033 else:
1034 name = None
1035 except (AttributeError, WindowsError):
1036
1037 name = None
1038
1039
1040
1041
1042
1043
1044
1045 if not name and mainModule is not None:
1046 try:
1047 name = mainModule.get_filename()
1048 if not name:
1049 name = None
1050 except (AttributeError, WindowsError):
1051
1052 name = None
1053
1054
1055 if name and mainModule is not None:
1056 mainModule.fileName = name
1057
1058
1059 return name
1060
1076
1078 """
1079 Retrieves the environment block memory address for the process.
1080
1081 @note: The size is always enough to contain the environment data, but
1082 it may not be an exact size. It's best to read the memory and
1083 scan for two null wide chars to find the actual size.
1084
1085 @rtype: tuple(int, int)
1086 @return: Tuple with the memory address of the environment block
1087 and it's size.
1088
1089 @raise WindowsError: On error an exception is raised.
1090 """
1091 peb = self.get_peb()
1092 pp = self.read_structure(peb.ProcessParameters,
1093 win32.RTL_USER_PROCESS_PARAMETERS)
1094 Environment = pp.Environment
1095 try:
1096 EnvironmentSize = pp.EnvironmentSize
1097 except AttributeError:
1098 mbi = self.mquery(Environment)
1099 EnvironmentSize = mbi.RegionSize + mbi.BaseAddress - Environment
1100 return (Environment, EnvironmentSize)
1101
1118
1120 """
1121 Retrieves the environment variables with wich the program is running.
1122
1123 @rtype: list of tuple(unicode, unicode)
1124 @return: Environment keys and values as found in the process memory.
1125
1126 @raise WindowsError: On error an exception is raised.
1127 """
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140 data = self.peek( *self.get_environment_block() )
1141
1142
1143 tmp = ctypes.create_string_buffer(data)
1144 buffer = ctypes.create_unicode_buffer(len(data))
1145 ctypes.memmove(buffer, tmp, len(data))
1146 del tmp
1147
1148
1149 pos = 0
1150 while buffer[pos] != u'\0':
1151 pos += 1
1152 pos += 1
1153
1154
1155 environment = []
1156 while buffer[pos] != u'\0':
1157
1158
1159 env_name_pos = pos
1160 env_name = u''
1161 found_name = False
1162 while buffer[pos] != u'\0':
1163
1164
1165 char = buffer[pos]
1166
1167
1168 if char == u'=':
1169
1170
1171 if env_name_pos == pos:
1172 env_name_pos += 1
1173 pos += 1
1174 continue
1175
1176
1177 pos += 1
1178 found_name = True
1179 break
1180
1181
1182 env_name += char
1183
1184
1185 pos += 1
1186
1187
1188 if not found_name:
1189 break
1190
1191
1192 env_value = u''
1193 while buffer[pos] != u'\0':
1194 env_value += buffer[pos]
1195 pos += 1
1196
1197
1198 pos += 1
1199
1200
1201 environment.append( (env_name, env_value) )
1202
1203
1204 if environment:
1205 environment.pop()
1206
1207
1208 return environment
1209
1211 """
1212 Retrieves the environment block data with wich the program is running.
1213
1214 @warn: Deprecated since WinAppDbg 1.5.
1215
1216 @see: L{win32.GuessStringType}
1217
1218 @type fUnicode: bool or None
1219 @param fUnicode: C{True} to return a list of Unicode strings, C{False}
1220 to return a list of ANSI strings, or C{None} to return whatever
1221 the default is for string types.
1222
1223 @rtype: list of str
1224 @return: Environment keys and values separated by a (C{=}) character,
1225 as found in the process memory.
1226
1227 @raise WindowsError: On error an exception is raised.
1228 """
1229
1230
1231 warnings.warn(
1232 "Process.get_environment_data() is deprecated" \
1233 " since WinAppDbg 1.5.",
1234 DeprecationWarning)
1235
1236
1237 block = [ key + u'=' + value for (key, value) \
1238 in self.get_environment_variables() ]
1239
1240
1241 if fUnicode is None:
1242 gst = win32.GuessStringType
1243 fUnicode = gst.t_default == gst.t_unicode
1244 if not fUnicode:
1245 block = [x.encode('cp1252') for x in block]
1246
1247
1248 return block
1249
1250 @staticmethod
1252 """
1253 Parse the environment block into a Python dictionary.
1254
1255 @warn: Deprecated since WinAppDbg 1.5.
1256
1257 @note: Values of duplicated keys are joined using null characters.
1258
1259 @type block: list of str
1260 @param block: List of strings as returned by L{get_environment_data}.
1261
1262 @rtype: dict(str S{->} str)
1263 @return: Dictionary of environment keys and values.
1264 """
1265
1266
1267 warnings.warn(
1268 "Process.parse_environment_data() is deprecated" \
1269 " since WinAppDbg 1.5.",
1270 DeprecationWarning)
1271
1272
1273 environment = dict()
1274
1275
1276 if not block:
1277 return environment
1278
1279
1280 gst = win32.GuessStringType
1281 if type(block[0]) == gst.t_ansi:
1282 equals = '='
1283 terminator = '\0'
1284 else:
1285 equals = u'='
1286 terminator = u'\0'
1287
1288
1289 for chunk in block:
1290 sep = chunk.find(equals, 1)
1291 if sep < 0:
1292
1293 continue
1294 key, value = chunk[:sep], chunk[sep+1:]
1295
1296
1297
1298 if key not in environment:
1299 environment[key] = value
1300 else:
1301 environment[key] += terminator + value
1302
1303
1304 return environment
1305
1307 """
1308 Retrieves the environment with wich the program is running.
1309
1310 @note: Duplicated keys are joined using null characters.
1311 To avoid this behavior, call L{get_environment_variables} instead
1312 and convert the results to a dictionary directly, like this:
1313 C{dict(process.get_environment_variables())}
1314
1315 @see: L{win32.GuessStringType}
1316
1317 @type fUnicode: bool or None
1318 @param fUnicode: C{True} to return a list of Unicode strings, C{False}
1319 to return a list of ANSI strings, or C{None} to return whatever
1320 the default is for string types.
1321
1322 @rtype: dict(str S{->} str)
1323 @return: Dictionary of environment keys and values.
1324
1325 @raise WindowsError: On error an exception is raised.
1326 """
1327
1328
1329 variables = self.get_environment_variables()
1330
1331
1332 if fUnicode is None:
1333 gst = win32.GuessStringType
1334 fUnicode = gst.t_default == gst.t_unicode
1335 if not fUnicode:
1336 variables = [ ( key.encode('cp1252'), value.encode('cp1252') ) \
1337 for (key, value) in variables ]
1338
1339
1340 environment = dict()
1341 for key, value in variables:
1342 if key in environment:
1343 environment[key] = environment[key] + u'\0' + value
1344 else:
1345 environment[key] = value
1346
1347
1348 return environment
1349
1350
1351
1352 - def search(self, pattern, minAddr = None, maxAddr = None):
1353 """
1354 Search for the given pattern within the process memory.
1355
1356 @type pattern: str, unicode or L{Pattern}
1357 @param pattern: Pattern to search for.
1358 It may be a byte string, a Unicode string, or an instance of
1359 L{Pattern}.
1360
1361 The following L{Pattern} subclasses are provided by WinAppDbg:
1362 - L{BytePattern}
1363 - L{TextPattern}
1364 - L{RegExpPattern}
1365 - L{HexPattern}
1366
1367 You can also write your own subclass of L{Pattern} for customized
1368 searches.
1369
1370 @type minAddr: int
1371 @param minAddr: (Optional) Start the search at this memory address.
1372
1373 @type maxAddr: int
1374 @param maxAddr: (Optional) Stop the search at this memory address.
1375
1376 @rtype: iterator of tuple( int, int, str )
1377 @return: An iterator of tuples. Each tuple contains the following:
1378 - The memory address where the pattern was found.
1379 - The size of the data that matches the pattern.
1380 - The data that matches the pattern.
1381
1382 @raise WindowsError: An error occurred when querying or reading the
1383 process memory.
1384 """
1385 if isinstance(pattern, str):
1386 return self.search_bytes(pattern, minAddr, maxAddr)
1387 if isinstance(pattern, unicode):
1388 return self.search_bytes(pattern.encode("utf-16le"),
1389 minAddr, maxAddr)
1390 if isinstance(pattern, Pattern):
1391 return Search.search_process(self, pattern, minAddr, maxAddr)
1392 raise TypeError("Unknown pattern type: %r" % type(pattern))
1393
1394 - def search_bytes(self, bytes, minAddr = None, maxAddr = None):
1395 """
1396 Search for the given byte pattern within the process memory.
1397
1398 @type bytes: str
1399 @param bytes: Bytes to search for.
1400
1401 @type minAddr: int
1402 @param minAddr: (Optional) Start the search at this memory address.
1403
1404 @type maxAddr: int
1405 @param maxAddr: (Optional) Stop the search at this memory address.
1406
1407 @rtype: iterator of int
1408 @return: An iterator of memory addresses where the pattern was found.
1409
1410 @raise WindowsError: An error occurred when querying or reading the
1411 process memory.
1412 """
1413 pattern = BytePattern(bytes)
1414 matches = Search.search_process(self, pattern, minAddr, maxAddr)
1415 for addr, size, data in matches:
1416 yield addr
1417
1418 - def search_text(self, text, encoding = "utf-16le",
1419 caseSensitive = False,
1420 minAddr = None,
1421 maxAddr = None):
1422 """
1423 Search for the given text within the process memory.
1424
1425 @type text: str or unicode
1426 @param text: Text to search for.
1427
1428 @type encoding: str
1429 @param encoding: (Optional) Encoding for the text parameter.
1430 Only used when the text to search for is a Unicode string.
1431 Don't change unless you know what you're doing!
1432
1433 @type caseSensitive: bool
1434 @param caseSensitive: C{True} of the search is case sensitive,
1435 C{False} otherwise.
1436
1437 @type minAddr: int
1438 @param minAddr: (Optional) Start the search at this memory address.
1439
1440 @type maxAddr: int
1441 @param maxAddr: (Optional) Stop the search at this memory address.
1442
1443 @rtype: iterator of tuple( int, str )
1444 @return: An iterator of tuples. Each tuple contains the following:
1445 - The memory address where the pattern was found.
1446 - The text that matches the pattern.
1447
1448 @raise WindowsError: An error occurred when querying or reading the
1449 process memory.
1450 """
1451 pattern = TextPattern(text, encoding, caseSensitive)
1452 matches = Search.search_process(self, pattern, minAddr, maxAddr)
1453 for addr, size, data in matches:
1454 yield addr, data
1455
1456 - def search_regexp(self, regexp, flags = 0,
1457 minAddr = None,
1458 maxAddr = None,
1459 bufferPages = -1):
1460 """
1461 Search for the given regular expression within the process memory.
1462
1463 @type regexp: str
1464 @param regexp: Regular expression string.
1465
1466 @type flags: int
1467 @param flags: Regular expression flags.
1468
1469 @type minAddr: int
1470 @param minAddr: (Optional) Start the search at this memory address.
1471
1472 @type maxAddr: int
1473 @param maxAddr: (Optional) Stop the search at this memory address.
1474
1475 @type bufferPages: int
1476 @param bufferPages: (Optional) Number of memory pages to buffer when
1477 performing the search. Valid values are:
1478 - C{0} or C{None}:
1479 Automatically determine the required buffer size. May not give
1480 complete results for regular expressions that match variable
1481 sized strings.
1482 - C{> 0}: Set the buffer size, in memory pages.
1483 - C{< 0}: Disable buffering entirely. This may give you a little
1484 speed gain at the cost of an increased memory usage. If the
1485 target process has very large contiguous memory regions it may
1486 actually be slower or even fail. It's also the only way to
1487 guarantee complete results for regular expressions that match
1488 variable sized strings.
1489
1490 @rtype: iterator of tuple( int, int, str )
1491 @return: An iterator of tuples. Each tuple contains the following:
1492 - The memory address where the pattern was found.
1493 - The size of the data that matches the pattern.
1494 - The data that matches the pattern.
1495
1496 @raise WindowsError: An error occurred when querying or reading the
1497 process memory.
1498 """
1499 pattern = RegExpPattern(regexp, flags)
1500 return Search.search_process(self, pattern,
1501 minAddr, maxAddr,
1502 bufferPages)
1503
1504 - def search_hexa(self, hexa, minAddr = None, maxAddr = None):
1505 """
1506 Search for the given hexadecimal pattern within the process memory.
1507
1508 Hex patterns must be in this form::
1509 "68 65 6c 6c 6f 20 77 6f 72 6c 64" # "hello world"
1510
1511 Spaces are optional. Capitalization of hex digits doesn't matter.
1512 This is exactly equivalent to the previous example::
1513 "68656C6C6F20776F726C64" # "hello world"
1514
1515 Wildcards are allowed, in the form of a C{?} sign in any hex digit::
1516 "5? 5? c3" # pop register / pop register / ret
1517 "b8 ?? ?? ?? ??" # mov eax, immediate value
1518
1519 @type hexa: str
1520 @param hexa: Pattern to search for.
1521
1522 @type minAddr: int
1523 @param minAddr: (Optional) Start the search at this memory address.
1524
1525 @type maxAddr: int
1526 @param maxAddr: (Optional) Stop the search at this memory address.
1527
1528 @rtype: iterator of tuple( int, str )
1529 @return: An iterator of tuples. Each tuple contains the following:
1530 - The memory address where the pattern was found.
1531 - The bytes that match the pattern.
1532
1533 @raise WindowsError: An error occurred when querying or reading the
1534 process memory.
1535 """
1536 pattern = HexPattern(hexa)
1537 matches = Search.search_process(self, pattern, minAddr, maxAddr)
1538 for addr, size, data in matches:
1539 yield addr, data
1540
1541 - def strings(self, minSize = 4, maxSize = 1024):
1542 """
1543 Extract ASCII strings from the process memory.
1544
1545 @type minSize: int
1546 @param minSize: (Optional) Minimum size of the strings to search for.
1547
1548 @type maxSize: int
1549 @param maxSize: (Optional) Maximum size of the strings to search for.
1550
1551 @rtype: iterator of tuple(int, int, str)
1552 @return: Iterator of strings extracted from the process memory.
1553 Each tuple contains the following:
1554 - The memory address where the string was found.
1555 - The size of the string.
1556 - The string.
1557 """
1558 return Search.extract_ascii_strings(self, minSize = minSize,
1559 maxSize = maxSize)
1560
1561
1562
1564 size = ctypes.sizeof(c_type)
1565 packed = self.read(address, size)
1566 if len(packed) != size:
1567 raise ctypes.WinError()
1568 return struct.unpack(format, packed)[0]
1569
1571 packed = struct.pack('@L', unpacked)
1572 self.write(address, packed)
1573
1574
1575
1576 - def read(self, lpBaseAddress, nSize):
1577 """
1578 Reads from the memory of the process.
1579
1580 @see: L{peek}
1581
1582 @type lpBaseAddress: int
1583 @param lpBaseAddress: Memory address to begin reading.
1584
1585 @type nSize: int
1586 @param nSize: Number of bytes to read.
1587
1588 @rtype: str
1589 @return: Bytes read from the process memory.
1590
1591 @raise WindowsError: On error an exception is raised.
1592 """
1593 hProcess = self.get_handle( win32.PROCESS_VM_READ |
1594 win32.PROCESS_QUERY_INFORMATION )
1595 if not self.is_buffer(lpBaseAddress, nSize):
1596 raise ctypes.WinError(win32.ERROR_INVALID_ADDRESS)
1597 data = win32.ReadProcessMemory(hProcess, lpBaseAddress, nSize)
1598 if len(data) != nSize:
1599 raise ctypes.WinError()
1600 return data
1601
1602 - def write(self, lpBaseAddress, lpBuffer):
1603 """
1604 Writes to the memory of the process.
1605
1606 @note: Page permissions may be changed temporarily while writing.
1607
1608 @see: L{poke}
1609
1610 @type lpBaseAddress: int
1611 @param lpBaseAddress: Memory address to begin writing.
1612
1613 @type lpBuffer: str
1614 @param lpBuffer: Bytes to write.
1615
1616 @raise WindowsError: On error an exception is raised.
1617 """
1618 r = self.poke(lpBaseAddress, lpBuffer)
1619 if r != len(lpBuffer):
1620 raise ctypes.WinError()
1621
1623 """
1624 Reads a single character to the memory of the process.
1625
1626 @see: L{peek_char}
1627
1628 @type lpBaseAddress: int
1629 @param lpBaseAddress: Memory address to begin writing.
1630
1631 @rtype: int
1632 @return: Character value read from the process memory.
1633
1634 @raise WindowsError: On error an exception is raised.
1635 """
1636 return ord( self.read(lpBaseAddress, 1) )
1637
1639 """
1640 Writes a single character to the memory of the process.
1641
1642 @note: Page permissions may be changed temporarily while writing.
1643
1644 @see: L{poke_char}
1645
1646 @type lpBaseAddress: int
1647 @param lpBaseAddress: Memory address to begin writing.
1648
1649 @type char: int
1650 @param char: Character to write.
1651
1652 @raise WindowsError: On error an exception is raised.
1653 """
1654 self.write(lpBaseAddress, chr(char))
1655
1657 """
1658 Reads a signed integer from the memory of the process.
1659
1660 @see: L{peek_int}
1661
1662 @type lpBaseAddress: int
1663 @param lpBaseAddress: Memory address to begin reading.
1664
1665 @rtype: int
1666 @return: Integer value read from the process memory.
1667
1668 @raise WindowsError: On error an exception is raised.
1669 """
1670 return self.__read_c_type(lpBaseAddress, '@l', ctypes.c_int)
1671
1672 - def write_int(self, lpBaseAddress, unpackedValue):
1673 """
1674 Writes a signed integer to the memory of the process.
1675
1676 @note: Page permissions may be changed temporarily while writing.
1677
1678 @see: L{poke_int}
1679
1680 @type lpBaseAddress: int
1681 @param lpBaseAddress: Memory address to begin writing.
1682
1683 @type unpackedValue: int, long
1684 @param unpackedValue: Value to write.
1685
1686 @raise WindowsError: On error an exception is raised.
1687 """
1688 self.__write_c_type(lpBaseAddress, '@l', unpackedValue)
1689
1691 """
1692 Reads an unsigned integer from the memory of the process.
1693
1694 @see: L{peek_uint}
1695
1696 @type lpBaseAddress: int
1697 @param lpBaseAddress: Memory address to begin reading.
1698
1699 @rtype: int
1700 @return: Integer value read from the process memory.
1701
1702 @raise WindowsError: On error an exception is raised.
1703 """
1704 return self.__read_c_type(lpBaseAddress, '@L', ctypes.c_uint)
1705
1706 - def write_uint(self, lpBaseAddress, unpackedValue):
1707 """
1708 Writes an unsigned integer to the memory of the process.
1709
1710 @note: Page permissions may be changed temporarily while writing.
1711
1712 @see: L{poke_uint}
1713
1714 @type lpBaseAddress: int
1715 @param lpBaseAddress: Memory address to begin writing.
1716
1717 @type unpackedValue: int, long
1718 @param unpackedValue: Value to write.
1719
1720 @raise WindowsError: On error an exception is raised.
1721 """
1722 self.__write_c_type(lpBaseAddress, '@L', unpackedValue)
1723
1725 """
1726 Reads a float from the memory of the process.
1727
1728 @see: L{peek_float}
1729
1730 @type lpBaseAddress: int
1731 @param lpBaseAddress: Memory address to begin reading.
1732
1733 @rtype: int
1734 @return: Floating point value read from the process memory.
1735
1736 @raise WindowsError: On error an exception is raised.
1737 """
1738 return self.__read_c_type(lpBaseAddress, '@f', ctypes.c_float)
1739
1741 """
1742 Writes a float to the memory of the process.
1743
1744 @note: Page permissions may be changed temporarily while writing.
1745
1746 @see: L{poke_float}
1747
1748 @type lpBaseAddress: int
1749 @param lpBaseAddress: Memory address to begin writing.
1750
1751 @type unpackedValue: int, long
1752 @param unpackedValue: Floating point value to write.
1753
1754 @raise WindowsError: On error an exception is raised.
1755 """
1756 self.__write_c_type(lpBaseAddress, '@f', unpackedValue)
1757
1759 """
1760 Reads a double from the memory of the process.
1761
1762 @see: L{peek_double}
1763
1764 @type lpBaseAddress: int
1765 @param lpBaseAddress: Memory address to begin reading.
1766
1767 @rtype: int
1768 @return: Floating point value read from the process memory.
1769
1770 @raise WindowsError: On error an exception is raised.
1771 """
1772 return self.__read_c_type(lpBaseAddress, '@d', ctypes.c_double)
1773
1775 """
1776 Writes a double to the memory of the process.
1777
1778 @note: Page permissions may be changed temporarily while writing.
1779
1780 @see: L{poke_double}
1781
1782 @type lpBaseAddress: int
1783 @param lpBaseAddress: Memory address to begin writing.
1784
1785 @type unpackedValue: int, long
1786 @param unpackedValue: Floating point value to write.
1787
1788 @raise WindowsError: On error an exception is raised.
1789 """
1790 self.__write_c_type(lpBaseAddress, '@d', unpackedValue)
1791
1793 """
1794 Reads a pointer value from the memory of the process.
1795
1796 @see: L{peek_pointer}
1797
1798 @type lpBaseAddress: int
1799 @param lpBaseAddress: Memory address to begin reading.
1800
1801 @rtype: int
1802 @return: Pointer value read from the process memory.
1803
1804 @raise WindowsError: On error an exception is raised.
1805 """
1806 return self.__read_c_type(lpBaseAddress, '@P', ctypes.c_void_p)
1807
1809 """
1810 Writes a pointer value to the memory of the process.
1811
1812 @note: Page permissions may be changed temporarily while writing.
1813
1814 @see: L{poke_pointer}
1815
1816 @type lpBaseAddress: int
1817 @param lpBaseAddress: Memory address to begin writing.
1818
1819 @type unpackedValue: int, long
1820 @param unpackedValue: Value to write.
1821
1822 @raise WindowsError: On error an exception is raised.
1823 """
1824 self.__write_c_type(lpBaseAddress, '@P', unpackedValue)
1825
1827 """
1828 Reads a DWORD from the memory of the process.
1829
1830 @see: L{peek_dword}
1831
1832 @type lpBaseAddress: int
1833 @param lpBaseAddress: Memory address to begin reading.
1834
1835 @rtype: int
1836 @return: Integer value read from the process memory.
1837
1838 @raise WindowsError: On error an exception is raised.
1839 """
1840 return self.__read_c_type(lpBaseAddress, '=L', win32.DWORD)
1841
1843 """
1844 Writes a DWORD to the memory of the process.
1845
1846 @note: Page permissions may be changed temporarily while writing.
1847
1848 @see: L{poke_dword}
1849
1850 @type lpBaseAddress: int
1851 @param lpBaseAddress: Memory address to begin writing.
1852
1853 @type unpackedValue: int, long
1854 @param unpackedValue: Value to write.
1855
1856 @raise WindowsError: On error an exception is raised.
1857 """
1858 self.__write_c_type(lpBaseAddress, '=L', unpackedValue)
1859
1861 """
1862 Reads a QWORD from the memory of the process.
1863
1864 @see: L{peek_qword}
1865
1866 @type lpBaseAddress: int
1867 @param lpBaseAddress: Memory address to begin reading.
1868
1869 @rtype: int
1870 @return: Integer value read from the process memory.
1871
1872 @raise WindowsError: On error an exception is raised.
1873 """
1874 return self.__read_c_type(lpBaseAddress, '=Q', win32.QWORD)
1875
1877 """
1878 Writes a QWORD to the memory of the process.
1879
1880 @note: Page permissions may be changed temporarily while writing.
1881
1882 @see: L{poke_qword}
1883
1884 @type lpBaseAddress: int
1885 @param lpBaseAddress: Memory address to begin writing.
1886
1887 @type unpackedValue: int, long
1888 @param unpackedValue: Value to write.
1889
1890 @raise WindowsError: On error an exception is raised.
1891 """
1892 self.__write_c_type(lpBaseAddress, '=Q', unpackedValue)
1893
1895 """
1896 Reads a ctypes structure from the memory of the process.
1897
1898 @see: L{read}
1899
1900 @type lpBaseAddress: int
1901 @param lpBaseAddress: Memory address to begin reading.
1902
1903 @type stype: class ctypes.Structure or a subclass.
1904 @param stype: Structure definition.
1905
1906 @rtype: int
1907 @return: Structure instance filled in with data
1908 read from the process memory.
1909
1910 @raise WindowsError: On error an exception is raised.
1911 """
1912 if type(lpBaseAddress) not in (type(0), type(0L)):
1913 lpBaseAddress = ctypes.cast(lpBaseAddress, ctypes.c_void_p)
1914 data = self.read(lpBaseAddress, ctypes.sizeof(stype))
1915 buff = ctypes.create_string_buffer(data)
1916 ptr = ctypes.cast(ctypes.pointer(buff), ctypes.POINTER(stype))
1917 return ptr.contents
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945 - def read_string(self, lpBaseAddress, nChars, fUnicode = False):
1946 """
1947 Reads an ASCII or Unicode string
1948 from the address space of the process.
1949
1950 @see: L{peek_string}
1951
1952 @type lpBaseAddress: int
1953 @param lpBaseAddress: Memory address to begin reading.
1954
1955 @type nChars: int
1956 @param nChars: String length to read, in characters.
1957 Remember that Unicode strings have two byte characters.
1958
1959 @type fUnicode: bool
1960 @param fUnicode: C{True} is the string is expected to be Unicode,
1961 C{False} if it's expected to be ANSI.
1962
1963 @rtype: str, unicode
1964 @return: String read from the process memory space.
1965
1966 @raise WindowsError: On error an exception is raised.
1967 """
1968 if fUnicode:
1969 nChars = nChars * 2
1970 szString = self.read(lpBaseAddress, nChars)
1971 if fUnicode:
1972 szString = unicode(szString, 'U16', 'ignore')
1973 return szString
1974
1975
1976
1977
1979 size = ctypes.sizeof(c_type)
1980 packed = self.peek(address, size)
1981 if len(packed) < size:
1982 packed = '\0' * (size - len(packed)) + packed
1983 elif len(packed) > size:
1984 packed = packed[:size]
1985 return struct.unpack(format, packed)[0]
1986
1988 packed = struct.pack('@L', unpacked)
1989 return self.poke(address, packed)
1990
1991 - def peek(self, lpBaseAddress, nSize):
1992 """
1993 Reads the memory of the process.
1994
1995 @see: L{read}
1996
1997 @type lpBaseAddress: int
1998 @param lpBaseAddress: Memory address to begin reading.
1999
2000 @type nSize: int
2001 @param nSize: Number of bytes to read.
2002
2003 @rtype: str
2004 @return: Bytes read from the process memory.
2005 Returns an empty string on error.
2006 """
2007
2008
2009
2010
2011 data = ''
2012 if nSize > 0:
2013 try:
2014 hProcess = self.get_handle( win32.PROCESS_VM_READ |
2015 win32.PROCESS_QUERY_INFORMATION )
2016 for mbi in self.get_memory_map(lpBaseAddress,
2017 lpBaseAddress + nSize):
2018 if not mbi.is_readable():
2019 nSize = mbi.BaseAddress - lpBaseAddress
2020 break
2021 if nSize > 0:
2022 data = win32.ReadProcessMemory(
2023 hProcess, lpBaseAddress, nSize)
2024 except WindowsError, e:
2025 msg = "Error reading process %d address %s: %s"
2026 msg %= (self.get_pid(),
2027 HexDump.address(lpBaseAddress),
2028 e.strerror)
2029 warnings.warn(msg)
2030 return data
2031
2032 - def poke(self, lpBaseAddress, lpBuffer):
2033 """
2034 Writes to the memory of the process.
2035
2036 @note: Page permissions may be changed temporarily while writing.
2037
2038 @see: L{write}
2039
2040 @type lpBaseAddress: int
2041 @param lpBaseAddress: Memory address to begin writing.
2042
2043 @type lpBuffer: str
2044 @param lpBuffer: Bytes to write.
2045
2046 @rtype: int
2047 @return: Number of bytes written.
2048 May be less than the number of bytes to write.
2049 """
2050 hProcess = self.get_handle( win32.PROCESS_VM_WRITE |
2051 win32.PROCESS_VM_OPERATION |
2052 win32.PROCESS_QUERY_INFORMATION )
2053 mbi = self.mquery(lpBaseAddress)
2054 if not mbi.has_content():
2055 raise ctypes.WinError(win32.ERROR_INVALID_ADDRESS)
2056 if mbi.is_image() or mbi.is_mapped():
2057 prot = win32.PAGE_WRITECOPY
2058 elif mbi.is_writeable():
2059 prot = None
2060 elif mbi.is_executable():
2061 prot = win32.PAGE_EXECUTE_READWRITE
2062 else:
2063 prot = win32.PAGE_READWRITE
2064 if prot is not None:
2065 try:
2066 self.mprotect(lpBaseAddress, len(lpBuffer), prot)
2067 except Exception:
2068 prot = None
2069 msg = ("Failed to adjust page permissions"
2070 " for process %s at address %s: %s")
2071 msg = msg % (self.get_pid(),
2072 HexDump.address(lpBaseAddress, self.get_bits()),
2073 traceback.format_exc())
2074 warnings.warn(msg, RuntimeWarning)
2075 try:
2076 r = win32.WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer)
2077 finally:
2078 if prot is not None:
2079 self.mprotect(lpBaseAddress, len(lpBuffer), mbi.Protect)
2080 return r
2081
2083 """
2084 Reads a single character from the memory of the process.
2085
2086 @see: L{read_char}
2087
2088 @type lpBaseAddress: int
2089 @param lpBaseAddress: Memory address to begin reading.
2090
2091 @rtype: int
2092 @return: Character read from the process memory.
2093 Returns zero on error.
2094 """
2095 char = self.peek(lpBaseAddress, 1)
2096 if char:
2097 return ord(char)
2098 return 0
2099
2101 """
2102 Writes a single character to the memory of the process.
2103
2104 @note: Page permissions may be changed temporarily while writing.
2105
2106 @see: L{write_char}
2107
2108 @type lpBaseAddress: int
2109 @param lpBaseAddress: Memory address to begin writing.
2110
2111 @type char: str
2112 @param char: Character to write.
2113
2114 @rtype: int
2115 @return: Number of bytes written.
2116 May be less than the number of bytes to write.
2117 """
2118 return self.poke(lpBaseAddress, chr(char))
2119
2121 """
2122 Reads a signed integer from the memory of the process.
2123
2124 @see: L{read_int}
2125
2126 @type lpBaseAddress: int
2127 @param lpBaseAddress: Memory address to begin reading.
2128
2129 @rtype: int
2130 @return: Integer value read from the process memory.
2131 Returns zero on error.
2132 """
2133 return self.__peek_c_type(lpBaseAddress, '@l', ctypes.c_int)
2134
2135 - def poke_int(self, lpBaseAddress, unpackedValue):
2136 """
2137 Writes a signed integer to the memory of the process.
2138
2139 @note: Page permissions may be changed temporarily while writing.
2140
2141 @see: L{write_int}
2142
2143 @type lpBaseAddress: int
2144 @param lpBaseAddress: Memory address to begin writing.
2145
2146 @type unpackedValue: int, long
2147 @param unpackedValue: Value to write.
2148
2149 @rtype: int
2150 @return: Number of bytes written.
2151 May be less than the number of bytes to write.
2152 """
2153 return self.__poke_c_type(lpBaseAddress, '@l', unpackedValue)
2154
2156 """
2157 Reads an unsigned integer from the memory of the process.
2158
2159 @see: L{read_uint}
2160
2161 @type lpBaseAddress: int
2162 @param lpBaseAddress: Memory address to begin reading.
2163
2164 @rtype: int
2165 @return: Integer value read from the process memory.
2166 Returns zero on error.
2167 """
2168 return self.__peek_c_type(lpBaseAddress, '@L', ctypes.c_uint)
2169
2170 - def poke_uint(self, lpBaseAddress, unpackedValue):
2171 """
2172 Writes an unsigned integer to the memory of the process.
2173
2174 @note: Page permissions may be changed temporarily while writing.
2175
2176 @see: L{write_uint}
2177
2178 @type lpBaseAddress: int
2179 @param lpBaseAddress: Memory address to begin writing.
2180
2181 @type unpackedValue: int, long
2182 @param unpackedValue: Value to write.
2183
2184 @rtype: int
2185 @return: Number of bytes written.
2186 May be less than the number of bytes to write.
2187 """
2188 return self.__poke_c_type(lpBaseAddress, '@L', unpackedValue)
2189
2191 """
2192 Reads a float from the memory of the process.
2193
2194 @see: L{read_float}
2195
2196 @type lpBaseAddress: int
2197 @param lpBaseAddress: Memory address to begin reading.
2198
2199 @rtype: int
2200 @return: Integer value read from the process memory.
2201 Returns zero on error.
2202 """
2203 return self.__peek_c_type(lpBaseAddress, '@f', ctypes.c_float)
2204
2205 - def poke_float(self, lpBaseAddress, unpackedValue):
2206 """
2207 Writes a float to the memory of the process.
2208
2209 @note: Page permissions may be changed temporarily while writing.
2210
2211 @see: L{write_float}
2212
2213 @type lpBaseAddress: int
2214 @param lpBaseAddress: Memory address to begin writing.
2215
2216 @type unpackedValue: int, long
2217 @param unpackedValue: Value to write.
2218
2219 @rtype: int
2220 @return: Number of bytes written.
2221 May be less than the number of bytes to write.
2222 """
2223 return self.__poke_c_type(lpBaseAddress, '@f', unpackedValue)
2224
2226 """
2227 Reads a double from the memory of the process.
2228
2229 @see: L{read_double}
2230
2231 @type lpBaseAddress: int
2232 @param lpBaseAddress: Memory address to begin reading.
2233
2234 @rtype: int
2235 @return: Integer value read from the process memory.
2236 Returns zero on error.
2237 """
2238 return self.__peek_c_type(lpBaseAddress, '@d', ctypes.c_double)
2239
2241 """
2242 Writes a double to the memory of the process.
2243
2244 @note: Page permissions may be changed temporarily while writing.
2245
2246 @see: L{write_double}
2247
2248 @type lpBaseAddress: int
2249 @param lpBaseAddress: Memory address to begin writing.
2250
2251 @type unpackedValue: int, long
2252 @param unpackedValue: Value to write.
2253
2254 @rtype: int
2255 @return: Number of bytes written.
2256 May be less than the number of bytes to write.
2257 """
2258 return self.__poke_c_type(lpBaseAddress, '@d', unpackedValue)
2259
2261 """
2262 Reads a DWORD from the memory of the process.
2263
2264 @see: L{read_dword}
2265
2266 @type lpBaseAddress: int
2267 @param lpBaseAddress: Memory address to begin reading.
2268
2269 @rtype: int
2270 @return: Integer value read from the process memory.
2271 Returns zero on error.
2272 """
2273 return self.__peek_c_type(lpBaseAddress, '=L', win32.DWORD)
2274
2275 - def poke_dword(self, lpBaseAddress, unpackedValue):
2276 """
2277 Writes a DWORD to the memory of the process.
2278
2279 @note: Page permissions may be changed temporarily while writing.
2280
2281 @see: L{write_dword}
2282
2283 @type lpBaseAddress: int
2284 @param lpBaseAddress: Memory address to begin writing.
2285
2286 @type unpackedValue: int, long
2287 @param unpackedValue: Value to write.
2288
2289 @rtype: int
2290 @return: Number of bytes written.
2291 May be less than the number of bytes to write.
2292 """
2293 return self.__poke_c_type(lpBaseAddress, '=L', unpackedValue)
2294
2296 """
2297 Reads a QWORD from the memory of the process.
2298
2299 @see: L{read_qword}
2300
2301 @type lpBaseAddress: int
2302 @param lpBaseAddress: Memory address to begin reading.
2303
2304 @rtype: int
2305 @return: Integer value read from the process memory.
2306 Returns zero on error.
2307 """
2308 return self.__peek_c_type(lpBaseAddress, '=Q', win32.QWORD)
2309
2310 - def poke_qword(self, lpBaseAddress, unpackedValue):
2311 """
2312 Writes a QWORD to the memory of the process.
2313
2314 @note: Page permissions may be changed temporarily while writing.
2315
2316 @see: L{write_qword}
2317
2318 @type lpBaseAddress: int
2319 @param lpBaseAddress: Memory address to begin writing.
2320
2321 @type unpackedValue: int, long
2322 @param unpackedValue: Value to write.
2323
2324 @rtype: int
2325 @return: Number of bytes written.
2326 May be less than the number of bytes to write.
2327 """
2328 return self.__poke_c_type(lpBaseAddress, '=Q', unpackedValue)
2329
2331 """
2332 Reads a pointer value from the memory of the process.
2333
2334 @see: L{read_pointer}
2335
2336 @type lpBaseAddress: int
2337 @param lpBaseAddress: Memory address to begin reading.
2338
2339 @rtype: int
2340 @return: Pointer value read from the process memory.
2341 Returns zero on error.
2342 """
2343 return self.__peek_c_type(lpBaseAddress, '@P', ctypes.c_void_p)
2344
2346 """
2347 Writes a pointer value to the memory of the process.
2348
2349 @note: Page permissions may be changed temporarily while writing.
2350
2351 @see: L{write_pointer}
2352
2353 @type lpBaseAddress: int
2354 @param lpBaseAddress: Memory address to begin writing.
2355
2356 @type unpackedValue: int, long
2357 @param unpackedValue: Value to write.
2358
2359 @rtype: int
2360 @return: Number of bytes written.
2361 May be less than the number of bytes to write.
2362 """
2363 return self.__poke_c_type(lpBaseAddress, '@P', unpackedValue)
2364
2365 - def peek_string(self, lpBaseAddress, fUnicode = False, dwMaxSize = 0x1000):
2366 """
2367 Tries to read an ASCII or Unicode string
2368 from the address space of the process.
2369
2370 @see: L{read_string}
2371
2372 @type lpBaseAddress: int
2373 @param lpBaseAddress: Memory address to begin reading.
2374
2375 @type fUnicode: bool
2376 @param fUnicode: C{True} is the string is expected to be Unicode,
2377 C{False} if it's expected to be ANSI.
2378
2379 @type dwMaxSize: int
2380 @param dwMaxSize: Maximum allowed string length to read, in bytes.
2381
2382 @rtype: str, unicode
2383 @return: String read from the process memory space.
2384 It B{doesn't} include the terminating null character.
2385 Returns an empty string on failure.
2386 """
2387
2388
2389 if not lpBaseAddress or dwMaxSize == 0:
2390 if fUnicode:
2391 return u''
2392 return ''
2393 if not dwMaxSize:
2394 dwMaxSize = 0x1000
2395
2396
2397 szString = self.peek(lpBaseAddress, dwMaxSize)
2398
2399
2400 if fUnicode:
2401
2402
2403 szString = unicode(szString, 'U16', 'replace')
2404
2405
2406
2407
2408
2409
2410
2411
2412 szString = szString[ : szString.find(u'\0') ]
2413
2414
2415 else:
2416
2417
2418 szString = szString[ : szString.find('\0') ]
2419
2420
2421 return szString
2422
2423
2424
2426 """
2427 Tries to guess which values in the given data are valid pointers,
2428 and reads some data from them.
2429
2430 @see: L{peek}
2431
2432 @type data: str
2433 @param data: Binary data to find pointers in.
2434
2435 @type peekSize: int
2436 @param peekSize: Number of bytes to read from each pointer found.
2437
2438 @type peekStep: int
2439 @param peekStep: Expected data alignment.
2440 Tipically you specify 1 when data alignment is unknown,
2441 or 4 when you expect data to be DWORD aligned.
2442 Any other value may be specified.
2443
2444 @rtype: dict( str S{->} str )
2445 @return: Dictionary mapping stack offsets to the data they point to.
2446 """
2447 result = dict()
2448 ptrSize = win32.sizeof(win32.LPVOID)
2449 if ptrSize == 4:
2450 ptrFmt = '<L'
2451 else:
2452 ptrFmt = '<Q'
2453 if len(data) > 0:
2454 for i in xrange(0, len(data), peekStep):
2455 packed = data[i:i+ptrSize]
2456 if len(packed) == ptrSize:
2457 address = struct.unpack(ptrFmt, packed)[0]
2458
2459 peek_data = self.peek(address, peekSize)
2460 if peek_data:
2461 result[i] = peek_data
2462 return result
2463
2464
2465
2466 - def malloc(self, dwSize, lpAddress = None):
2467 """
2468 Allocates memory into the address space of the process.
2469
2470 @see: L{free}
2471
2472 @type dwSize: int
2473 @param dwSize: Number of bytes to allocate.
2474
2475 @type lpAddress: int
2476 @param lpAddress: (Optional)
2477 Desired address for the newly allocated memory.
2478 This is only a hint, the memory could still be allocated somewhere
2479 else.
2480
2481 @rtype: int
2482 @return: Address of the newly allocated memory.
2483
2484 @raise WindowsError: On error an exception is raised.
2485 """
2486 hProcess = self.get_handle(win32.PROCESS_VM_OPERATION)
2487 return win32.VirtualAllocEx(hProcess, lpAddress, dwSize)
2488
2489 - def mprotect(self, lpAddress, dwSize, flNewProtect):
2490 """
2491 Set memory protection in the address space of the process.
2492
2493 @see: U{http://msdn.microsoft.com/en-us/library/aa366899.aspx}
2494
2495 @type lpAddress: int
2496 @param lpAddress: Address of memory to protect.
2497
2498 @type dwSize: int
2499 @param dwSize: Number of bytes to protect.
2500
2501 @type flNewProtect: int
2502 @param flNewProtect: New protect flags.
2503
2504 @rtype: int
2505 @return: Old protect flags.
2506
2507 @raise WindowsError: On error an exception is raised.
2508 """
2509 hProcess = self.get_handle(win32.PROCESS_VM_OPERATION)
2510 return win32.VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect)
2511
2512 - def mquery(self, lpAddress):
2513 """
2514 Query memory information from the address space of the process.
2515 Returns a L{win32.MemoryBasicInformation} object.
2516
2517 @see: U{http://msdn.microsoft.com/en-us/library/aa366907(VS.85).aspx}
2518
2519 @type lpAddress: int
2520 @param lpAddress: Address of memory to query.
2521
2522 @rtype: L{win32.MemoryBasicInformation}
2523 @return: Memory region information.
2524
2525 @raise WindowsError: On error an exception is raised.
2526 """
2527 hProcess = self.get_handle(win32.PROCESS_QUERY_INFORMATION)
2528 return win32.VirtualQueryEx(hProcess, lpAddress)
2529
2530 - def free(self, lpAddress):
2531 """
2532 Frees memory from the address space of the process.
2533
2534 @see: U{http://msdn.microsoft.com/en-us/library/aa366894(v=vs.85).aspx}
2535
2536 @type lpAddress: int
2537 @param lpAddress: Address of memory to free.
2538 Must be the base address returned by L{malloc}.
2539
2540 @raise WindowsError: On error an exception is raised.
2541 """
2542 hProcess = self.get_handle(win32.PROCESS_VM_OPERATION)
2543 win32.VirtualFreeEx(hProcess, lpAddress)
2544
2545
2546
2548 """
2549 Determines if an address is a valid code or data pointer.
2550
2551 That is, the address must be valid and must point to code or data in
2552 the target process.
2553
2554 @type address: int
2555 @param address: Memory address to query.
2556
2557 @rtype: bool
2558 @return: C{True} if the address is a valid code or data pointer.
2559
2560 @raise WindowsError: An exception is raised on error.
2561 """
2562 try:
2563 mbi = self.mquery(address)
2564 except WindowsError, e:
2565 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2566 return False
2567 raise
2568 return mbi.has_content()
2569
2571 """
2572 Determines if an address is a valid user mode address.
2573
2574 @type address: int
2575 @param address: Memory address to query.
2576
2577 @rtype: bool
2578 @return: C{True} if the address is a valid user mode address.
2579
2580 @raise WindowsError: An exception is raised on error.
2581 """
2582 try:
2583 mbi = self.mquery(address)
2584 except WindowsError, e:
2585 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2586 return False
2587 raise
2588 return True
2589
2591 """
2592 Determines if an address belongs to a free page.
2593
2594 @note: Returns always C{False} for kernel mode addresses.
2595
2596 @type address: int
2597 @param address: Memory address to query.
2598
2599 @rtype: bool
2600 @return: C{True} if the address belongs to a free page.
2601
2602 @raise WindowsError: An exception is raised on error.
2603 """
2604 try:
2605 mbi = self.mquery(address)
2606 except WindowsError, e:
2607 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2608 return False
2609 raise
2610 return mbi.is_free()
2611
2613 """
2614 Determines if an address belongs to a reserved page.
2615
2616 @note: Returns always C{False} for kernel mode addresses.
2617
2618 @type address: int
2619 @param address: Memory address to query.
2620
2621 @rtype: bool
2622 @return: C{True} if the address belongs to a reserved page.
2623
2624 @raise WindowsError: An exception is raised on error.
2625 """
2626 try:
2627 mbi = self.mquery(address)
2628 except WindowsError, e:
2629 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2630 return False
2631 raise
2632 return mbi.is_reserved()
2633
2635 """
2636 Determines if an address belongs to a commited page.
2637
2638 @note: Returns always C{False} for kernel mode addresses.
2639
2640 @type address: int
2641 @param address: Memory address to query.
2642
2643 @rtype: bool
2644 @return: C{True} if the address belongs to a commited page.
2645
2646 @raise WindowsError: An exception is raised on error.
2647 """
2648 try:
2649 mbi = self.mquery(address)
2650 except WindowsError, e:
2651 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2652 return False
2653 raise
2654 return mbi.is_commited()
2655
2657 """
2658 Determines if an address belongs to a guard page.
2659
2660 @note: Returns always C{False} for kernel mode addresses.
2661
2662 @type address: int
2663 @param address: Memory address to query.
2664
2665 @rtype: bool
2666 @return: C{True} if the address belongs to a guard page.
2667
2668 @raise WindowsError: An exception is raised on error.
2669 """
2670 try:
2671 mbi = self.mquery(address)
2672 except WindowsError, e:
2673 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2674 return False
2675 raise
2676 return mbi.is_guard()
2677
2679 """
2680 Determines if an address belongs to a commited and readable page.
2681 The page may or may not have additional permissions.
2682
2683 @note: Returns always C{False} for kernel mode addresses.
2684
2685 @type address: int
2686 @param address: Memory address to query.
2687
2688 @rtype: bool
2689 @return:
2690 C{True} if the address belongs to a commited and readable page.
2691
2692 @raise WindowsError: An exception is raised on error.
2693 """
2694 try:
2695 mbi = self.mquery(address)
2696 except WindowsError, e:
2697 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2698 return False
2699 raise
2700 return mbi.is_readable()
2701
2703 """
2704 Determines if an address belongs to a commited and writeable page.
2705 The page may or may not have additional permissions.
2706
2707 @note: Returns always C{False} for kernel mode addresses.
2708
2709 @type address: int
2710 @param address: Memory address to query.
2711
2712 @rtype: bool
2713 @return:
2714 C{True} if the address belongs to a commited and writeable page.
2715
2716 @raise WindowsError: An exception is raised on error.
2717 """
2718 try:
2719 mbi = self.mquery(address)
2720 except WindowsError, e:
2721 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2722 return False
2723 raise
2724 return mbi.is_writeable()
2725
2727 """
2728 Determines if an address belongs to a commited, copy-on-write page.
2729 The page may or may not have additional permissions.
2730
2731 @note: Returns always C{False} for kernel mode addresses.
2732
2733 @type address: int
2734 @param address: Memory address to query.
2735
2736 @rtype: bool
2737 @return:
2738 C{True} if the address belongs to a commited, copy-on-write page.
2739
2740 @raise WindowsError: An exception is raised on error.
2741 """
2742 try:
2743 mbi = self.mquery(address)
2744 except WindowsError, e:
2745 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2746 return False
2747 raise
2748 return mbi.is_copy_on_write()
2749
2751 """
2752 Determines if an address belongs to a commited and executable page.
2753 The page may or may not have additional permissions.
2754
2755 @note: Returns always C{False} for kernel mode addresses.
2756
2757 @type address: int
2758 @param address: Memory address to query.
2759
2760 @rtype: bool
2761 @return:
2762 C{True} if the address belongs to a commited and executable page.
2763
2764 @raise WindowsError: An exception is raised on error.
2765 """
2766 try:
2767 mbi = self.mquery(address)
2768 except WindowsError, e:
2769 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2770 return False
2771 raise
2772 return mbi.is_executable()
2773
2775 """
2776 Determines if an address belongs to a commited, writeable and
2777 executable page. The page may or may not have additional permissions.
2778
2779 Looking for writeable and executable pages is important when
2780 exploiting a software vulnerability.
2781
2782 @note: Returns always C{False} for kernel mode addresses.
2783
2784 @type address: int
2785 @param address: Memory address to query.
2786
2787 @rtype: bool
2788 @return:
2789 C{True} if the address belongs to a commited, writeable and
2790 executable page.
2791
2792 @raise WindowsError: An exception is raised on error.
2793 """
2794 try:
2795 mbi = self.mquery(address)
2796 except WindowsError, e:
2797 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2798 return False
2799 raise
2800 return mbi.is_executable_and_writeable()
2801
2803 """
2804 Determines if the given memory area is a valid code or data buffer.
2805
2806 @note: Returns always C{False} for kernel mode addresses.
2807
2808 @see: L{mquery}
2809
2810 @type address: int
2811 @param address: Memory address.
2812
2813 @type size: int
2814 @param size: Number of bytes. Must be greater than zero.
2815
2816 @rtype: bool
2817 @return: C{True} if the memory area is a valid code or data buffer,
2818 C{False} otherwise.
2819
2820 @raise ValueError: The size argument must be greater than zero.
2821 @raise WindowsError: On error an exception is raised.
2822 """
2823 if size <= 0:
2824 raise ValueError("The size argument must be greater than zero")
2825 while size > 0:
2826 try:
2827 mbi = self.mquery(address)
2828 except WindowsError, e:
2829 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2830 return False
2831 raise
2832 if not mbi.has_content():
2833 return False
2834 size = size - mbi.RegionSize
2835 return True
2836
2838 """
2839 Determines if the given memory area is readable.
2840
2841 @note: Returns always C{False} for kernel mode addresses.
2842
2843 @see: L{mquery}
2844
2845 @type address: int
2846 @param address: Memory address.
2847
2848 @type size: int
2849 @param size: Number of bytes. Must be greater than zero.
2850
2851 @rtype: bool
2852 @return: C{True} if the memory area is readable, C{False} otherwise.
2853
2854 @raise ValueError: The size argument must be greater than zero.
2855 @raise WindowsError: On error an exception is raised.
2856 """
2857 if size <= 0:
2858 raise ValueError("The size argument must be greater than zero")
2859 while size > 0:
2860 try:
2861 mbi = self.mquery(address)
2862 except WindowsError, e:
2863 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2864 return False
2865 raise
2866 if not mbi.is_readable():
2867 return False
2868 size = size - mbi.RegionSize
2869 return True
2870
2872 """
2873 Determines if the given memory area is writeable.
2874
2875 @note: Returns always C{False} for kernel mode addresses.
2876
2877 @see: L{mquery}
2878
2879 @type address: int
2880 @param address: Memory address.
2881
2882 @type size: int
2883 @param size: Number of bytes. Must be greater than zero.
2884
2885 @rtype: bool
2886 @return: C{True} if the memory area is writeable, C{False} otherwise.
2887
2888 @raise ValueError: The size argument must be greater than zero.
2889 @raise WindowsError: On error an exception is raised.
2890 """
2891 if size <= 0:
2892 raise ValueError("The size argument must be greater than zero")
2893 while size > 0:
2894 try:
2895 mbi = self.mquery(address)
2896 except WindowsError, e:
2897 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2898 return False
2899 raise
2900 if not mbi.is_writeable():
2901 return False
2902 size = size - mbi.RegionSize
2903 return True
2904
2906 """
2907 Determines if the given memory area is marked as copy-on-write.
2908
2909 @note: Returns always C{False} for kernel mode addresses.
2910
2911 @see: L{mquery}
2912
2913 @type address: int
2914 @param address: Memory address.
2915
2916 @type size: int
2917 @param size: Number of bytes. Must be greater than zero.
2918
2919 @rtype: bool
2920 @return: C{True} if the memory area is marked as copy-on-write,
2921 C{False} otherwise.
2922
2923 @raise ValueError: The size argument must be greater than zero.
2924 @raise WindowsError: On error an exception is raised.
2925 """
2926 if size <= 0:
2927 raise ValueError("The size argument must be greater than zero")
2928 while size > 0:
2929 try:
2930 mbi = self.mquery(address)
2931 except WindowsError, e:
2932 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2933 return False
2934 raise
2935 if not mbi.is_copy_on_write():
2936 return False
2937 size = size - mbi.RegionSize
2938 return True
2939
2941 """
2942 Determines if the given memory area is executable.
2943
2944 @note: Returns always C{False} for kernel mode addresses.
2945
2946 @see: L{mquery}
2947
2948 @type address: int
2949 @param address: Memory address.
2950
2951 @type size: int
2952 @param size: Number of bytes. Must be greater than zero.
2953
2954 @rtype: bool
2955 @return: C{True} if the memory area is executable, C{False} otherwise.
2956
2957 @raise ValueError: The size argument must be greater than zero.
2958 @raise WindowsError: On error an exception is raised.
2959 """
2960 if size <= 0:
2961 raise ValueError("The size argument must be greater than zero")
2962 while size > 0:
2963 try:
2964 mbi = self.mquery(address)
2965 except WindowsError, e:
2966 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2967 return False
2968 raise
2969 if not mbi.is_executable():
2970 return False
2971 size = size - mbi.RegionSize
2972 return True
2973
2975 """
2976 Determines if the given memory area is writeable and executable.
2977
2978 Looking for writeable and executable pages is important when
2979 exploiting a software vulnerability.
2980
2981 @note: Returns always C{False} for kernel mode addresses.
2982
2983 @see: L{mquery}
2984
2985 @type address: int
2986 @param address: Memory address.
2987
2988 @type size: int
2989 @param size: Number of bytes. Must be greater than zero.
2990
2991 @rtype: bool
2992 @return: C{True} if the memory area is writeable and executable,
2993 C{False} otherwise.
2994
2995 @raise ValueError: The size argument must be greater than zero.
2996 @raise WindowsError: On error an exception is raised.
2997 """
2998 if size <= 0:
2999 raise ValueError("The size argument must be greater than zero")
3000 while size > 0:
3001 try:
3002 mbi = self.mquery(address)
3003 except WindowsError, e:
3004 if e.winerror == win32.ERROR_INVALID_PARAMETER:
3005 return False
3006 raise
3007 if not mbi.is_executable():
3008 return False
3009 size = size - mbi.RegionSize
3010 return True
3011
3013 """
3014 Produces a memory map to the process address space.
3015
3016 Optionally restrict the map to the given address range.
3017
3018 @see: L{mquery}
3019
3020 @type minAddr: int
3021 @param minAddr: (Optional) Starting address in address range to query.
3022
3023 @type maxAddr: int
3024 @param maxAddr: (Optional) Ending address in address range to query.
3025
3026 @rtype: list( L{win32.MemoryBasicInformation} )
3027 @return: List of memory region information objects.
3028 """
3029 return list(self.iter_memory_map(minAddr, maxAddr))
3030
3032 """
3033 Returns a L{Regenerator} that can iterate indefinitely over the memory
3034 map to the process address space.
3035
3036 Optionally restrict the map to the given address range.
3037
3038 @see: L{mquery}
3039
3040 @type minAddr: int
3041 @param minAddr: (Optional) Starting address in address range to query.
3042
3043 @type maxAddr: int
3044 @param maxAddr: (Optional) Ending address in address range to query.
3045
3046 @rtype: L{Regenerator} of L{win32.MemoryBasicInformation}
3047 @return: List of memory region information objects.
3048 """
3049 return Regenerator(self.iter_memory_map, minAddr, maxAddr)
3050
3052 """
3053 Produces an iterator over the memory map to the process address space.
3054
3055 Optionally restrict the map to the given address range.
3056
3057 @see: L{mquery}
3058
3059 @type minAddr: int
3060 @param minAddr: (Optional) Starting address in address range to query.
3061
3062 @type maxAddr: int
3063 @param maxAddr: (Optional) Ending address in address range to query.
3064
3065 @rtype: iterator of L{win32.MemoryBasicInformation}
3066 @return: List of memory region information objects.
3067 """
3068 minAddr, maxAddr = MemoryAddresses.align_address_range(minAddr,maxAddr)
3069 prevAddr = minAddr - 1
3070 currentAddr = minAddr
3071 while prevAddr < currentAddr < maxAddr:
3072 try:
3073 mbi = self.mquery(currentAddr)
3074 except WindowsError, e:
3075 if e.winerror == win32.ERROR_INVALID_PARAMETER:
3076 break
3077 raise
3078 yield mbi
3079 prevAddr = currentAddr
3080 currentAddr = mbi.BaseAddress + mbi.RegionSize
3081
3083 """
3084 Retrieves the filenames for memory mapped files in the debugee.
3085
3086 @type memoryMap: list( L{win32.MemoryBasicInformation} )
3087 @param memoryMap: (Optional) Memory map returned by L{get_memory_map}.
3088 If not given, the current memory map is used.
3089
3090 @rtype: dict( int S{->} str )
3091 @return: Dictionary mapping memory addresses to file names.
3092 Native filenames are converted to Win32 filenames when possible.
3093 """
3094 hProcess = self.get_handle( win32.PROCESS_VM_READ |
3095 win32.PROCESS_QUERY_INFORMATION )
3096 if not memoryMap:
3097 memoryMap = self.get_memory_map()
3098 mappedFilenames = dict()
3099 for mbi in memoryMap:
3100 if mbi.Type not in (win32.MEM_IMAGE, win32.MEM_MAPPED):
3101 continue
3102 baseAddress = mbi.BaseAddress
3103 fileName = ""
3104 try:
3105 fileName = win32.GetMappedFileName(hProcess, baseAddress)
3106 fileName = PathOperations.native_to_win32_pathname(fileName)
3107 except WindowsError, e:
3108
3109
3110
3111
3112
3113
3114
3115 pass
3116 mappedFilenames[baseAddress] = fileName
3117 return mappedFilenames
3118
3120 """
3121 Returns a L{Regenerator} that allows you to iterate through the memory
3122 contents of a process indefinitely.
3123
3124 It's basically the same as the L{take_memory_snapshot} method, but it
3125 takes the snapshot of each memory region as it goes, as opposed to
3126 taking the whole snapshot at once. This allows you to work with very
3127 large snapshots without a significant performance penalty.
3128
3129 Example::
3130 # Print the memory contents of a process.
3131 process.suspend()
3132 try:
3133 snapshot = process.generate_memory_snapshot()
3134 for mbi in snapshot:
3135 print HexDump.hexblock(mbi.content, mbi.BaseAddress)
3136 finally:
3137 process.resume()
3138
3139 The downside of this is the process must remain suspended while
3140 iterating the snapshot, otherwise strange things may happen.
3141
3142 The snapshot can be iterated more than once. Each time it's iterated
3143 the memory contents of the process will be fetched again.
3144
3145 You can also iterate the memory of a dead process, just as long as the
3146 last open handle to it hasn't been closed.
3147
3148 @see: L{take_memory_snapshot}
3149
3150 @type minAddr: int
3151 @param minAddr: (Optional) Starting address in address range to query.
3152
3153 @type maxAddr: int
3154 @param maxAddr: (Optional) Ending address in address range to query.
3155
3156 @rtype: L{Regenerator} of L{win32.MemoryBasicInformation}
3157 @return: Generator that when iterated returns memory region information
3158 objects. Two extra properties are added to these objects:
3159 - C{filename}: Mapped filename, or C{None}.
3160 - C{content}: Memory contents, or C{None}.
3161 """
3162 return Regenerator(self.iter_memory_snapshot, minAddr, maxAddr)
3163
3165 """
3166 Returns an iterator that allows you to go through the memory contents
3167 of a process.
3168
3169 It's basically the same as the L{take_memory_snapshot} method, but it
3170 takes the snapshot of each memory region as it goes, as opposed to
3171 taking the whole snapshot at once. This allows you to work with very
3172 large snapshots without a significant performance penalty.
3173
3174 Example::
3175 # Print the memory contents of a process.
3176 process.suspend()
3177 try:
3178 snapshot = process.generate_memory_snapshot()
3179 for mbi in snapshot:
3180 print HexDump.hexblock(mbi.content, mbi.BaseAddress)
3181 finally:
3182 process.resume()
3183
3184 The downside of this is the process must remain suspended while
3185 iterating the snapshot, otherwise strange things may happen.
3186
3187 The snapshot can only iterated once. To be able to iterate indefinitely
3188 call the L{generate_memory_snapshot} method instead.
3189
3190 You can also iterate the memory of a dead process, just as long as the
3191 last open handle to it hasn't been closed.
3192
3193 @see: L{take_memory_snapshot}
3194
3195 @type minAddr: int
3196 @param minAddr: (Optional) Starting address in address range to query.
3197
3198 @type maxAddr: int
3199 @param maxAddr: (Optional) Ending address in address range to query.
3200
3201 @rtype: iterator of L{win32.MemoryBasicInformation}
3202 @return: Iterator of memory region information objects.
3203 Two extra properties are added to these objects:
3204 - C{filename}: Mapped filename, or C{None}.
3205 - C{content}: Memory contents, or C{None}.
3206 """
3207
3208
3209
3210
3211
3212
3213
3214
3215 memory = self.get_memory_map(minAddr, maxAddr)
3216
3217
3218 if not memory:
3219 return
3220
3221
3222
3223 try:
3224 filenames = self.get_mapped_filenames(memory)
3225 except WindowsError, e:
3226 if e.winerror != win32.ERROR_ACCESS_DENIED:
3227 raise
3228 filenames = dict()
3229
3230
3231 if minAddr is not None:
3232 minAddr = MemoryAddresses.align_address_to_page_start(minAddr)
3233 mbi = memory[0]
3234 if mbi.BaseAddress < minAddr:
3235 mbi.RegionSize = mbi.BaseAddress + mbi.RegionSize - minAddr
3236 mbi.BaseAddress = minAddr
3237
3238
3239 if maxAddr is not None:
3240 if maxAddr != MemoryAddresses.align_address_to_page_start(maxAddr):
3241 maxAddr = MemoryAddresses.align_address_to_page_end(maxAddr)
3242 mbi = memory[-1]
3243 if mbi.BaseAddress + mbi.RegionSize > maxAddr:
3244 mbi.RegionSize = maxAddr - mbi.BaseAddress
3245
3246
3247 while memory:
3248 mbi = memory.pop(0)
3249 mbi.filename = filenames.get(mbi.BaseAddress, None)
3250 if mbi.has_content():
3251 mbi.content = self.read(mbi.BaseAddress, mbi.RegionSize)
3252 else:
3253 mbi.content = None
3254 yield mbi
3255
3257 """
3258 Takes a snapshot of the memory contents of the process.
3259
3260 It's best if the process is suspended (if alive) when taking the
3261 snapshot. Execution can be resumed afterwards.
3262
3263 Example::
3264 # Print the memory contents of a process.
3265 process.suspend()
3266 try:
3267 snapshot = process.take_memory_snapshot()
3268 for mbi in snapshot:
3269 print HexDump.hexblock(mbi.content, mbi.BaseAddress)
3270 finally:
3271 process.resume()
3272
3273 You can also iterate the memory of a dead process, just as long as the
3274 last open handle to it hasn't been closed.
3275
3276 @warning: If the target process has a very big memory footprint, the
3277 resulting snapshot will be equally big. This may result in a severe
3278 performance penalty.
3279
3280 @see: L{generate_memory_snapshot}
3281
3282 @type minAddr: int
3283 @param minAddr: (Optional) Starting address in address range to query.
3284
3285 @type maxAddr: int
3286 @param maxAddr: (Optional) Ending address in address range to query.
3287
3288 @rtype: list( L{win32.MemoryBasicInformation} )
3289 @return: List of memory region information objects.
3290 Two extra properties are added to these objects:
3291 - C{filename}: Mapped filename, or C{None}.
3292 - C{content}: Memory contents, or C{None}.
3293 """
3294 return list( self.iter_memory_snapshot(minAddr, maxAddr) )
3295
3299 """
3300 Attempts to restore the memory state as it was when the given snapshot
3301 was taken.
3302
3303 @warning: Currently only the memory contents, state and protect bits
3304 are restored. Under some circumstances this method may fail (for
3305 example if memory was freed and then reused by a mapped file).
3306
3307 @type snapshot: list( L{win32.MemoryBasicInformation} )
3308 @param snapshot: Memory snapshot returned by L{take_memory_snapshot}.
3309 Snapshots returned by L{generate_memory_snapshot} don't work here.
3310
3311 @type bSkipMappedFiles: bool
3312 @param bSkipMappedFiles: C{True} to avoid restoring the contents of
3313 memory mapped files, C{False} otherwise. Use with care! Setting
3314 this to C{False} can cause undesired side effects - changes to
3315 memory mapped files may be written to disk by the OS. Also note
3316 that most mapped files are typically executables and don't change,
3317 so trying to restore their contents is usually a waste of time.
3318
3319 @type bSkipOnError: bool
3320 @param bSkipOnError: C{True} to issue a warning when an error occurs
3321 during the restoration of the snapshot, C{False} to stop and raise
3322 an exception instead. Use with care! Setting this to C{True} will
3323 cause the debugger to falsely believe the memory snapshot has been
3324 correctly restored.
3325
3326 @raise WindowsError: An error occured while restoring the snapshot.
3327 @raise RuntimeError: An error occured while restoring the snapshot.
3328 @raise TypeError: A snapshot of the wrong type was passed.
3329 """
3330 if not snapshot or not isinstance(snapshot, list) \
3331 or not isinstance(snapshot[0], win32.MemoryBasicInformation):
3332 raise TypeError( "Only snapshots returned by " \
3333 "take_memory_snapshot() can be used here." )
3334
3335
3336 hProcess = self.get_handle( win32.PROCESS_VM_WRITE |
3337 win32.PROCESS_VM_OPERATION |
3338 win32.PROCESS_SUSPEND_RESUME |
3339 win32.PROCESS_QUERY_INFORMATION )
3340
3341
3342 self.suspend()
3343 try:
3344
3345
3346 for old_mbi in snapshot:
3347
3348
3349 new_mbi = self.mquery(old_mbi.BaseAddress)
3350 if new_mbi.BaseAddress == old_mbi.BaseAddress and \
3351 new_mbi.RegionSize == old_mbi.RegionSize:
3352 self.__restore_mbi(hProcess, new_mbi, old_mbi,
3353 bSkipMappedFiles)
3354
3355
3356 else:
3357
3358
3359 old_mbi = win32.MemoryBasicInformation(old_mbi)
3360
3361
3362 old_start = old_mbi.BaseAddress
3363 old_end = old_start + old_mbi.RegionSize
3364 new_start = new_mbi.BaseAddress
3365 new_end = new_start + new_mbi.RegionSize
3366 if old_start > new_start:
3367 start = old_start
3368 else:
3369 start = new_start
3370 if old_end < new_end:
3371 end = old_end
3372 else:
3373 end = new_end
3374
3375
3376 step = MemoryAddresses.pageSize
3377 old_mbi.RegionSize = step
3378 new_mbi.RegionSize = step
3379 address = start
3380 while address < end:
3381 old_mbi.BaseAddress = address
3382 new_mbi.BaseAddress = address
3383 self.__restore_mbi(hProcess, new_mbi, old_mbi,
3384 bSkipMappedFiles, bSkipOnError)
3385 address = address + step
3386
3387
3388 finally:
3389 self.resume()
3390
3391 - def __restore_mbi(self, hProcess, new_mbi, old_mbi, bSkipMappedFiles,
3392 bSkipOnError):
3393 """
3394 Used internally by L{restore_memory_snapshot}.
3395 """
3396
3397
3398
3399
3400
3401
3402 try:
3403
3404
3405 if new_mbi.State != old_mbi.State:
3406 if new_mbi.is_free():
3407 if old_mbi.is_reserved():
3408
3409
3410 address = win32.VirtualAllocEx(hProcess,
3411 old_mbi.BaseAddress,
3412 old_mbi.RegionSize,
3413 win32.MEM_RESERVE,
3414 old_mbi.Protect)
3415 if address != old_mbi.BaseAddress:
3416 self.free(address)
3417 msg = "Error restoring region at address %s"
3418 msg = msg % HexDump(old_mbi.BaseAddress,
3419 self.get_bits())
3420 raise RuntimeError(msg)
3421
3422 new_mbi.Protect = old_mbi.Protect
3423
3424 else:
3425
3426
3427 address = win32.VirtualAllocEx(hProcess,
3428 old_mbi.BaseAddress,
3429 old_mbi.RegionSize,
3430 win32.MEM_RESERVE | \
3431 win32.MEM_COMMIT,
3432 old_mbi.Protect)
3433 if address != old_mbi.BaseAddress:
3434 self.free(address)
3435 msg = "Error restoring region at address %s"
3436 msg = msg % HexDump(old_mbi.BaseAddress,
3437 self.get_bits())
3438 raise RuntimeError(msg)
3439
3440 new_mbi.Protect = old_mbi.Protect
3441
3442 elif new_mbi.is_reserved():
3443 if old_mbi.is_commited():
3444
3445
3446 address = win32.VirtualAllocEx(hProcess,
3447 old_mbi.BaseAddress,
3448 old_mbi.RegionSize,
3449 win32.MEM_COMMIT,
3450 old_mbi.Protect)
3451 if address != old_mbi.BaseAddress:
3452 self.free(address)
3453 msg = "Error restoring region at address %s"
3454 msg = msg % HexDump(old_mbi.BaseAddress,
3455 self.get_bits())
3456 raise RuntimeError(msg)
3457
3458 new_mbi.Protect = old_mbi.Protect
3459
3460 else:
3461
3462
3463 win32.VirtualFreeEx(hProcess,
3464 old_mbi.BaseAddress,
3465 old_mbi.RegionSize,
3466 win32.MEM_RELEASE)
3467
3468 else:
3469 if old_mbi.is_reserved():
3470
3471
3472 win32.VirtualFreeEx(hProcess,
3473 old_mbi.BaseAddress,
3474 old_mbi.RegionSize,
3475 win32.MEM_DECOMMIT)
3476
3477 else:
3478
3479
3480 win32.VirtualFreeEx(hProcess,
3481 old_mbi.BaseAddress,
3482 old_mbi.RegionSize,
3483 win32.MEM_DECOMMIT | win32.MEM_RELEASE)
3484
3485 new_mbi.State = old_mbi.State
3486
3487
3488 if old_mbi.is_commited() and old_mbi.Protect != new_mbi.Protect:
3489 win32.VirtualProtectEx(hProcess, old_mbi.BaseAddress,
3490 old_mbi.RegionSize, old_mbi.Protect)
3491 new_mbi.Protect = old_mbi.Protect
3492
3493
3494
3495 if old_mbi.has_content():
3496 if old_mbi.Type != 0:
3497 if not bSkipMappedFiles:
3498 self.poke(old_mbi.BaseAddress, old_mbi.content)
3499 else:
3500 self.write(old_mbi.BaseAddress, old_mbi.content)
3501 new_mbi.content = old_mbi.content
3502
3503
3504 except Exception:
3505 if not bSkipOnError:
3506 raise
3507 msg = "Error restoring region at address %s: %s"
3508 msg = msg % (
3509 HexDump(old_mbi.BaseAddress, self.get_bits()),
3510 traceback.format_exc())
3511 warnings.warn(msg, RuntimeWarning)
3512
3513
3514
3516 """
3517 Injects relocatable code into the process memory and executes it.
3518
3519 @warning: Don't forget to free the memory when you're done with it!
3520 Otherwise you'll be leaking memory in the target process.
3521
3522 @see: L{inject_dll}
3523
3524 @type payload: str
3525 @param payload: Relocatable code to run in a new thread.
3526
3527 @type lpParameter: int
3528 @param lpParameter: (Optional) Parameter to be pushed in the stack.
3529
3530 @rtype: tuple( L{Thread}, int )
3531 @return: The injected Thread object
3532 and the memory address where the code was written.
3533
3534 @raise WindowsError: An exception is raised on error.
3535 """
3536
3537
3538
3539
3540
3541 lpStartAddress = self.malloc(len(payload))
3542
3543
3544 try:
3545
3546
3547 self.write(lpStartAddress, payload)
3548
3549
3550 aThread = self.start_thread(lpStartAddress, lpParameter,
3551 bSuspended = False)
3552
3553
3554
3555
3556
3557
3558 aThread.pInjectedMemory = lpStartAddress
3559
3560
3561 except Exception, e:
3562 self.free(lpStartAddress)
3563 raise
3564
3565
3566 return aThread, lpStartAddress
3567
3568
3569
3570
3571
3572 - def inject_dll(self, dllname, procname = None, lpParameter = 0,
3573 bWait = True, dwTimeout = None):
3574 """
3575 Injects a DLL into the process memory.
3576
3577 @warning: Setting C{bWait} to C{True} when the process is frozen by a
3578 debug event will cause a deadlock in your debugger.
3579
3580 @warning: This involves allocating memory in the target process.
3581 This is how the freeing of this memory is handled:
3582
3583 - If the C{bWait} flag is set to C{True} the memory will be freed
3584 automatically before returning from this method.
3585 - If the C{bWait} flag is set to C{False}, the memory address is
3586 set as the L{Thread.pInjectedMemory} property of the returned
3587 thread object.
3588 - L{Debug} objects free L{Thread.pInjectedMemory} automatically
3589 both when it detaches from a process and when the injected
3590 thread finishes its execution.
3591 - The {Thread.kill} method also frees L{Thread.pInjectedMemory}
3592 automatically, even if you're not attached to the process.
3593
3594 You could still be leaking memory if not careful. For example, if
3595 you inject a dll into a process you're not attached to, you don't
3596 wait for the thread's completion and you don't kill it either, the
3597 memory would be leaked.
3598
3599 @see: L{inject_code}
3600
3601 @type dllname: str
3602 @param dllname: Name of the DLL module to load.
3603
3604 @type procname: str
3605 @param procname: (Optional) Procedure to call when the DLL is loaded.
3606
3607 @type lpParameter: int
3608 @param lpParameter: (Optional) Parameter to the C{procname} procedure.
3609
3610 @type bWait: bool
3611 @param bWait: C{True} to wait for the process to finish.
3612 C{False} to return immediately.
3613
3614 @type dwTimeout: int
3615 @param dwTimeout: (Optional) Timeout value in milliseconds.
3616 Ignored if C{bWait} is C{False}.
3617
3618 @rtype: L{Thread}
3619 @return: Newly created thread object. If C{bWait} is set to C{True} the
3620 thread will be dead, otherwise it will be alive.
3621
3622 @raise NotImplementedError: The target platform is not supported.
3623 Currently calling a procedure in the library is only supported in
3624 the I{i386} architecture.
3625
3626 @raise WindowsError: An exception is raised on error.
3627 """
3628
3629
3630 aModule = self.get_module_by_name('kernel32.dll')
3631 if aModule is None:
3632 self.scan_modules()
3633 aModule = self.get_module_by_name('kernel32.dll')
3634 if aModule is None:
3635 raise RuntimeError(
3636 "Cannot resolve kernel32.dll in the remote process")
3637
3638
3639 if procname:
3640 if self.get_arch() != win32.ARCH_I386:
3641 raise NotImplementedError()
3642 dllname = str(dllname)
3643
3644
3645 pllib = aModule.resolve('LoadLibraryA')
3646 if not pllib:
3647 raise RuntimeError(
3648 "Cannot resolve kernel32.dll!LoadLibraryA"
3649 " in the remote process")
3650
3651
3652 pgpad = aModule.resolve('GetProcAddress')
3653 if not pgpad:
3654 raise RuntimeError(
3655 "Cannot resolve kernel32.dll!GetProcAddress"
3656 " in the remote process")
3657
3658
3659 pvf = aModule.resolve('VirtualFree')
3660 if not pvf:
3661 raise RuntimeError(
3662 "Cannot resolve kernel32.dll!VirtualFree"
3663 " in the remote process")
3664
3665
3666 code = ''.encode('latin1')
3667
3668
3669 code += '\xe8' + struct.pack('<L', len(dllname) + 1) + dllname + '\0'
3670
3671
3672 code += '\xb8' + struct.pack('<L', pllib)
3673
3674
3675 code += '\xff\xd0'
3676
3677 if procname:
3678
3679
3680 code += '\xe8' + struct.pack('<L', len(procname) + 1)
3681 code += procname + '\0'
3682
3683
3684 code += '\x50'
3685
3686
3687 code += '\xb8' + struct.pack('<L', pgpad)
3688
3689
3690 code += '\xff\xd0'
3691
3692
3693 code += '\x8b\xec'
3694
3695
3696 code += '\x68' + struct.pack('<L', lpParameter)
3697
3698
3699 code += '\xff\xd0'
3700
3701
3702 code += '\x8b\xe5'
3703
3704
3705 code += '\x5a'
3706
3707
3708 code += '\x68' + struct.pack('<L', win32.MEM_RELEASE)
3709
3710
3711 code += '\x68' + struct.pack('<L', 0x1000)
3712
3713
3714 code += '\xe8\x00\x00\x00\x00'
3715
3716
3717 code += '\x81\x24\x24\x00\xf0\xff\xff'
3718
3719
3720 code += '\xb8' + struct.pack('<L', pvf)
3721
3722
3723 code += '\x52'
3724
3725
3726 code += '\xff\xe0'
3727
3728
3729
3730
3731 aThread, lpStartAddress = self.inject_code(code, lpParameter)
3732
3733
3734 else:
3735
3736
3737 if type(dllname) == type(u''):
3738 pllibname = 'LoadLibraryW'
3739 bufferlen = (len(dllname) + 1) * 2
3740 dllname = win32.ctypes.create_unicode_buffer(dllname).raw[:bufferlen + 1]
3741 else:
3742 pllibname = 'LoadLibraryA'
3743 dllname = str(dllname) + '\x00'
3744 bufferlen = len(dllname)
3745 pllib = aModule.resolve(pllibname)
3746 if not pllib:
3747 msg = "Cannot resolve kernel32.dll!%s in the remote process"
3748 raise RuntimeError(msg % pllibname)
3749
3750
3751 pbuffer = self.malloc(bufferlen)
3752 try:
3753 self.write(pbuffer, dllname)
3754
3755
3756 try:
3757 aThread = self.start_thread(pllib, pbuffer)
3758 except WindowsError, e:
3759 if e.winerror != win32.ERROR_NOT_ENOUGH_MEMORY:
3760 raise
3761
3762
3763
3764
3765 raise NotImplementedError(
3766 "Target process belongs to a different"
3767 " Terminal Services session, cannot inject!"
3768 )
3769
3770
3771
3772
3773
3774 aThread.pInjectedMemory = pbuffer
3775
3776
3777 except Exception:
3778 self.free(pbuffer)
3779 raise
3780
3781
3782 if bWait:
3783 aThread.wait(dwTimeout)
3784 self.free(aThread.pInjectedMemory)
3785 del aThread.pInjectedMemory
3786
3787
3788 return aThread
3789
3790 - def clean_exit(self, dwExitCode = 0, bWait = False, dwTimeout = None):
3791 """
3792 Injects a new thread to call ExitProcess().
3793 Optionally waits for the injected thread to finish.
3794
3795 @warning: Setting C{bWait} to C{True} when the process is frozen by a
3796 debug event will cause a deadlock in your debugger.
3797
3798 @type dwExitCode: int
3799 @param dwExitCode: Process exit code.
3800
3801 @type bWait: bool
3802 @param bWait: C{True} to wait for the process to finish.
3803 C{False} to return immediately.
3804
3805 @type dwTimeout: int
3806 @param dwTimeout: (Optional) Timeout value in milliseconds.
3807 Ignored if C{bWait} is C{False}.
3808
3809 @raise WindowsError: An exception is raised on error.
3810 """
3811 if not dwExitCode:
3812 dwExitCode = 0
3813 pExitProcess = self.resolve_label('kernel32!ExitProcess')
3814 aThread = self.start_thread(pExitProcess, dwExitCode)
3815 if bWait:
3816 aThread.wait(dwTimeout)
3817
3818
3819
3821 """
3822 Notify the creation of a new process.
3823
3824 This is done automatically by the L{Debug} class, you shouldn't need
3825 to call it yourself.
3826
3827 @type event: L{CreateProcessEvent}
3828 @param event: Create process event.
3829
3830 @rtype: bool
3831 @return: C{True} to call the user-defined handle, C{False} otherwise.
3832 """
3833
3834 bCallHandler = _ThreadContainer._notify_create_process(self, event)
3835 bCallHandler = bCallHandler and \
3836 _ModuleContainer._notify_create_process(self, event)
3837 return bCallHandler
3838
3842 """
3843 Encapsulates the capability to contain Process objects.
3844
3845 @group Instrumentation:
3846 start_process, argv_to_cmdline, cmdline_to_argv, get_explorer_pid
3847
3848 @group Processes snapshot:
3849 scan, scan_processes, scan_processes_fast,
3850 get_process, get_process_count, get_process_ids,
3851 has_process, iter_processes, iter_process_ids,
3852 find_processes_by_filename, get_pid_from_tid,
3853 get_windows,
3854 scan_process_filenames,
3855 clear, clear_processes, clear_dead_processes,
3856 clear_unattached_processes,
3857 close_process_handles,
3858 close_process_and_thread_handles
3859
3860 @group Threads snapshots:
3861 scan_processes_and_threads,
3862 get_thread, get_thread_count, get_thread_ids,
3863 has_thread
3864
3865 @group Modules snapshots:
3866 scan_modules, find_modules_by_address,
3867 find_modules_by_base, find_modules_by_name,
3868 get_module_count
3869 """
3870
3872 self.__processDict = dict()
3873
3875 """
3876 Private method to automatically initialize the snapshot
3877 when you try to use it without calling any of the scan_*
3878 methods first. You don't need to call this yourself.
3879 """
3880 if not self.__processDict:
3881 try:
3882 self.scan_processes()
3883 except Exception:
3884 self.scan_processes_fast()
3885 self.scan_process_filenames()
3886
3888 """
3889 @type anObject: L{Process}, L{Thread}, int
3890 @param anObject:
3891 - C{int}: Global ID of the process to look for.
3892 - C{int}: Global ID of the thread to look for.
3893 - C{Process}: Process object to look for.
3894 - C{Thread}: Thread object to look for.
3895
3896 @rtype: bool
3897 @return: C{True} if the snapshot contains
3898 a L{Process} or L{Thread} object with the same ID.
3899 """
3900 if isinstance(anObject, Process):
3901 anObject = anObject.dwProcessId
3902 if self.has_process(anObject):
3903 return True
3904 for aProcess in self.iter_processes():
3905 if anObject in aProcess:
3906 return True
3907 return False
3908
3910 """
3911 @see: L{iter_processes}
3912 @rtype: dictionary-valueiterator
3913 @return: Iterator of L{Process} objects in this snapshot.
3914 """
3915 return self.iter_processes()
3916
3918 """
3919 @see: L{get_process_count}
3920 @rtype: int
3921 @return: Count of L{Process} objects in this snapshot.
3922 """
3923 return self.get_process_count()
3924
3926 """
3927 @type dwProcessId: int
3928 @param dwProcessId: Global ID of the process to look for.
3929
3930 @rtype: bool
3931 @return: C{True} if the snapshot contains a
3932 L{Process} object with the given global ID.
3933 """
3934 self.__initialize_snapshot()
3935 return dwProcessId in self.__processDict
3936
3938 """
3939 @type dwProcessId: int
3940 @param dwProcessId: Global ID of the process to look for.
3941
3942 @rtype: L{Process}
3943 @return: Process object with the given global ID.
3944 """
3945 self.__initialize_snapshot()
3946 if dwProcessId not in self.__processDict:
3947 msg = "Unknown process ID %d" % dwProcessId
3948 raise KeyError(msg)
3949 return self.__processDict[dwProcessId]
3950
3952 """
3953 @see: L{iter_processes}
3954 @rtype: dictionary-keyiterator
3955 @return: Iterator of global process IDs in this snapshot.
3956 """
3957 self.__initialize_snapshot()
3958 return self.__processDict.iterkeys()
3959
3961 """
3962 @see: L{iter_process_ids}
3963 @rtype: dictionary-valueiterator
3964 @return: Iterator of L{Process} objects in this snapshot.
3965 """
3966 self.__initialize_snapshot()
3967 return self.__processDict.itervalues()
3968
3970 """
3971 @see: L{iter_process_ids}
3972 @rtype: list( int )
3973 @return: List of global process IDs in this snapshot.
3974 """
3975 self.__initialize_snapshot()
3976 return self.__processDict.keys()
3977
3979 """
3980 @rtype: int
3981 @return: Count of L{Process} objects in this snapshot.
3982 """
3983 self.__initialize_snapshot()
3984 return len(self.__processDict)
3985
3986
3987
3988
3989
3990
3992 """
3993 @rtype: list of L{Window}
3994 @return: Returns a list of windows
3995 handled by all processes in this snapshot.
3996 """
3997 window_list = list()
3998 for process in self.iter_processes():
3999 window_list.extend( process.get_windows() )
4000 return window_list
4001
4056
4057
4058
4059 @staticmethod
4061 """
4062 Convert a list of arguments to a single command line string.
4063
4064 @type argv: list( str )
4065 @param argv: List of argument strings.
4066 The first element is the program to execute.
4067
4068 @rtype: str
4069 @return: Command line string.
4070 """
4071 cmdline = list()
4072 for token in argv:
4073 if not token:
4074 token = '""'
4075 else:
4076 if '"' in token:
4077 token = token.replace('"', '\\"')
4078 if ' ' in token or \
4079 '\t' in token or \
4080 '\n' in token or \
4081 '\r' in token:
4082 token = '"%s"' % token
4083 cmdline.append(token)
4084 return ' '.join(cmdline)
4085
4086 @staticmethod
4088 """
4089 Convert a single command line string to a list of arguments.
4090
4091 @type lpCmdLine: str
4092 @param lpCmdLine: Command line string.
4093 The first token is the program to execute.
4094
4095 @rtype: list( str )
4096 @return: List of argument strings.
4097 """
4098 if not lpCmdLine:
4099 return []
4100 return win32.CommandLineToArgv(lpCmdLine)
4101
4103 """
4104 Starts a new process for instrumenting (or debugging).
4105
4106 @type lpCmdLine: str
4107 @param lpCmdLine: Command line to execute. Can't be an empty string.
4108
4109 @type bConsole: bool
4110 @keyword bConsole: True to inherit the console of the debugger.
4111 Defaults to C{False}.
4112
4113 @type bDebug: bool
4114 @keyword bDebug: C{True} to attach to the new process.
4115 To debug a process it's best to use the L{Debug} class instead.
4116 Defaults to C{False}.
4117
4118 @type bFollow: bool
4119 @keyword bFollow: C{True} to automatically attach to the child
4120 processes of the newly created process. Ignored unless C{bDebug} is
4121 C{True}. Defaults to C{False}.
4122
4123 @type bInheritHandles: bool
4124 @keyword bInheritHandles: C{True} if the new process should inherit
4125 it's parent process' handles. Defaults to C{False}.
4126
4127 @type bSuspended: bool
4128 @keyword bSuspended: C{True} to suspend the main thread before any code
4129 is executed in the debugee. Defaults to C{False}.
4130
4131 @type dwParentProcessId: int or None
4132 @keyword dwParentProcessId: C{None} if the debugger process should be
4133 the parent process (default), or a process ID to forcefully set as
4134 the debugee's parent (only available for Windows Vista and above).
4135
4136 @type iTrustLevel: int
4137 @keyword iTrustLevel: Trust level.
4138 Must be one of the following values:
4139 - 0: B{No trust}. May not access certain resources, such as
4140 cryptographic keys and credentials. Only available since
4141 Windows XP and 2003, desktop editions.
4142 - 1: B{Normal trust}. Run with the same privileges as a normal
4143 user, that is, one that doesn't have the I{Administrator} or
4144 I{Power User} user rights. Only available since Windows XP
4145 and 2003, desktop editions.
4146 - 2: B{Full trust}. Run with the exact same privileges as the
4147 current user. This is the default value.
4148
4149 @type bAllowElevation: bool
4150 @keyword bAllowElevation: C{True} to allow the child process to keep
4151 UAC elevation, if the debugger itself is running elevated. C{False}
4152 to ensure the child process doesn't run with elevation. Defaults to
4153 C{True}.
4154
4155 This flag is only meaningful on Windows Vista and above, and if the
4156 debugger itself is running with elevation. It can be used to make
4157 sure the child processes don't run elevated as well.
4158
4159 This flag DOES NOT force an elevation prompt when the debugger is
4160 not running with elevation.
4161
4162 Note that running the debugger with elevation (or the Python
4163 interpreter at all for that matter) is not normally required.
4164 You should only need to if the target program requires elevation
4165 to work properly (for example if you try to debug an installer).
4166
4167 @rtype: L{Process}
4168 @return: Process object.
4169 """
4170
4171
4172 bConsole = kwargs.pop('bConsole', False)
4173 bDebug = kwargs.pop('bDebug', False)
4174 bFollow = kwargs.pop('bFollow', False)
4175 bSuspended = kwargs.pop('bSuspended', False)
4176 bInheritHandles = kwargs.pop('bInheritHandles', False)
4177 dwParentProcessId = kwargs.pop('dwParentProcessId', None)
4178 iTrustLevel = kwargs.pop('iTrustLevel', 2)
4179 bAllowElevation = kwargs.pop('bAllowElevation', True)
4180 if kwargs:
4181 raise TypeError("Unknown keyword arguments: %s" % kwargs.keys())
4182 if not lpCmdLine:
4183 raise ValueError("Missing command line to execute!")
4184
4185
4186 if iTrustLevel is None:
4187 iTrustLevel = 2
4188
4189
4190 try:
4191 bAllowElevation = bAllowElevation or not self.is_admin()
4192 except AttributeError:
4193 bAllowElevation = True
4194 warnings.warn(
4195 "UAC elevation is only available in Windows Vista and above",
4196 RuntimeWarning)
4197
4198
4199 dwCreationFlags = 0
4200 dwCreationFlags |= win32.CREATE_DEFAULT_ERROR_MODE
4201 dwCreationFlags |= win32.CREATE_BREAKAWAY_FROM_JOB
4202
4203 if not bConsole:
4204 dwCreationFlags |= win32.DETACHED_PROCESS
4205
4206 if bSuspended:
4207 dwCreationFlags |= win32.CREATE_SUSPENDED
4208 if bDebug:
4209 dwCreationFlags |= win32.DEBUG_PROCESS
4210 if not bFollow:
4211 dwCreationFlags |= win32.DEBUG_ONLY_THIS_PROCESS
4212
4213
4214
4215 lpStartupInfo = None
4216 if dwParentProcessId is not None:
4217 myPID = win32.GetCurrentProcessId()
4218 if dwParentProcessId != myPID:
4219 if self.has_process(dwParentProcessId):
4220 ParentProcess = self.get_process(dwParentProcessId)
4221 else:
4222 ParentProcess = Process(dwParentProcessId)
4223 ParentProcessHandle = ParentProcess.get_handle(
4224 win32.PROCESS_CREATE_PROCESS)
4225 AttributeListData = (
4226 (
4227 win32.PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
4228 ParentProcessHandle._as_parameter_
4229 ),
4230 )
4231 AttributeList = win32.ProcThreadAttributeList(AttributeListData)
4232 StartupInfoEx = win32.STARTUPINFOEX()
4233 StartupInfo = StartupInfoEx.StartupInfo
4234 StartupInfo.cb = win32.sizeof(win32.STARTUPINFOEX)
4235 StartupInfo.lpReserved = 0
4236 StartupInfo.lpDesktop = 0
4237 StartupInfo.lpTitle = 0
4238 StartupInfo.dwFlags = 0
4239 StartupInfo.cbReserved2 = 0
4240 StartupInfo.lpReserved2 = 0
4241 StartupInfoEx.lpAttributeList = AttributeList.value
4242 lpStartupInfo = StartupInfoEx
4243 dwCreationFlags |= win32.EXTENDED_STARTUPINFO_PRESENT
4244
4245 pi = None
4246 try:
4247
4248
4249 if iTrustLevel >= 2 and bAllowElevation:
4250 pi = win32.CreateProcess(None, lpCmdLine,
4251 bInheritHandles = bInheritHandles,
4252 dwCreationFlags = dwCreationFlags,
4253 lpStartupInfo = lpStartupInfo)
4254
4255
4256 else:
4257
4258
4259
4260 hToken = None
4261 try:
4262 if not bAllowElevation:
4263 if bFollow:
4264 msg = (
4265 "Child processes can't be autofollowed"
4266 " when dropping UAC elevation.")
4267 raise NotImplementedError(msg)
4268 if bConsole:
4269 msg = (
4270 "Child processes can't inherit the debugger's"
4271 " console when dropping UAC elevation.")
4272 raise NotImplementedError(msg)
4273 if bInheritHandles:
4274 msg = (
4275 "Child processes can't inherit the debugger's"
4276 " handles when dropping UAC elevation.")
4277 raise NotImplementedError(msg)
4278 try:
4279 hWnd = self.get_shell_window()
4280 except WindowsError:
4281 hWnd = self.get_desktop_window()
4282 shell = hWnd.get_process()
4283 try:
4284 hShell = shell.get_handle(
4285 win32.PROCESS_QUERY_INFORMATION)
4286 with win32.OpenProcessToken(hShell) as hShellToken:
4287 hToken = win32.DuplicateTokenEx(hShellToken)
4288 finally:
4289 shell.close_handle()
4290
4291
4292 if iTrustLevel < 2:
4293 if iTrustLevel > 0:
4294 dwLevelId = win32.SAFER_LEVELID_NORMALUSER
4295 else:
4296 dwLevelId = win32.SAFER_LEVELID_UNTRUSTED
4297 with win32.SaferCreateLevel(dwLevelId = dwLevelId) as hSafer:
4298 hSaferToken = win32.SaferComputeTokenFromLevel(
4299 hSafer, hToken)[0]
4300 try:
4301 if hToken is not None:
4302 hToken.close()
4303 except:
4304 hSaferToken.close()
4305 raise
4306 hToken = hSaferToken
4307
4308
4309 if bAllowElevation:
4310 pi = win32.CreateProcessAsUser(
4311 hToken = hToken,
4312 lpCommandLine = lpCmdLine,
4313 bInheritHandles = bInheritHandles,
4314 dwCreationFlags = dwCreationFlags,
4315 lpStartupInfo = lpStartupInfo)
4316
4317
4318
4319
4320
4321
4322 else:
4323
4324
4325 dwCreationFlags &= ~win32.DEBUG_PROCESS
4326 dwCreationFlags &= ~win32.DEBUG_ONLY_THIS_PROCESS
4327
4328
4329 dwCreationFlags &= ~win32.DETACHED_PROCESS
4330
4331
4332 dwCreationFlags |= win32.CREATE_SUSPENDED
4333
4334
4335 pi = win32.CreateProcessWithToken(
4336 hToken = hToken,
4337 dwLogonFlags = win32.LOGON_WITH_PROFILE,
4338 lpCommandLine = lpCmdLine,
4339 dwCreationFlags = dwCreationFlags,
4340 lpStartupInfo = lpStartupInfo)
4341
4342
4343 if bDebug:
4344 win32.DebugActiveProcess(pi.dwProcessId)
4345
4346
4347 if not bSuspended:
4348 win32.ResumeThread(pi.hThread)
4349
4350
4351 finally:
4352 if hToken is not None:
4353 hToken.close()
4354
4355
4356
4357 aProcess = Process(pi.dwProcessId, pi.hProcess)
4358 aThread = Thread (pi.dwThreadId, pi.hThread)
4359 aProcess._add_thread(aThread)
4360 self._add_process(aProcess)
4361
4362
4363 except:
4364 if pi is not None:
4365 try:
4366 win32.TerminateProcess(pi.hProcess)
4367 except WindowsError:
4368 pass
4369 pi.hThread.close()
4370 pi.hProcess.close()
4371 raise
4372
4373
4374 return aProcess
4375
4377 """
4378 Tries to find the process ID for "explorer.exe".
4379
4380 @rtype: int or None
4381 @return: Returns the process ID, or C{None} on error.
4382 """
4383 try:
4384 exp = win32.SHGetFolderPath(win32.CSIDL_WINDOWS)
4385 except Exception:
4386 exp = None
4387 if not exp:
4388 exp = os.getenv('SystemRoot')
4389 if exp:
4390 exp = os.path.join(exp, 'explorer.exe')
4391 exp_list = self.find_processes_by_filename(exp)
4392 if exp_list:
4393 return exp_list[0][0].get_pid()
4394 return None
4395
4396
4397
4398
4399
4401 """
4402 Populates the snapshot with running processes and threads,
4403 and loaded modules.
4404
4405 Tipically this is the first method called after instantiating a
4406 L{System} object, as it makes a best effort approach to gathering
4407 information on running processes.
4408
4409 @rtype: bool
4410 @return: C{True} if the snapshot is complete, C{False} if the debugger
4411 doesn't have permission to scan some processes. In either case, the
4412 snapshot is complete for all processes the debugger has access to.
4413 """
4414 has_threads = True
4415 try:
4416 try:
4417
4418
4419
4420 self.scan_processes_and_threads()
4421
4422 except Exception:
4423
4424
4425 self.scan_processes_fast()
4426
4427
4428 for aProcess in self.__processDict.values():
4429 if aProcess._get_thread_ids():
4430 try:
4431 aProcess.scan_threads()
4432 except WindowsError:
4433 has_threads = False
4434
4435 finally:
4436
4437
4438
4439
4440 self.scan_processes()
4441
4442
4443 has_modules = self.scan_modules()
4444
4445
4446 has_full_names = self.scan_process_filenames()
4447
4448
4449 return has_threads and has_modules and has_full_names
4450
4527
4529 """
4530 Populates the snapshot with loaded modules.
4531
4532 Tipically you don't need to call this method directly, if unsure use
4533 L{scan} instead.
4534
4535 @note: This method uses the Toolhelp API.
4536
4537 @see: L{scan_processes_and_threads}
4538
4539 @rtype: bool
4540 @return: C{True} if the snapshot is complete, C{False} if the debugger
4541 doesn't have permission to scan some processes. In either case, the
4542 snapshot is complete for all processes the debugger has access to.
4543 """
4544 complete = True
4545 for aProcess in self.__processDict.itervalues():
4546 try:
4547 aProcess.scan_modules()
4548 except WindowsError, e:
4549 complete = False
4550 return complete
4551
4553 """
4554 Populates the snapshot with running processes.
4555
4556 Tipically you don't need to call this method directly, if unsure use
4557 L{scan} instead.
4558
4559 @note: This method uses the Remote Desktop API instead of the Toolhelp
4560 API. It might give slightly different results, especially if the
4561 current process does not have full privileges.
4562
4563 @note: This method will only retrieve process filenames. To get the
4564 process pathnames instead, B{after} this method call
4565 L{scan_process_filenames}.
4566
4567 @raise WindowsError: An error occured while updating the snapshot.
4568 The snapshot was not modified.
4569 """
4570
4571
4572
4573 our_pid = win32.GetCurrentProcessId()
4574 dead_pids = set( self.__processDict.keys() )
4575
4576
4577 if our_pid in dead_pids:
4578 dead_pids.remove(our_pid)
4579
4580
4581 pProcessInfo = None
4582 try:
4583 pProcessInfo, dwCount = win32.WTSEnumerateProcesses(
4584 win32.WTS_CURRENT_SERVER_HANDLE)
4585
4586
4587 for index in xrange(dwCount):
4588 sProcessInfo = pProcessInfo[index]
4589
4590
4591
4592
4593
4594
4595 pid = sProcessInfo.ProcessId
4596 if pid == our_pid:
4597 continue
4598
4599
4600 if pid in dead_pids:
4601 dead_pids.remove(pid)
4602
4603
4604
4605
4606 fileName = sProcessInfo.pProcessName
4607
4608
4609 if pid not in self.__processDict:
4610 aProcess = Process(pid, fileName = fileName)
4611 self._add_process(aProcess)
4612
4613
4614
4615 elif fileName:
4616 aProcess = self.__processDict.get(pid)
4617 if not aProcess.fileName:
4618 aProcess.fileName = fileName
4619
4620
4621 finally:
4622 if pProcessInfo is not None:
4623 try:
4624 win32.WTSFreeMemory(pProcessInfo)
4625 except WindowsError:
4626 pass
4627
4628
4629
4630 for pid in dead_pids:
4631 self._del_process(pid)
4632
4634 """
4635 Populates the snapshot with running processes.
4636 Only the PID is retrieved for each process.
4637
4638 Dead processes are removed.
4639 Threads and modules of living processes are ignored.
4640
4641 Tipically you don't need to call this method directly, if unsure use
4642 L{scan} instead.
4643
4644 @note: This method uses the PSAPI. It may be faster for scanning,
4645 but some information may be missing, outdated or slower to obtain.
4646 This could be a good tradeoff under some circumstances.
4647 """
4648
4649
4650 new_pids = set( win32.EnumProcesses() )
4651 old_pids = set( self.__processDict.keys() )
4652
4653
4654 our_pid = win32.GetCurrentProcessId()
4655 if our_pid in new_pids:
4656 new_pids.remove(our_pid)
4657 if our_pid in old_pids:
4658 old_pids.remove(our_pid)
4659
4660
4661 for pid in new_pids.difference(old_pids):
4662 self._add_process( Process(pid) )
4663
4664
4665 for pid in old_pids.difference(new_pids):
4666 self._del_process(pid)
4667
4669 """
4670 Update the filename for each process in the snapshot when possible.
4671
4672 @note: Tipically you don't need to call this method. It's called
4673 automatically by L{scan} to get the full pathname for each process
4674 when possible, since some scan methods only get filenames without
4675 the path component.
4676
4677 If unsure, use L{scan} instead.
4678
4679 @see: L{scan}, L{Process.get_filename}
4680
4681 @rtype: bool
4682 @return: C{True} if all the pathnames were retrieved, C{False} if the
4683 debugger doesn't have permission to scan some processes. In either
4684 case, all processes the debugger has access to have a full pathname
4685 instead of just a filename.
4686 """
4687 complete = True
4688 for aProcess in self.__processDict.values():
4689 try:
4690 new_name = None
4691 old_name = aProcess.fileName
4692 try:
4693 aProcess.fileName = None
4694 new_name = aProcess.get_filename()
4695 finally:
4696 if not new_name:
4697 aProcess.fileName = old_name
4698 complete = False
4699 except Exception:
4700 complete = False
4701 return complete
4702
4703
4704
4714
4716 """
4717 Removes Process objects from the snapshot
4718 referring to processes not being debugged.
4719 """
4720 for pid in self.get_process_ids():
4721 aProcess = self.get_process(pid)
4722 if not aProcess.is_being_debugged():
4723 self._del_process(aProcess)
4724
4740
4742 """
4743 Closes all open handles to processes and threads in this snapshot.
4744 """
4745 for aProcess in self.iter_processes():
4746 aProcess.close_thread_handles()
4747 try:
4748 aProcess.close_handle()
4749 except Exception, e:
4750 try:
4751 msg = "Cannot close process handle %s, reason: %s"
4752 msg %= (aProcess.hProcess.value, str(e))
4753 warnings.warn(msg)
4754 except Exception:
4755 pass
4756
4758 """
4759 Removes all L{Process}, L{Thread} and L{Module} objects in this snapshot.
4760 """
4761
4762 for aProcess in self.iter_processes():
4763 aProcess.clear()
4764 self.__processDict = dict()
4765
4767 """
4768 Clears this snapshot.
4769
4770 @see: L{clear_processes}
4771 """
4772 self.clear_processes()
4773
4774
4775
4776
4777
4783
4790
4796
4802
4803 has_thread.__doc__ = _ThreadContainer.has_thread.__doc__
4804 get_thread.__doc__ = _ThreadContainer.get_thread.__doc__
4805 get_thread_ids.__doc__ = _ThreadContainer.get_thread_ids.__doc__
4806 get_thread_count.__doc__ = _ThreadContainer.get_thread_count.__doc__
4807
4808
4809
4810
4811
4817
4818 get_module_count.__doc__ = _ModuleContainer.get_module_count.__doc__
4819
4820
4821
4833
4835 """
4836 @rtype: list( L{Module}... )
4837 @return: List of Module objects found.
4838 """
4839 found = list()
4840 for aProcess in self.iter_processes():
4841 aModule = aProcess.get_module_by_name(fileName)
4842 if aModule is not None:
4843 found.append( (aProcess, aModule) )
4844 return found
4845
4847 """
4848 @rtype: list( L{Module}... )
4849 @return: List of Module objects that best match the given address.
4850 """
4851 found = list()
4852 for aProcess in self.iter_processes():
4853 aModule = aProcess.get_module_at_address(address)
4854 if aModule is not None:
4855 found.append( (aProcess, aModule) )
4856 return found
4857
4877
4879 """
4880 @type fileName: str
4881 @param fileName: Filename to search for.
4882 If it's a full pathname, the match must be exact.
4883 If it's a base filename only, the file part is matched,
4884 regardless of the directory where it's located.
4885
4886 @note: If the process is not found and the file extension is not
4887 given, this method will search again assuming a default
4888 extension (.exe).
4889
4890 @rtype: list of tuple( L{Process}, str )
4891 @return: List of processes matching the given main module filename.
4892 Each tuple contains a Process object and it's filename.
4893 """
4894 found = self.__find_processes_by_filename(fileName)
4895 if not found:
4896 fn, ext = PathOperations.split_extension(fileName)
4897 if not ext:
4898 fileName = '%s.exe' % fn
4899 found = self.__find_processes_by_filename(fileName)
4900 return found
4901
4902
4903
4904
4905
4907 """
4908 Private method to add a process object to the snapshot.
4909
4910 @type aProcess: L{Process}
4911 @param aProcess: Process object.
4912 """
4913
4914
4915
4916
4917
4918
4919
4920 dwProcessId = aProcess.dwProcessId
4921
4922
4923
4924 self.__processDict[dwProcessId] = aProcess
4925
4927 """
4928 Private method to remove a process object from the snapshot.
4929
4930 @type dwProcessId: int
4931 @param dwProcessId: Global process ID.
4932 """
4933 try:
4934 aProcess = self.__processDict[dwProcessId]
4935 del self.__processDict[dwProcessId]
4936 except KeyError:
4937 aProcess = None
4938 msg = "Unknown process ID %d" % dwProcessId
4939 warnings.warn(msg, RuntimeWarning)
4940 if aProcess:
4941 aProcess.clear()
4942
4943
4974
4976 """
4977 Notify the termination of a process.
4978
4979 This is done automatically by the L{Debug} class, you shouldn't need
4980 to call it yourself.
4981
4982 @type event: L{ExitProcessEvent}
4983 @param event: Exit process event.
4984
4985 @rtype: bool
4986 @return: C{True} to call the user-defined handle, C{False} otherwise.
4987 """
4988 dwProcessId = event.get_pid()
4989
4990 if dwProcessId in self.__processDict:
4991 self._del_process(dwProcessId)
4992 return True
4993