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 Instrumentation module.
30
31 @see: U{http://apps.sourceforge.net/trac/winappdbg/wiki/Instrumentation}
32
33 @group Instrumentation:
34 System, Process, Thread, Module
35 @group Capabilities (private):
36 ModuleContainer, ThreadContainer, ProcessContainer, SymbolContainer,
37 ThreadDebugOperations, ProcessDebugOperations,
38 MemoryOperations, MemoryAddresses, SymbolOperations, PathOperations,
39 SymbolEnumerator
40 """
41
42
43
44
45
46
47
48 __revision__ = "$Id: system.py 550 2009-12-13 23:52:46Z qvasimodo $"
49
50 __all__ = [
51
52 'System',
53 'Process',
54 'Thread',
55 'Module',
56
57
58 'MemoryAddresses',
59 'PathOperations',
60 ]
61
62 import win32
63 import win32.version
64 from textio import HexInput, HexDump
65
66 import re
67 import os
68 import sys
69 import ctypes
70 import struct
71
72 try:
73 from distorm import Decode, Decode16Bits, Decode32Bits, Decode64Bits
74 except ImportError:
75 Decode16Bits = None
76 Decode32Bits = None
77 Decode64Bits = None
79 "PLEASE INSTALL DISTORM BEFORE GENERATING THE DOCUMENTATION"
80 msg = ("diStorm is not installed or can't be found. "
81 "Download it from: http://www.ragestorm.net/distorm/")
82 raise NotImplementedError, msg
83
87 """
88 Static methods for filename and pathname manipulation.
89 """
90
91 @staticmethod
93 """
94 @type pathname: str
95 @param pathname: Absolute path.
96
97 @rtype: str
98 @return: Relative path.
99 """
100 return win32.PathFindFileName(pathname)
101
102 @staticmethod
104 """
105 @type filename: str
106 @param filename: Relative path.
107
108 @rtype: str
109 @return: Absolute path.
110 """
111 return win32.GetFullPathName(filename)
112
113 @staticmethod
115 """
116 @see: L{path_is_absolute}
117
118 @type path: str
119 @param path: Absolute or relative path.
120
121 @rtype: bool
122 @return: C{True} if the path is relative, C{False} if it's absolute.
123 """
124 return win32.PathIsRelative(path)
125
126 @staticmethod
128 """
129 @see: L{path_is_relative}
130
131 @type path: str
132 @param path: Absolute or relative path.
133
134 @rtype: bool
135 @return: C{True} if the path is absolute, C{False} if it's relative.
136 """
137 return not win32.PathIsRelative(path)
138
139 @staticmethod
141 """
142 @type pathname: str
143 @param pathname: Absolute path.
144
145 @rtype: tuple( str, str )
146 @return:
147 Tuple containing the file and extension components of the filename.
148 """
149 filepart = win32.PathRemoveExtension(pathname)
150 extpart = win32.PathFindExtension(pathname)
151 return (filepart, extpart)
152
153 @staticmethod
155 """
156 @type pathname: str
157 @param pathname: Absolute path.
158
159 @rtype: tuple( str, str )
160 @return: Tuple containing the path to the file and the base filename.
161 """
162 filepart = win32.PathFindFileName(pathname)
163 pathpart = win32.PathRemoveFileSpec(pathname)
164 return (pathpart, filepart)
165
166 @staticmethod
168 """
169 @see: L{join_path}
170
171 @type path: str
172 @param path: Absolute or relative path.
173
174 @rtype: list( str... )
175 @return: List of path components.
176 """
177 components = list()
178 while path:
179 next = win32.PathFindNextComponent(path)
180 if next:
181 prev = path[ : -len(next) ]
182 components.append(prev)
183 path = next
184 return components
185
186 @staticmethod
188 """
189 @see: L{split_path}
190
191 @type components: tuple( str... )
192 @param components: Path components.
193
194 @rtype: str
195 @return: Absolute or relative path.
196 """
197 if components:
198 path = components[0]
199 for next in components[1:]:
200 path = win32.PathAppend(path, next)
201 else:
202 path = ""
203 return path
204
205 @staticmethod
207 """
208 @type name: str
209 @param name: Native (NT) absolute pathname.
210
211 @rtype: str
212 @return: Win32 absolute pathname.
213 """
214
215
216
217 if name.startswith("\\"):
218 if name.startswith("\\??\\"):
219 name = name[4:]
220 elif name.startswith("\\SystemRoot\\"):
221 system_root_path = os.environ['SYSTEMROOT']
222 if system_root_path.endswith('\\'):
223 system_root_path = system_root_path[:-1]
224 name = system_root_path + name[11:]
225 else:
226 for drive_number in xrange(ord('A'), ord('Z') + 1):
227 drive_letter = '%c:' % drive_number
228 try:
229 device_native_path = win32.QueryDosDevice(drive_letter)
230 except WindowsError, e:
231 if e.winerror in (win32.ERROR_FILE_NOT_FOUND, \
232 win32.ERROR_PATH_NOT_FOUND):
233 continue
234 raise
235 if not device_native_path.endswith('\\'):
236 device_native_path += '\\'
237 if name.startswith(device_native_path):
238 name = drive_letter + '\\' + \
239 name[ len(device_native_path) : ]
240 break
241 return name
242
246 """
247 Encapsulates the capability to contain Module objects.
248
249 @group Modules snapshot:
250 scan_modules,
251 get_module, get_module_bases, get_module_count,
252 get_module_at_address, get_module_by_name,
253 has_module, iter_modules, iter_module_addresses,
254 clear_modules
255
256 @group Event notifications (private):
257 notify_load_dll,
258 notify_unload_dll
259 """
260
264
266 """
267 Private method to automatically initialize the snapshot
268 when you try to use it without calling any of the scan_*
269 methods first. You don't need to call this yourself.
270 """
271 if not self.__moduleDict:
272 self.scan_modules()
273
275 """
276 @type anObject: L{Module}, int
277 @param anObject:
278 - C{Module}: Module object to look for.
279 - C{int}: Base address of the DLL to look for.
280
281 @rtype: bool
282 @return: C{True} if the snapshot contains
283 a L{Module} object with the same base address.
284 """
285 if isinstance(anObject, Module):
286 anObject = anObject.lpBaseOfDll
287 return self.has_module(anObject)
288
290 """
291 @see: L{iter_modules}
292 @rtype: dictionary-valueiterator
293 @return: Iterator of L{Module} objects in this snapshot.
294 """
295 return self.iter_modules()
296
298 """
299 @see: L{get_module_count}
300 @rtype: int
301 @return: Count of L{Module} objects in this snapshot.
302 """
303 return self.get_module_count()
304
306 """
307 @type lpBaseOfDll: int
308 @param lpBaseOfDll: Base address of the DLL to look for.
309
310 @rtype: bool
311 @return: C{True} if the snapshot contains a
312 L{Module} object with the given base address.
313 """
314 self.__initialize_snapshot()
315 return lpBaseOfDll in self.__moduleDict
316
318 """
319 @type lpBaseOfDll: int
320 @param lpBaseOfDll: Base address of the DLL to look for.
321
322 @rtype: L{Module}
323 @return: Module object with the given base address.
324 """
325 self.__initialize_snapshot()
326 if lpBaseOfDll not in self.__moduleDict:
327 msg = "Unknown DLL base address %s"
328 msg = msg % HexDump.address(lpBaseOfDll)
329 raise KeyError, msg
330 return self.__moduleDict[lpBaseOfDll]
331
333 """
334 @see: L{iter_modules}
335 @rtype: dictionary-keyiterator
336 @return: Iterator of DLL base addresses in this snapshot.
337 """
338 self.__initialize_snapshot()
339 return self.__moduleDict.iterkeys()
340
342 """
343 @see: L{iter_module_addresses}
344 @rtype: dictionary-valueiterator
345 @return: Iterator of L{Module} objects in this snapshot.
346 """
347 self.__initialize_snapshot()
348 return self.__moduleDict.itervalues()
349
351 """
352 @see: L{iter_module_addresses}
353 @rtype: list( int... )
354 @return: List of DLL base addresses in this snapshot.
355 """
356 self.__initialize_snapshot()
357 return self.__moduleDict.keys()
358
360 """
361 @rtype: int
362 @return: Count of L{Module} objects in this snapshot.
363 """
364 self.__initialize_snapshot()
365 return len(self.__moduleDict)
366
367
368
370 """
371 @type modName: int
372 @param modName:
373 Name of the module to look for, as returned by L{Module.get_name}.
374 If two or more modules with the same name are loaded, only one
375 of the matching modules is returned.
376
377 You can also pass a full pathname to the DLL file.
378 This works correctly even if two modules with the same name
379 are loaded from different paths.
380
381 @rtype: L{Module}
382 @return: C{Module} object that best matches the given name.
383 Returns C{None} if no C{Module} can be found.
384 """
385
386
387
388 modName = modName.lower()
389
390
391 if PathOperations.path_is_absolute(modName):
392 for lib in self.iter_modules():
393 if modName == lib.get_filename().lower():
394 return lib
395 return None
396
397
398
399
400 modDict = [ ( lib.get_name(), lib ) for lib in self.iter_modules() ]
401 modDict = dict(modDict)
402
403
404 if modName in modDict:
405 return modDict[modName]
406
407
408 filepart, extpart = PathOperations.split_extension(modName)
409 if filepart and extpart:
410 if filepart in modDict:
411 return modDict[filepart]
412
413
414 try:
415 baseAddress = HexInput.integer(modName)
416 except ValueError:
417 return None
418 if self.has_module(baseAddress):
419 return self.get_module(baseAddress)
420
421
422 return None
423
425 """
426 @type address: int
427 @param address: Memory address to query.
428
429 @rtype: L{Module}
430 @return: C{Module} object that best matches the given address.
431 Returns C{None} if no C{Module} can be found.
432 """
433 bases = self.get_module_bases()
434 bases.sort()
435
436 bases.append(0x1000000000000000)
437 if address >= bases[0]:
438 for i in xrange(len(bases)-1):
439 begin, end = bases[i:i+2]
440 if begin <= address <= end:
441 module = self.get_module(begin)
442 here = module.is_address_here(address)
443 if here is False:
444 break
445 else:
446 return module
447 return None
448
449
501
503 """
504 Clears the modules snapshot.
505 """
506 self.__moduleDict = dict()
507
508
509
510
511
525
531
561
563 """
564 Notify the load of the main module.
565
566 This is done automatically by the L{Debug} class, you shouldn't need
567 to call it yourself.
568
569 @type event: L{CreateProcessEvent}
570 @param event: Create process event.
571 """
572 self.__add_loaded_module(event)
573 return True
574
576 """
577 Notify the load of a new module.
578
579 This is done automatically by the L{Debug} class, you shouldn't need
580 to call it yourself.
581
582 @type event: L{LoadDLLEvent}
583 @param event: Load DLL event.
584 """
585 self.__add_loaded_module(event)
586 return True
587
589 """
590 Notify the release of a loaded module.
591
592 This is done automatically by the L{Debug} class, you shouldn't need
593 to call it yourself.
594
595 @type event: L{UnloadDLLEvent}
596 @param event: Unload DLL event.
597 """
598 lpBaseOfDll = event.get_module_base()
599
600 if self.__moduleDict.has_key(lpBaseOfDll):
601 self.__del_module(lpBaseOfDll)
602 return True
603
607 """
608 Encapsulates the capability to contain Thread objects.
609
610 @group Instrumentation:
611 start_thread
612
613 @group Threads snapshot:
614 scan_threads,
615 get_thread, get_thread_count, get_thread_ids,
616 has_thread, iter_threads, iter_thread_ids,
617 find_threads_by_name,
618 clear_threads, clear_dead_threads, close_thread_handles
619
620 @group Event notifications (private):
621 notify_create_process,
622 notify_create_thread,
623 notify_exit_thread
624 """
625
629
631 """
632 Private method to automatically initialize the snapshot
633 when you try to use it without calling any of the scan_*
634 methods first. You don't need to call this yourself.
635 """
636 if not self.__threadDict:
637 self.scan_threads()
638
640 """
641 @type anObject: L{Thread}, int
642 @param anObject:
643 - C{int}: Global ID of the thread to look for.
644 - C{Thread}: Thread object to look for.
645
646 @rtype: bool
647 @return: C{True} if the snapshot contains
648 a L{Thread} object with the same ID.
649 """
650 if isinstance(anObject, Thread):
651 anObject = anObject.dwThreadId
652 return self.has_thread(anObject)
653
655 """
656 @see: L{iter_threads}
657 @rtype: dictionary-valueiterator
658 @return: Iterator of L{Thread} objects in this snapshot.
659 """
660 return self.iter_threads()
661
663 """
664 @see: L{get_thread_count}
665 @rtype: int
666 @return: Count of L{Thread} objects in this snapshot.
667 """
668 return self.get_thread_count()
669
671 """
672 @type dwThreadId: int
673 @param dwThreadId: Global ID of the thread to look for.
674
675 @rtype: bool
676 @return: C{True} if the snapshot contains a
677 L{Thread} object with the given global ID.
678 """
679 self.__initialize_snapshot()
680 return dwThreadId in self.__threadDict
681
683 """
684 @type dwThreadId: int
685 @param dwThreadId: Global ID of the thread to look for.
686
687 @rtype: L{Thread}
688 @return: Thread object with the given global ID.
689 """
690 self.__initialize_snapshot()
691 if dwThreadId not in self.__threadDict:
692 msg = "Unknown thread ID: %d" % dwThreadId
693 raise KeyError, msg
694 return self.__threadDict[dwThreadId]
695
697 """
698 @see: L{iter_threads}
699 @rtype: dictionary-keyiterator
700 @return: Iterator of global thread IDs in this snapshot.
701 """
702 self.__initialize_snapshot()
703 return self.__threadDict.iterkeys()
704
706 """
707 @see: L{iter_thread_ids}
708 @rtype: dictionary-valueiterator
709 @return: Iterator of L{Thread} objects in this snapshot.
710 """
711 self.__initialize_snapshot()
712 return self.__threadDict.itervalues()
713
715 """
716 @rtype: list( int )
717 @return: List of global thread IDs in this snapshot.
718 """
719 self.__initialize_snapshot()
720 return self.__threadDict.keys()
721
723 """
724 @rtype: int
725 @return: Count of L{Thread} objects in this snapshot.
726 """
727 self.__initialize_snapshot()
728 return len(self.__threadDict)
729
730
731
733 """
734 Find threads by name, using different search methods.
735
736 @type name: str, None
737 @param name: Name to look for. Use C{None} to find nameless threads.
738
739 @type bExactMatch: bool
740 @param bExactMatch: C{True} if the name must be
741 B{exactly} as given, C{False} if the name can be
742 loosely matched.
743
744 This parameter is ignored when C{name} is C{None}.
745
746 @rtype: list( L{Thread} )
747 @return: All threads matching the given name.
748 """
749 found_threads = list()
750
751
752 if name is None:
753 for aThread in self.iter_threads():
754 if aThread.get_name() is None:
755 found_threads.append(aThread)
756
757
758 elif bExactMatch:
759 for aThread in self.iter_threads():
760 if aThread.get_name() == name:
761 found_threads.append(aThread)
762
763
764 else:
765 for aThread in self.iter_threads():
766 t_name = aThread.get_name()
767 if t_name is not None and name in t_name:
768 found_threads.append(aThread)
769
770 return found_threads
771
772
773
774 - def start_thread(self, lpStartAddress, lpParameter=0, bSuspended = False):
775 """
776 Remotely creates a new thread in the process.
777
778 @type lpStartAddress: int
779 @param lpStartAddress: Start address for the new thread.
780
781 @type lpParameter: int
782 @param lpParameter: Optional argument for the new thread.
783
784 @type bSuspended: bool
785 @param bSuspended: C{True} if the new thread should be suspended.
786 In that case use L{Thread.resume} to start execution.
787 """
788 if bSuspended:
789 dwCreationFlags = win32.CREATE_SUSPENDED
790 else:
791 dwCreationFlags = 0
792 hThread, dwThreadId = win32.CreateRemoteThread(self.get_handle(), 0, 0,
793 lpStartAddress, lpParameter, dwCreationFlags)
794 aThread = Thread(dwThreadId, hThread, self)
795 self.__add_thread(aThread)
796 return aThread
797
798
799
800
801
802
803
840
842 """
843 Remove Thread objects from the snapshot
844 referring to threads no longer running.
845 """
846 for tid in self.get_thread_ids():
847 aThread = self.get_thread(tid)
848 if not aThread.is_alive():
849 self.__del_thread(aThread)
850
852 """
853 Clears the threads snapshot.
854 """
855 self.__threadDict = dict()
856
858 """
859 Closes all open handles to threads in the snapshot.
860 """
861 for aThread in self.iter_threads():
862 try:
863 aThread.close_handle()
864 except Exception, e:
865 pass
866
867
868
869
870
885
891
903
905 """
906 Notify the creation of the main thread of this process.
907
908 This is done automatically by the L{Debug} class, you shouldn't need
909 to call it yourself.
910
911 @type event: L{CreateProcessEvent}
912 @param event: Create process event.
913 """
914 self.__add_created_thread(event)
915 return True
916
918 """
919 Notify the creation of a new thread in this process.
920
921 This is done automatically by the L{Debug} class, you shouldn't need
922 to call it yourself.
923
924 @type event: L{CreateThreadEvent}
925 @param event: Create thread event.
926 """
927 self.__add_created_thread(event)
928 return True
929
931 """
932 Notify the termination of a thread.
933
934 This is done automatically by the L{Debug} class, you shouldn't need
935 to call it yourself.
936
937 @type event: L{ExitThreadEvent}
938 @param event: Exit thread event.
939 """
940 dwThreadId = event.get_tid()
941
942 if self.__threadDict.has_key(dwThreadId):
943 self.__del_thread(dwThreadId)
944 return True
945
949 """
950 Encapsulates the capability to contain Process objects.
951
952 @group Instrumentation:
953 start_process, argv_to_cmdline, cmdline_to_argv
954
955 @group Processes snapshot:
956 scan, scan_processes, scan_processes_fast,
957 get_process, get_process_count, get_process_ids,
958 has_process, iter_processes, iter_process_ids,
959 find_processes_by_filename, get_pid_from_tid,
960 clear, clear_processes, clear_dead_processes,
961 clear_unattached_processes,
962 close_process_handles,
963 close_process_and_thread_handles
964
965 @group Threads snapshots:
966 scan_processes_and_threads,
967 get_thread, get_thread_count, get_thread_ids,
968 has_thread
969
970 @group Modules snapshots:
971 scan_modules, find_modules_by_address,
972 find_modules_by_base, find_modules_by_name,
973 get_module_count
974
975 @group Event notifications (private):
976 notify_create_process,
977 notify_exit_process
978 """
979
983
985 """
986 Private method to automatically initialize the snapshot
987 when you try to use it without calling any of the scan_*
988 methods first. You don't need to call this yourself.
989 """
990 if not self.__processDict:
991
992 try:
993 self.scan_processes()
994 except Exception:
995 self.scan_processes_fast()
996
998 """
999 @type anObject: L{Process}, L{Thread}, int
1000 @param anObject:
1001 - C{int}: Global ID of the process to look for.
1002 - C{int}: Global ID of the thread to look for.
1003 - C{Process}: Process object to look for.
1004 - C{Thread}: Thread object to look for.
1005
1006 @rtype: bool
1007 @return: C{True} if the snapshot contains
1008 a L{Process} or L{Thread} object with the same ID.
1009 """
1010 if isinstance(anObject, Process):
1011 anObject = anObject.dwProcessId
1012 if self.has_process(anObject):
1013 return True
1014 for aProcess in self.iter_processes():
1015 if anObject in aProcess:
1016 return True
1017 return False
1018
1020 """
1021 @see: L{iter_processes}
1022 @rtype: dictionary-valueiterator
1023 @return: Iterator of L{Process} objects in this snapshot.
1024 """
1025 return self.iter_processes()
1026
1028 """
1029 @see: L{get_process_count}
1030 @rtype: int
1031 @return: Count of L{Process} objects in this snapshot.
1032 """
1033 return self.get_process_count()
1034
1036 """
1037 @type dwProcessId: int
1038 @param dwProcessId: Global ID of the process to look for.
1039
1040 @rtype: bool
1041 @return: C{True} if the snapshot contains a
1042 L{Process} object with the given global ID.
1043 """
1044 self.__initialize_snapshot()
1045 return dwProcessId in self.__processDict
1046
1048 """
1049 @type dwProcessId: int
1050 @param dwProcessId: Global ID of the process to look for.
1051
1052 @rtype: L{Process}
1053 @return: Process object with the given global ID.
1054 """
1055 self.__initialize_snapshot()
1056 if dwProcessId not in self.__processDict:
1057 msg = "Unknown process ID %d" % dwProcessId
1058 raise KeyError, msg
1059 return self.__processDict[dwProcessId]
1060
1062 """
1063 @see: L{iter_processes}
1064 @rtype: dictionary-keyiterator
1065 @return: Iterator of global process IDs in this snapshot.
1066 """
1067 self.__initialize_snapshot()
1068 return self.__processDict.iterkeys()
1069
1071 """
1072 @see: L{iter_process_ids}
1073 @rtype: dictionary-valueiterator
1074 @return: Iterator of L{Process} objects in this snapshot.
1075 """
1076 self.__initialize_snapshot()
1077 return self.__processDict.itervalues()
1078
1080 """
1081 @see: L{iter_process_ids}
1082 @rtype: list( int )
1083 @return: List of global process IDs in this snapshot.
1084 """
1085 self.__initialize_snapshot()
1086 return self.__processDict.keys()
1087
1089 """
1090 @rtype: int
1091 @return: Count of L{Process} objects in this snapshot.
1092 """
1093 self.__initialize_snapshot()
1094 return len(self.__processDict)
1095
1096
1097
1099 window_list = list()
1100 for process in self.iter_processes():
1101 window_list.extend( process.get_windows() )
1102 return window_list
1103
1125
1126
1127
1128 @staticmethod
1130 """
1131 Convert a list of arguments to a single command line string.
1132
1133 @type argv: list( str )
1134 @param argv: List of argument strings.
1135 The first element is the program to execute.
1136
1137 @rtype: str
1138 @return: Command line string.
1139 """
1140 cmdline = list()
1141 for token in argv:
1142 if not token:
1143 token = '""'
1144 else:
1145 if '"' in token:
1146 token = token.replace('"', '\\"')
1147 if ' ' in token or \
1148 '\t' in token or \
1149 '\n' in token or \
1150 '\r' in token:
1151 token = '"%s"' % token
1152 cmdline.append(token)
1153 return ' '.join(cmdline)
1154
1155 @staticmethod
1157 """
1158 Convert a single command line string to a list of arguments.
1159
1160 @type lpCmdLine: str
1161 @param lpCmdLine: Command line string.
1162 The first token is the program to execute.
1163
1164 @rtype: list( str )
1165 @return: List of argument strings.
1166 """
1167 if not lpCmdLine:
1168 return []
1169 return win32.CommandLineToArgv(lpCmdLine)
1170
1171 - def start_process(self, lpCmdLine,
1172 bConsole = False,
1173 bDebug = False,
1174 bFollow = False,
1175 bSuspended = False,
1176 bInheritHandles = False,
1177 dwParentProcessId = None
1178 ):
1179 """
1180 Starts a new process for instrumenting (or debugging).
1181
1182 @type lpCmdLine: str
1183 @param lpCmdLine: Command line to execute. Can't be an empty string.
1184
1185 @type bConsole: bool
1186 @param bConsole: C{True} if the new process should inherit the console.
1187 Defaults to C{False}.
1188
1189 @type bDebug: bool
1190 @param bDebug: C{True} to attach to the new process.
1191 To debug a process it's best to use the L{Debug} class instead.
1192 Defaults to C{False}.
1193
1194 @type bFollow: bool
1195 @param bFollow: C{True} to automatically attach to the child processes
1196 of the newly created process. Ignored unless C{bDebug} is C{True}.
1197 Defaults to C{False}.
1198
1199 @type bSuspended: bool
1200 @param bSuspended: C{True} if the new process should be suspended.
1201 Defaults to C{False}.
1202
1203 @type bInheritHandles: bool
1204 @param bInheritHandles: C{True} if the new process should inherit it's
1205 parent process' handles. Defaults to C{False}.
1206
1207 @type dwParentProcessId: int or None
1208 @param dwParentProcessId: C{None} if the debugger process should be the
1209 parent process (default), or a process ID to forcefully set as the
1210 debuguee's parent (only available for Windows Vista and above).
1211
1212 @rtype: L{Process}
1213 @return: Process object.
1214 """
1215 if not lpCmdLine:
1216 raise ValueError, "Missing command line to execute!"
1217 dwCreationFlags = 0
1218 dwCreationFlags |= win32.CREATE_DEFAULT_ERROR_MODE
1219 dwCreationFlags |= win32.CREATE_BREAKAWAY_FROM_JOB
1220 if not bConsole:
1221 dwCreationFlags |= win32.DETACHED_PROCESS
1222 if bSuspended:
1223 dwCreationFlags |= win32.CREATE_SUSPENDED
1224 if bDebug:
1225 dwCreationFlags |= win32.DEBUG_PROCESS
1226 if bDebug and not bFollow:
1227 dwCreationFlags |= win32.DEBUG_ONLY_THIS_PROCESS
1228 lpStartupInfo = None
1229 if dwParentProcessId is not None:
1230 myPID = win32.GetProcessId( win32.GetCurrentProcess() )
1231 if dwParentProcessId != myPID:
1232 if self.has_process(dwParentProcessId):
1233 ParentProcess = self.get_process(dwParentProcessId)
1234 else:
1235 ParentProcess = Process(dwParentProcessId)
1236 ParentProcessHandle = ParentProcess.get_handle()._as_parameter_
1237 AttributeList = (
1238 (
1239 win32.PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
1240 ParentProcessHandle
1241 ),
1242 )
1243 AttributeList = win32.ProcThreadAttributeList(AttributeList)
1244 StartupInfoEx = win32.STARTUPINFOEX()
1245 StartupInfo = StartupInfoEx.StartupInfo
1246 StartupInfo.cb = win32.sizeof(win32.STARTUPINFOEX)
1247 StartupInfo.lpReserved = 0
1248 StartupInfo.lpDesktop = 0
1249 StartupInfo.lpTitle = 0
1250 StartupInfo.dwFlags = 0
1251 StartupInfo.cbReserved2 = 0
1252 StartupInfo.lpReserved2 = 0
1253 StartupInfoEx.lpAttributeList = AttributeList.value
1254 lpStartupInfo = StartupInfoEx
1255 dwCreationFlags |= win32.EXTENDED_STARTUPINFO_PRESENT
1256 pi = win32.CreateProcess(win32.NULL, lpCmdLine,
1257 bInheritHandles = bInheritHandles,
1258 dwCreationFlags = dwCreationFlags,
1259 lpStartupInfo = lpStartupInfo)
1260 aProcess = Process(pi.dwProcessId, pi.hProcess)
1261 aThread = Thread (pi.dwThreadId, pi.hThread)
1262 aProcess._ThreadContainer__add_thread(aThread)
1263 self.__add_process(aProcess)
1264 return aProcess
1265
1266
1267
1268
1269
1281
1355
1357 """
1358 Populates the snapshot with loaded modules.
1359 """
1360
1361 for aProcess in self.__processDict.itervalues():
1362 try:
1363 aProcess.scan_modules()
1364 except WindowsError, e:
1365
1366 dwProcessId = aProcess.get_pid()
1367 if dwProcessId == 4 and e.winerror == 8:
1368 continue
1369
1400
1402 """
1403 Populates the snapshot with running processes.
1404 Only the PID is retrieved for each process.
1405
1406 Dead processes are removed.
1407 Threads and modules of living processes are ignored.
1408
1409 @note: This method may be faster for scanning, but some information
1410 may be missing, outdated or slower to obtain. This could be a good
1411 tradeoff under some circumstances.
1412 """
1413
1414
1415 new_pids = set( win32.EnumProcesses() )
1416
1417 old_pids = set( self.__processDict.keys() )
1418
1419
1420 our_pid = win32.GetProcessId( win32.GetCurrentProcess() )
1421 if our_pid in new_pids:
1422 new_pids.remove(our_pid)
1423 if our_pid in old_pids:
1424 old_pids.remove(our_pid)
1425
1426
1427 for pid in new_pids.difference(old_pids):
1428 self.__add_process( Process(pid) )
1429
1430
1431 for pid in old_pids.difference(new_pids):
1432 self.__del_process(pid)
1433
1435 """
1436 Removes Process objects from the snapshot
1437 referring to processes no longer running.
1438 """
1439 for pid in self.get_process_ids():
1440 aProcess = self.get_process(pid)
1441 if not aProcess.is_alive():
1442 self.__del_process(aProcess)
1443
1445 """
1446 Removes Process objects from the snapshot
1447 referring to processes not being debugged.
1448 """
1449 for pid in self.get_process_ids():
1450 aProcess = self.get_process(pid)
1451 if not aProcess.is_being_debugged():
1452 self.__del_process(aProcess)
1453
1464
1476
1478 """
1479 Removes all L{Process}, L{Thread} and L{Module} objects in this snapshot.
1480 """
1481 self.__processDict = dict()
1482
1484 """
1485 Clears this snapshot.
1486
1487 @see: L{clear_processes}
1488 """
1489 self.clear_processes()
1490
1491
1492
1493
1494
1500
1507
1513
1519
1520 has_thread.__doc__ = ThreadContainer.has_thread.__doc__
1521 get_thread.__doc__ = ThreadContainer.get_thread.__doc__
1522 get_thread_ids.__doc__ = ThreadContainer.get_thread_ids.__doc__
1523 get_thread_count.__doc__ = ThreadContainer.get_thread_count.__doc__
1524
1525
1526
1527
1528
1534
1535 get_module_count.__doc__ = ModuleContainer.get_module_count.__doc__
1536
1537
1538
1540 """
1541 @rtype: list( L{Module}... )
1542 @return: List of Module objects with the given base address.
1543 """
1544 found = list()
1545 for aProcess in self.iter_processes():
1546 if aProcess.has_module(lpBaseOfDll):
1547 aModule = aProcess.get_module(lpBaseOfDll)
1548 found.append( (aProcess, aModule) )
1549 return found
1550
1552 """
1553 @rtype: list( L{Module}... )
1554 @return: List of Module objects found.
1555 """
1556 found = list()
1557 for aProcess in self.iter_processes():
1558 aModule = aProcess.get_module_by_name(fileName)
1559 if aModule is not None:
1560 found.append( (aProcess, aModule) )
1561 return found
1562
1564 """
1565 @rtype: list( L{Module}... )
1566 @return: List of Module objects that best match the given address.
1567 """
1568 found = list()
1569 for aProcess in self.iter_processes():
1570 aModule = aProcess.get_module_at_address(address)
1571 if aModule is not None:
1572 found.append( (aProcess, aModule) )
1573 return found
1574
1576 """
1577 Internally used by L{find_processes_by_filename}.
1578 """
1579 found = list()
1580 filename = filename.lower()
1581 if PathOperations.path_is_absolute(filename):
1582 for aProcess in self.iter_processes():
1583 imagename = aProcess.get_filename()
1584 if imagename and imagename.lower() == filename:
1585 found.append( (aProcess, imagename) )
1586 else:
1587 for aProcess in self.iter_processes():
1588 imagename = aProcess.get_filename()
1589 if imagename:
1590 imagename = PathOperations.pathname_to_filename(imagename)
1591 if imagename.lower() == filename:
1592 found.append( (aProcess, imagename) )
1593 return found
1594
1596 """
1597 @type fileName: str
1598 @param fileName: Filename to search for.
1599 If it's a full pathname, the match must be exact.
1600 If it's a base filename only, the file part is matched,
1601 regardless of the directory where it's located.
1602
1603 @note: If the process is not found and the file extension is not
1604 given, this method will search again assuming a default
1605 extension (.exe).
1606
1607 @rtype: list of tuple( L{Process}, str )
1608 @return: List of processes matching the given main module filename.
1609 Each tuple contains a Process object and it's filename.
1610 """
1611 found = self.__find_processes_by_filename(fileName)
1612 if not found:
1613 fn, ext = PathOperations.split_extension(fileName)
1614 if not ext:
1615 fileName = '%s.exe' % fn
1616 found = self.__find_processes_by_filename(fileName)
1617 return found
1618
1619
1620
1621
1622
1636
1638
1639
1640
1641 del self.__processDict[dwProcessId]
1642
1643
1671
1673 """
1674 Notify the termination of a process.
1675
1676 This is done automatically by the L{Debug} class, you shouldn't need
1677 to call it yourself.
1678
1679 @type event: L{ExitProcessEvent}
1680 @param event: Exit process event.
1681 """
1682 dwProcessId = event.get_pid()
1683
1684 if self.__processDict.has_key(dwProcessId):
1685 self.__del_process(dwProcessId)
1686 return True
1687
1691 """
1692 Class to manipulate memory addresses.
1693 """
1694
1695 @staticmethod
1697 """
1698 Align the given address to the start of the page it occupies.
1699
1700 @type address: int
1701 @param address: Memory address.
1702
1703 @rtype: int
1704 @return: Aligned memory address.
1705 """
1706 return address - ( address % System.pageSize )
1707
1708 @staticmethod
1710 """
1711 Align the given address to the end of the page it occupies.
1712
1713 @type address: int
1714 @param address: Memory address.
1715
1716 @rtype: int
1717 @return: Aligned memory address.
1718 """
1719 return address + System.pageSize - ( address % System.pageSize )
1720
1721 @classmethod
1723 """
1724 Align the given address range to the start and end of the page(s) it occupies.
1725
1726 @type begin: int
1727 @param begin: Memory address of the beginning of the buffer.
1728
1729 @type end: int
1730 @param end: Memory address of the end of the buffer.
1731
1732 @rtype: tuple( int, int )
1733 @return: Aligned memory addresses.
1734 """
1735 if end > begin:
1736 begin, end = end, begin
1737 return (
1738 cls.align_address_to_page_start(begin),
1739 cls.align_address_to_page_end(end)
1740 )
1741
1742 @classmethod
1743 - def get_buffer_size_in_pages(cls, address, size):
1744 """
1745 Get the number of pages in use by the given buffer.
1746
1747 @type address: int
1748 @param address: Aligned memory address.
1749
1750 @type size: int
1751 @param size: Buffer size.
1752
1753 @rtype: int
1754 @return: Buffer size in number of pages.
1755 """
1756 if size < 0:
1757 size = -size
1758 address = address - size
1759 begin, end = cls.align_address_range(address, address + size)
1760 return int(float(end - begin) / float(System.pageSize))
1761
1762 @staticmethod
1764 return (old_begin <= begin < old_end) or \
1765 (old_begin < end <= old_end) or \
1766 (begin <= old_begin < end) or \
1767 (begin < old_end <= end)
1768
1777 """
1778 Encapsulates the capabilities to manipulate the memory of a process.
1779
1780 @group Memory mapping:
1781 get_memory_map, malloc, free, mprotect, mquery, is_pointer,
1782 is_address_valid, is_address_free, is_address_reserved,
1783 is_address_commited, is_address_guard, is_address_readable,
1784 is_address_writeable, is_address_copy_on_write, is_address_executable,
1785 is_address_executable_and_writeable
1786
1787 @group Memory read:
1788 read, read_char, read_uint, read_pointer, read_structure,
1789 peek, peek_char, peek_uint, peek_pointer, peek_string
1790
1791 @group Memory write:
1792 write, write_char, write_uint, write_pointer,
1793 poke, poke_char, poke_uint, poke_pointer
1794 """
1795
1796
1797
1798
1799
1800 - def read(self, lpBaseAddress, nSize):
1801 """
1802 Reads from the memory of the process.
1803
1804 @see: L{peek}
1805
1806 @type lpBaseAddress: int
1807 @param lpBaseAddress: Memory address to begin reading.
1808
1809 @type nSize: int
1810 @param nSize: Number of bytes to read.
1811
1812 @rtype: str
1813 @return: Bytes read from the process memory.
1814
1815 @raise WindowsError: On error an exception is raised.
1816 """
1817 if not self.mquery(lpBaseAddress).has_content():
1818 raise ctypes.WinError(win32.ERROR_INVALID_ADDRESS)
1819 data = win32.ReadProcessMemory(self.get_handle(), lpBaseAddress, nSize)
1820 if len(data) != nSize:
1821 raise ctypes.WinError()
1822 return data
1823
1824
1825
1826 - def write(self, lpBaseAddress, lpBuffer):
1827 """
1828 Writes to the memory of the process.
1829
1830 @see: L{poke}
1831
1832 @type lpBaseAddress: int
1833 @param lpBaseAddress: Memory address to begin writing.
1834
1835 @type lpBuffer: int
1836 @param lpBuffer: Bytes to write.
1837
1838 @raise WindowsError: On error an exception is raised.
1839 """
1840 if not self.mquery(lpBaseAddress).has_content():
1841 raise ctypes.WinError(win32.ERROR_INVALID_ADDRESS)
1842 r = win32.WriteProcessMemory(self.get_handle(), lpBaseAddress, lpBuffer)
1843 if r != len(lpBuffer):
1844 raise ctypes.WinError()
1845
1847 """
1848 Reads a single unsigned integer from the memory of the process.
1849
1850 @see: L{peek}
1851
1852 @type lpBaseAddress: int
1853 @param lpBaseAddress: Memory address to begin reading.
1854
1855 @rtype: int
1856 @return: Integer value read from the process memory.
1857
1858 @raise WindowsError: On error an exception is raised.
1859 """
1860 packedDword = self.read(lpBaseAddress, 4)
1861 if len(packedDword) != 4:
1862 raise ctypes.WinError()
1863 unpackedDword = struct.unpack('<L', packedDword)[0]
1864 return unpackedDword
1865
1866 - def write_uint(self, lpBaseAddress, unpackedDword):
1867 """
1868 Writes a single unsigned integer to the memory of the process.
1869
1870 @see: L{poke_uint}
1871
1872 @type lpBaseAddress: int
1873 @param lpBaseAddress: Memory address to begin writing.
1874
1875 @type unpackedDword: int, long
1876 @param unpackedDword: Value to write.
1877
1878 @raise WindowsError: On error an exception is raised.
1879 """
1880 packedDword = struct.pack('<L', unpackedDword)
1881 self.write(lpBaseAddress, packedDword)
1882
1884 """
1885 Reads a single pointer value from the memory of the process.
1886
1887 @see: L{peek_pointer}
1888
1889 @type lpBaseAddress: int
1890 @param lpBaseAddress: Memory address to begin reading.
1891
1892 @rtype: int
1893 @return: Pointer value read from the process memory.
1894
1895 @raise WindowsError: On error an exception is raised.
1896 """
1897 lpvoidLength = win32.sizeof(win32.LPVOID)
1898 packedValue = self.read(lpBaseAddress, lpvoidLength)
1899 if lpvoidLength == 4:
1900 lpvoidFmt = '<L'
1901 else:
1902 lpvoidFmt = '<Q'
1903 unpackedValue = struct.unpack(lpvoidFmt, packedValue)[0]
1904 return unpackedValue
1905
1907 """
1908 Writes a single pointer value to the memory of the process.
1909
1910 @see: L{poke_pointer}
1911
1912 @type lpBaseAddress: int
1913 @param lpBaseAddress: Memory address to begin writing.
1914
1915 @type unpackedValue: int, long
1916 @param unpackedValue: Value to write.
1917
1918 @raise WindowsError: On error an exception is raised.
1919 """
1920 lpvoidLength = win32.sizeof(win32.LPVOID)
1921 if lpvoidLength == 4:
1922 lpvoidFmt = '<L'
1923 else:
1924 lpvoidFmt = '<Q'
1925 packedValue = struct.pack(lpvoidFmt, unpackedValue)
1926 self.write(lpBaseAddress, packedValue)
1927
1929 """
1930 Reads a single character to the memory of the process.
1931
1932 @see: L{write_char}
1933
1934 @type lpBaseAddress: int
1935 @param lpBaseAddress: Memory address to begin writing.
1936
1937 @rtype: int
1938 @return: Character value read from the process memory.
1939
1940 @raise WindowsError: On error an exception is raised.
1941 """
1942 return ord( self.read(lpBaseAddress, 1) )
1943
1945 """
1946 Writes a single character to the memory of the process.
1947
1948 @see: L{write_char}
1949
1950 @type lpBaseAddress: int
1951 @param lpBaseAddress: Memory address to begin writing.
1952
1953 @type char: int
1954 @param char: Character to write.
1955
1956 @raise WindowsError: On error an exception is raised.
1957 """
1958 self.write(lpBaseAddress, chr(char))
1959
1961 """
1962 Reads a ctypes structure from the memory of the process.
1963
1964 @see: L{read}
1965
1966 @type lpBaseAddress: int
1967 @param lpBaseAddress: Memory address to begin reading.
1968
1969 @type stype: class ctypes.Structure or a subclass.
1970 @param stype: Structure definition.
1971
1972 @rtype: int
1973 @return: Structure instance filled in with data
1974 read from the process memory.
1975
1976 @raise WindowsError: On error an exception is raised.
1977 """
1978 if type(lpBaseAddress) not in (type(0), type(0L)):
1979 lpBaseAddress = ctypes.cast(lpBaseAddress, ctypes.c_void_p)
1980 data = self.read(lpBaseAddress, ctypes.sizeof(stype))
1981 buff = ctypes.create_string_buffer(data)
1982 ptr = ctypes.cast(ctypes.pointer(buff), ctypes.POINTER(stype))
1983 return ptr.contents
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009 - def read_string(self, lpBaseAddress, nChars, fUnicode = False):
2010 """
2011 Reads an ASCII or Unicode string
2012 from the address space of the process.
2013
2014 @see: L{read}
2015
2016 @type lpBaseAddress: int
2017 @param lpBaseAddress: Memory address to begin reading.
2018
2019 @type nChars: int
2020 @param nChars: String length to read, in characters.
2021 Remember that Unicode strings have two byte characters.
2022
2023 @type fUnicode: bool
2024 @param fUnicode: C{True} is the string is expected to be Unicode,
2025 C{False} if it's expected to be ANSI.
2026
2027 @rtype: str, unicode
2028 @return: String read from the process memory space.
2029
2030 @raise WindowsError: On error an exception is raised.
2031 """
2032 if fUnicode:
2033 nChars = nChars * 2
2034 szString = self.read(lpBaseAddress, nChars)
2035 if fUnicode:
2036 szString = unicode(szString, 'U16', 'ignore')
2037 return szString
2038
2039
2040
2041 - def peek(self, lpBaseAddress, nSize):
2042 """
2043 Reads the memory of the process.
2044
2045 @see: L{read}
2046
2047 @type lpBaseAddress: int
2048 @param lpBaseAddress: Memory address to begin reading.
2049
2050 @type nSize: int
2051 @param nSize: Number of bytes to read.
2052
2053 @rtype: str
2054 @return: Bytes read from the process memory.
2055 Returns an empty string on error.
2056 """
2057 data = ''
2058 if nSize > 0:
2059 try:
2060 data = win32.ReadProcessMemory(self.get_handle(),
2061 lpBaseAddress, nSize)
2062 except WindowsError:
2063 pass
2064 return data
2065
2066 - def poke(self, lpBaseAddress, lpBuffer):
2067 """
2068 Writes to the memory of the process.
2069
2070 @see: L{write}
2071
2072 @type lpBaseAddress: int
2073 @param lpBaseAddress: Memory address to begin writing.
2074
2075 @type lpBuffer: str
2076 @param lpBuffer: Bytes to write.
2077
2078 @rtype: int
2079 @return: Number of bytes written.
2080 May be less than the number of bytes to write.
2081 """
2082 try:
2083 bytesWritten = win32.WriteProcessMemory(self.get_handle(),
2084 lpBaseAddress, lpBuffer)
2085 except WindowsError:
2086 bytesWritten = 0
2087 return bytesWritten
2088
2090 """
2091 Reads a single unsigned integer from the memory of the process.
2092
2093 @see: L{read_uint}
2094
2095 @type lpBaseAddress: int
2096 @param lpBaseAddress: Memory address to begin reading.
2097
2098 @rtype: int
2099 @return: Integer value read from the process memory.
2100 Returns zero on error.
2101 """
2102 dwordLength = win32.sizeof(win32.UINT)
2103 packedDword = self.peek(lpBaseAddress, dwordLength)
2104 if len(packedDword) < dwordLength:
2105 packedDword += '\x00' * (dwordLength - len(packedDword))
2106 unpackedDword = struct.unpack('<L', packedDword)[0]
2107 return unpackedDword
2108
2109 - def poke_uint(self, lpBaseAddress, unpackedDword):
2110 """
2111 Writes a single unsigned integer to the memory of the process.
2112
2113 @see: L{write_uint}
2114
2115 @type lpBaseAddress: int
2116 @param lpBaseAddress: Memory address to begin writing.
2117
2118 @type unpackedDword: int, long
2119 @param unpackedDword: Value to write.
2120
2121 @rtype: int
2122 @return: Number of bytes written.
2123 May be less than the number of bytes to write.
2124 """
2125 packedDword = struct.pack('<L', unpackedDword)
2126 dwBytesWritten = self.poke(lpBaseAddress, packedDword)
2127 return dwBytesWritten
2128
2130 """
2131 Reads a single pointer value from the memory of the process.
2132
2133 @see: L{read_pointer}
2134
2135 @type lpBaseAddress: int
2136 @param lpBaseAddress: Memory address to begin reading.
2137
2138 @rtype: int
2139 @return: Pointer value read from the process memory.
2140 Returns zero on error.
2141 """
2142 lpvoidLength = win32.sizeof(win32.LPVOID)
2143 packedValue = self.read(lpBaseAddress, lpvoidLength)
2144 if len(packedValue) < lpvoidLength:
2145 packedValue += '\x00' * (lpvoidLength - len(packedValue))
2146 if lpvoidLength == 4:
2147 lpvoidFmt = '<L'
2148 else:
2149 lpvoidFmt = '<Q'
2150 unpackedValue = struct.unpack(lpvoidFmt, packedValue)[0]
2151 return unpackedValue
2152
2154 """
2155 Writes a single pointer value to the memory of the process.
2156
2157 @see: L{write_pointer}
2158
2159 @type lpBaseAddress: int
2160 @param lpBaseAddress: Memory address to begin writing.
2161
2162 @type unpackedValue: int, long
2163 @param unpackedValue: Value to write.
2164
2165 @rtype: int
2166 @return: Number of bytes written.
2167 May be less than the number of bytes to write.
2168 """
2169 lpvoidLength = win32.sizeof(win32.LPVOID)
2170 if lpvoidLength == 4:
2171 lpvoidFmt = '<L'
2172 else:
2173 lpvoidFmt = '<Q'
2174 packedValue = struct.pack(lpvoidFmt, unpackedValue)
2175 dwBytesWritten = self.poke(lpBaseAddress, packedValue)
2176 return dwBytesWritten
2177
2179 """
2180 Reads a single character from the memory of the process.
2181
2182 @see: L{read_char}
2183
2184 @type lpBaseAddress: int
2185 @param lpBaseAddress: Memory address to begin reading.
2186
2187 @rtype: int
2188 @return: Character read from the process memory.
2189 Returns zero on error.
2190 """
2191 char = self.peek(lpBaseAddress, 1)
2192 if char:
2193 return ord(char)
2194 return 0
2195
2197 """
2198 Writes a single character to the memory of the process.
2199
2200 @see: L{write_char}
2201
2202 @type lpBaseAddress: int
2203 @param lpBaseAddress: Memory address to begin writing.
2204
2205 @type char: str
2206 @param char: Character to write.
2207
2208 @rtype: int
2209 @return: Number of bytes written.
2210 May be less than the number of bytes to write.
2211 """
2212 return self.poke(lpBaseAddress, chr(char))
2213
2214 - def peek_string(self, lpBaseAddress, fUnicode = False, dwMaxSize = 0x1000):
2215 """
2216 Tries to read an ASCII or Unicode string
2217 from the address space of the process.
2218
2219 @see: L{peek}
2220
2221 @type lpBaseAddress: int
2222 @param lpBaseAddress: Memory address to begin reading.
2223
2224 @type fUnicode: bool
2225 @param fUnicode: C{True} is the string is expected to be Unicode,
2226 C{False} if it's expected to be ANSI.
2227
2228 @type dwMaxSize: int
2229 @param dwMaxSize: Maximum allowed string length to read, in bytes.
2230
2231 @rtype: str, unicode
2232 @return: String read from the process memory space.
2233 It doesn't include the terminating null character.
2234 Returns an empty string on failure.
2235 """
2236
2237
2238
2239 szString = self.peek(lpBaseAddress, dwMaxSize)
2240 if fUnicode:
2241 szString = unicode(szString, 'U16', 'ignore')
2242 szString = ctypes.create_unicode_buffer(szString).value
2243 else:
2244 szString = ctypes.create_string_buffer(szString).value
2245 return szString
2246
2247
2248
2250 """
2251 Allocates memory into the address space of the process.
2252
2253 @see: L{free}
2254
2255 @type dwSize: int
2256 @param dwSize: Number of bytes to allocate.
2257
2258 @type lpAddress: int
2259 @param lpAddress: (Optional)
2260 Desired address for the newly allocated memory.
2261 This is only a hint, the memory could still be allocated somewhere
2262 else.
2263
2264 @rtype: int
2265 @return: Address of the newly allocated memory.
2266
2267 @raise WindowsError: On error an exception is raised.
2268 """
2269 return win32.VirtualAllocEx(self.get_handle(), lpAddress, dwSize)
2270
2271 - def mprotect(self, lpAddress, dwSize, flNewProtect):
2272 """
2273 Set memory protection in the address space of the process.
2274
2275 @see: U{http://msdn.microsoft.com/en-us/library/aa366899.aspx}
2276
2277 @type lpAddress: int
2278 @param lpAddress: Address of memory to protect.
2279
2280 @type dwSize: int
2281 @param dwSize: Number of bytes to protect.
2282
2283 @type flNewProtect: int
2284 @param flNewProtect: New protect flags.
2285
2286 @rtype: int
2287 @return: Old protect flags.
2288
2289 @raise WindowsError: On error an exception is raised.
2290 """
2291 return win32.VirtualProtectEx(self.get_handle(), lpAddress, dwSize,
2292 flNewProtect)
2293
2294 - def mquery(self, lpAddress):
2295 """
2296 Query memory information from the address space of the process.
2297 Returns a L{win32.MemoryBasicInformation} object.
2298
2299 @see: U{http://msdn.microsoft.com/en-us/library/aa366907(VS.85).aspx}
2300
2301 @type lpAddress: int
2302 @param lpAddress: Address of memory to query.
2303
2304 @rtype: L{win32.MemoryBasicInformation}
2305 @return: Memory region information.
2306
2307 @raise WindowsError: On error an exception is raised.
2308 """
2309 return win32.VirtualQueryEx(self.get_handle(), lpAddress)
2310
2311 - def free(self, lpAddress, dwSize = 0):
2312 """
2313 Frees memory from the address space of the process.
2314
2315 @see: L{malloc}
2316
2317 @type lpAddress: int
2318 @param lpAddress: Address of memory to free.
2319
2320 @type dwSize: int
2321 @param dwSize: (Optional) Number of bytes to free.
2322
2323 @rtype: bool
2324 @return: C{True} on success, C{False} on error.
2325 """
2326 success = win32.VirtualFreeEx(self.get_handle(), lpAddress, dwSize)
2327 return bool(success)
2328
2329
2330
2332 """
2333 Determines if an address is a valid code or data pointer.
2334
2335 That is, the address must be valid and must point to code or data in
2336 the target process.
2337
2338 @type address: int
2339 @param address: Memory address to query.
2340
2341 @rtype: bool
2342 @return: C{True} if the address is a valid code or data pointer.
2343
2344 @raise WindowsError: An exception is raised on error.
2345 """
2346 try:
2347 mbi = self.mquery(address)
2348 except WindowsError, e:
2349 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2350 return False
2351 raise
2352 return mbi.has_content()
2353
2355 """
2356 Determines if an address is a valid user mode address.
2357
2358 @type address: int
2359 @param address: Memory address to query.
2360
2361 @rtype: bool
2362 @return: C{True} if the address is a valid user mode address.
2363
2364 @raise WindowsError: An exception is raised on error.
2365 """
2366 try:
2367 mbi = self.mquery(address)
2368 except WindowsError, e:
2369 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2370 return False
2371 raise
2372 return True
2373
2375 """
2376 Determines if an address belongs to a free page.
2377
2378 @note: Returns always C{False} for kernel mode addresses.
2379
2380 @type address: int
2381 @param address: Memory address to query.
2382
2383 @rtype: bool
2384 @return: C{True} if the address belongs to a free page.
2385
2386 @raise WindowsError: An exception is raised on error.
2387 """
2388 try:
2389 mbi = self.mquery(address)
2390 except WindowsError, e:
2391 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2392 return False
2393 raise
2394 return mbi.is_free()
2395
2397 """
2398 Determines if an address belongs to a reserved page.
2399
2400 @note: Returns always C{False} for kernel mode addresses.
2401
2402 @type address: int
2403 @param address: Memory address to query.
2404
2405 @rtype: bool
2406 @return: C{True} if the address belongs to a reserved page.
2407
2408 @raise WindowsError: An exception is raised on error.
2409 """
2410 try:
2411 mbi = self.mquery(address)
2412 except WindowsError, e:
2413 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2414 return False
2415 raise
2416 return mbi.is_reserved()
2417
2419 """
2420 Determines if an address belongs to a commited page.
2421
2422 @note: Returns always C{False} for kernel mode addresses.
2423
2424 @type address: int
2425 @param address: Memory address to query.
2426
2427 @rtype: bool
2428 @return: C{True} if the address belongs to a commited page.
2429
2430 @raise WindowsError: An exception is raised on error.
2431 """
2432 try:
2433 mbi = self.mquery(address)
2434 except WindowsError, e:
2435 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2436 return False
2437 raise
2438 return mbi.is_commited()
2439
2441 """
2442 Determines if an address belongs to a guard page.
2443
2444 @note: Returns always C{False} for kernel mode addresses.
2445
2446 @type address: int
2447 @param address: Memory address to query.
2448
2449 @rtype: bool
2450 @return: C{True} if the address belongs to a guard page.
2451
2452 @raise WindowsError: An exception is raised on error.
2453 """
2454 try:
2455 mbi = self.mquery(address)
2456 except WindowsError, e:
2457 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2458 return False
2459 raise
2460 return mbi.is_guard()
2461
2463 """
2464 Determines if an address belongs to a commited and readable page.
2465 The page may or may not have additional permissions.
2466
2467 @note: Returns always C{False} for kernel mode addresses.
2468
2469 @type address: int
2470 @param address: Memory address to query.
2471
2472 @rtype: bool
2473 @return:
2474 C{True} if the address belongs to a commited and readable page.
2475
2476 @raise WindowsError: An exception is raised on error.
2477 """
2478 try:
2479 mbi = self.mquery(address)
2480 except WindowsError, e:
2481 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2482 return False
2483 raise
2484 return mbi.is_readable()
2485
2487 """
2488 Determines if an address belongs to a commited and writeable page.
2489 The page may or may not have additional permissions.
2490
2491 @note: Returns always C{False} for kernel mode addresses.
2492
2493 @type address: int
2494 @param address: Memory address to query.
2495
2496 @rtype: bool
2497 @return:
2498 C{True} if the address belongs to a commited and writeable page.
2499
2500 @raise WindowsError: An exception is raised on error.
2501 """
2502 try:
2503 mbi = self.mquery(address)
2504 except WindowsError, e:
2505 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2506 return False
2507 raise
2508 return mbi.is_writeable()
2509
2511 """
2512 Determines if an address belongs to a commited, copy-on-write page.
2513 The page may or may not have additional permissions.
2514
2515 @note: Returns always C{False} for kernel mode addresses.
2516
2517 @type address: int
2518 @param address: Memory address to query.
2519
2520 @rtype: bool
2521 @return:
2522 C{True} if the address belongs to a commited, copy-on-write page.
2523
2524 @raise WindowsError: An exception is raised on error.
2525 """
2526 try:
2527 mbi = self.mquery(address)
2528 except WindowsError, e:
2529 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2530 return False
2531 raise
2532 return mbi.is_copy_on_write()
2533
2535 """
2536 Determines if an address belongs to a commited and executable page.
2537 The page may or may not have additional permissions.
2538
2539 @note: Returns always C{False} for kernel mode addresses.
2540
2541 @type address: int
2542 @param address: Memory address to query.
2543
2544 @rtype: bool
2545 @return:
2546 C{True} if the address belongs to a commited and executable page.
2547
2548 @raise WindowsError: An exception is raised on error.
2549 """
2550 try:
2551 mbi = self.mquery(address)
2552 except WindowsError, e:
2553 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2554 return False
2555 raise
2556 return mbi.is_executable()
2557
2559 """
2560 Determines if an address belongs to a commited, writeable and
2561 executable page. The page may or may not have additional permissions.
2562
2563 Looking for writeable and executable pages is important when
2564 exploiting a software vulnerability.
2565
2566 @note: Returns always C{False} for kernel mode addresses.
2567
2568 @type address: int
2569 @param address: Memory address to query.
2570
2571 @rtype: bool
2572 @return:
2573 C{True} if the address belongs to a commited, writeable and
2574 executable page.
2575
2576 @raise WindowsError: An exception is raised on error.
2577 """
2578 try:
2579 mbi = self.mquery(address)
2580 except WindowsError, e:
2581 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2582 return False
2583 raise
2584 return mbi.is_executable_and_writeable()
2585
2587 """
2588 Produces a memory map to the process address space.
2589 Optionally restrict the map to the given address range.
2590
2591 @see: L{mquery}
2592
2593 @type minAddr: int
2594 @param minAddr: (Optional) Starting address in address range to query.
2595
2596 @type maxAddr: int
2597 @param maxAddr: (Optional) Ending address in address range to query.
2598
2599 @rtype: list( L{win32.MemoryBasicInformation} )
2600 @return: List of memory region information objects.
2601 """
2602 if minAddr is None:
2603 minAddr = 0
2604 if maxAddr is None:
2605 maxAddr = win32.LPVOID(-1).value
2606 if minAddr > maxAddr:
2607 minAddr, maxAddr = maxAddr, minAddr
2608 minAddr = MemoryAddresses.align_address_to_page_start(minAddr)
2609 maxAddr = MemoryAddresses.align_address_to_page_end(maxAddr)
2610 prevAddr = minAddr
2611 currentAddr = minAddr
2612 memoryMap = list()
2613 while currentAddr <= maxAddr and currentAddr >= prevAddr:
2614 try:
2615 mbi = self.mquery(currentAddr)
2616 except WindowsError, e:
2617 if e.winerror == win32.ERROR_INVALID_PARAMETER:
2618 break
2619 raise
2620 memoryMap.append(mbi)
2621 prevAddr = currentAddr
2622 currentAddr = mbi.BaseAddress + mbi.RegionSize
2623 return memoryMap
2624
2626 """
2627 Retrieves the filenames for memory mapped files in the debugee.
2628
2629 @type memoryMap: list( L{win32.MemoryBasicInformation} )
2630 @param memoryMap: (Optional) Memory map returned by L{get_memory_map}.
2631 If not given, the current memory map is used.
2632
2633 @rtype: dict( int S{->} str )
2634 @return: Dictionary mapping memory addresses to file names.
2635 Native filenames are converted to Win32 filenames when possible.
2636 """
2637 hProcess = self.get_handle()
2638 if not memoryMap:
2639 memoryMap = self.get_memory_map()
2640 mappedFilenames = dict()
2641 for mbi in memoryMap:
2642
2643
2644
2645 if mbi.Type not in (win32.MEM_IMAGE, win32.MEM_MAPPED):
2646 continue
2647
2648 baseAddress = mbi.BaseAddress
2649 fileName = ""
2650 try:
2651 fileName = win32.GetMappedFileName(hProcess, baseAddress)
2652 fileName = PathOperations.native_to_win32_pathname(fileName)
2653 except WindowsError, e:
2654
2655 pass
2656 mappedFilenames[baseAddress] = fileName
2657 return mappedFilenames
2658
2660 """
2661 Takes a snapshot of the memory contents of the process.
2662
2663 @type minAddr: int
2664 @param minAddr: (Optional) Starting address in address range to query.
2665
2666 @type maxAddr: int
2667 @param maxAddr: (Optional) Ending address in address range to query.
2668
2669 @rtype: list( L{win32.MemoryBasicInformation} )
2670 @return: List of memory region information objects.
2671 Two extra properties are added to these objects:
2672 - C{filename}: Mapped filename, or C{None}.
2673 - C{content}: Memory contents, or C{None}.
2674 """
2675 snapshot = self.get_memory_map(minAddr, maxAddr)
2676 filenames = self.get_mapped_filenames(snapshot)
2677 for mbi in snapshot:
2678 mbi.filename = filenames.get(mbi.BaseAddress, None)
2679 if mbi.has_content():
2680 mbi.content = self.read(mbi.BaseAddress, mbi.RegionSize)
2681 else:
2682 mbi.content = None
2683 return snapshot
2684
2686 """
2687 Attempts to restore the memory state as it was when the given snapshot
2688 was taken.
2689
2690 @warning: Currently only the memory contents, state and protect bits
2691 are restored. Under some circumstances this method may fail (for
2692 example if memory was freed and then reused by a mapped file).
2693
2694 @type snapshot: list( L{win32.MemoryBasicInformation} )
2695 @param snapshot: Memory snapshot returned by L{take_memory_snapshot}.
2696
2697 @raise WindowsError: An error occured while restoring the snapshot.
2698 @raise RuntimeError: An error occured while restoring the snapshot.
2699 """
2700
2701
2702 hProcess = self.get_handle()
2703
2704
2705 self.suspend()
2706 try:
2707
2708
2709 for old_mbi in snapshot:
2710
2711
2712 new_mbi = self.mquery(old_mbi.BaseAddress)
2713 if new_mbi.BaseAddress == old_mbi.BaseAddress and new_mbi.RegionSize == old_mbi.RegionSize:
2714 self.__restore_mbi(hProcess, new_mbi, old_mbi)
2715
2716
2717 else:
2718 start = old_mbi.BaseAddress
2719 end = start + old_mbi.RegionSize
2720 for address in xrange(start, end, System.pageSize):
2721 new_mbi = self.mquery(address)
2722 self.__restore_mbi(hProcess, new_mbi, old_mbi)
2723
2724
2725 finally:
2726 self.resume()
2727
2729 """
2730 Used internally by L{restore_memory_snapshot}.
2731 """
2732
2733
2734
2735
2736 if new_mbi.State != old_mbi.State:
2737 if new_mbi.is_free():
2738 if old_mbi.is_reserved():
2739 address = win32.VirtualAllocEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_RESERVE, old_mbi.Protect)
2740 if address != old_mbi.BaseAddress:
2741 self.free(address)
2742 msg = "Error restoring region at address %s"
2743 msg = msg % HexDump(old_mbi.BaseAddress)
2744 raise RuntimeError, msg
2745 new_mbi.Protect = old_mbi.Protect
2746 else:
2747 address = win32.VirtualAllocEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_RESERVE | win32.MEM_COMMIT, old_mbi.Protect)
2748 if address != old_mbi.BaseAddress:
2749 self.free(address)
2750 msg = "Error restoring region at address %s"
2751 msg = msg % HexDump(old_mbi.BaseAddress)
2752 raise RuntimeError, msg
2753 new_mbi.Protect = old_mbi.Protect
2754 elif new_mbi.is_reserved():
2755 if old_mbi.is_commited():
2756 address = win32.VirtualAllocEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_COMMIT, old_mbi.Protect)
2757 if address != old_mbi.BaseAddress:
2758 self.free(address)
2759 msg = "Error restoring region at address %s"
2760 msg = msg % HexDump(old_mbi.BaseAddress)
2761 raise RuntimeError, msg
2762 new_mbi.Protect = old_mbi.Protect
2763 else:
2764 win32.VirtualFreeEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_RELEASE)
2765 else:
2766 if old_mbi.is_reserved():
2767 win32.VirtualFreeEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_DECOMMIT)
2768 else:
2769 win32.VirtualFreeEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_DECOMMIT | win32.MEM_RELEASE)
2770
2771
2772 if old_mbi.Protect != new_mbi.Protect:
2773 win32.VirtualProtectEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, old_mbi.Protect)
2774
2775
2776
2777 if old_mbi.has_content():
2778 if old_mbi.Type != 0:
2779 self.poke(old_mbi.BaseAddress, old_mbi.content)
2780 else:
2781 self.write(old_mbi.BaseAddress, old_mbi.content)
2782
2786 """
2787 Internally used by L{SymbolContainer} to enumerate symbols in a module.
2788 """
2789
2791 self.symbols = list()
2792
2793 - def __call__(self, SymbolName, SymbolAddress, SymbolSize, UserContext):
2794 """
2795 Callback that receives symbols and stores them in a Python list.
2796 """
2797
2798
2799
2800
2801 self.symbols.append( (SymbolName, SymbolAddress, SymbolSize) )
2802 return win32.TRUE
2803
2805 """
2806 Capability to contain symbols. Used by L{Module}.
2807
2808 @group Symbols:
2809 load_symbols, unload_symbols, get_symbols, iter_symbols,
2810 resolve_symbol, get_symbol_at_address
2811 """
2812
2814 self.__symbols = list()
2815
2816
2817
2818
2819
2821 """
2822 Loads the debugging symbols for a module.
2823 Automatically called by L{get_symbols}.
2824 """
2825 hProcess = self.get_process().get_handle()
2826 hFile = self.hFile
2827 BaseOfDll = self.get_base()
2828 SizeOfDll = self.get_size()
2829 Enumerator = SymbolEnumerator()
2830 try:
2831 win32.SymInitialize(hProcess)
2832 SymOptions = win32.SymGetOptions()
2833 win32.SymSetOptions(SymOptions | \
2834 win32.SYMOPT_ALLOW_ZERO_ADDRESS | \
2835 win32.SYMOPT_CASE_INSENSITIVE | \
2836 win32.SYMOPT_FAVOR_COMPRESSED | \
2837 win32.SYMOPT_INCLUDE_32BIT_MODULES | \
2838 win32.SYMOPT_UNDNAME)
2839 try:
2840 win32.SymSetOptions(SymOptions | win32.SYMOPT_ALLOW_ABSOLUTE_SYMBOLS)
2841 except WindowsError:
2842 pass
2843 try:
2844 try:
2845 win32.SymLoadModule64(hProcess, hFile, None, None, BaseOfDll, SizeOfDll)
2846 except WindowsError:
2847 ImageName = self.get_filename()
2848 win32.SymLoadModule64(hProcess, None, ImageName, None, BaseOfDll, SizeOfDll)
2849 try:
2850 win32.SymEnumerateSymbols64(hProcess, BaseOfDll, Enumerator)
2851 finally:
2852 win32.SymUnloadModule64(hProcess, BaseOfDll)
2853 finally:
2854 win32.SymCleanup(hProcess)
2855 except WindowsError, e:
2856
2857
2858 pass
2859 self.__symbols = Enumerator.symbols
2860
2862 """
2863 Unloads the debugging symbols for a module.
2864 """
2865 self.__symbols = list()
2866
2868 """
2869 Returns the debugging symbols for a module.
2870 The symbols are automatically loaded when needed.
2871
2872 @rtype: list of tuple( str, int, int )
2873 @return: List of symbols.
2874 Each symbol is represented by a tuple that contains:
2875 - Symbol name
2876 - Symbol memory address
2877 - Symbol size in bytes
2878 """
2879 if not self.__symbols:
2880 self.load_symbols()
2881 return list(self.__symbols)
2882
2884 """
2885 Returns an iterator for the debugging symbols in a module,
2886 in no particular order.
2887 The symbols are automatically loaded when needed.
2888
2889 @rtype: iterator of tuple( str, int, int )
2890 @return: Iterator of symbols.
2891 Each symbol is represented by a tuple that contains:
2892 - Symbol name
2893 - Symbol memory address
2894 - Symbol size in bytes
2895 """
2896 if not self.__symbols:
2897 self.load_symbols()
2898 return self.__symbols.__iter__()
2899
2901 """
2902 Resolves a debugging symbol's address.
2903
2904 @type symbol: str
2905 @param symbol: Name of the symbol to resolve.
2906
2907 @type bCaseSensitive: bool
2908 @param bCaseSensitive: C{True} for case sensitive matches,
2909 C{False} for case insensitive.
2910
2911 @rtype: int or None
2912 @return: Memory address of symbol. C{None} if not found.
2913 """
2914 if bCaseSensitive:
2915 for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols():
2916 if symbol == SymbolName:
2917 return SymbolAddress
2918 else:
2919 symbol = symbol.lower()
2920 for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols():
2921 if symbol == SymbolName.lower():
2922 return SymbolAddress
2923
2925 found = None
2926 for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols():
2927 if SymbolAddress > address:
2928 continue
2929 if SymbolAddress + SymbolSize > address:
2930 if not found or found[1] < SymbolAddress:
2931 found = (SymbolName, SymbolAddress, SymbolSize)
2932 return found
2933
2937 """
2938 Encapsulates symbol operations capabilities.
2939
2940 Requires a L{ModuleContainer}.
2941
2942 @note: Labels are an approximated way of referencing memory locations
2943 across different executions of the same process, or different processes
2944 with common modules. They are not meant to be perfectly unique, and
2945 some errors may occur when multiple modules with the same name are
2946 loaded, or when module filenames can't be retrieved.
2947
2948 Read more on labels here:
2949 U{http://apps.sourceforge.net/trac/winappdbg/wiki/HowLabelsWork}
2950
2951 @group Labels:
2952 parse_label,
2953 split_label,
2954 sanitize_label,
2955 resolve_label,
2956 get_label_at_address,
2957 split_label_strict,
2958 split_label_fuzzy
2959
2960 @group Symbols:
2961 load_symbols, unload_symbols, get_symbols, iter_symbols,
2962 resolve_symbol, get_symbol_at_address
2963
2964 @group Debugging:
2965 get_system_breakpoint, get_user_breakpoint, get_breakin_breakpoint,
2966 is_system_defined_breakpoint
2967 """
2968
2974
2975 @staticmethod
2976 - def parse_label(module = None, function = None, offset = None):
2977 """
2978 Creates a label from a module and a function name, plus an offset.
2979
2980 @warning: This method only parses the label, it doesn't make sure the
2981 label actually points to a valid memory location.
2982
2983 @type module: None or str
2984 @param module: (Optional) Module name.
2985
2986 @type function: None, str or int
2987 @param function: (Optional) Function name or ordinal.
2988
2989 @type offset: None or int
2990 @param offset: (Optional) Offset value.
2991
2992 If C{function} is specified, offset from the function.
2993
2994 If C{function} is C{None}, offset from the module.
2995
2996 @rtype: str
2997 @return:
2998 Label representing the given function in the given module.
2999
3000 @raise ValueError:
3001 The module or function name contain invalid characters.
3002 """
3003
3004
3005
3006
3007
3008 try:
3009 function = "#0x%x" % function
3010 except TypeError:
3011 pass
3012
3013
3014 if module is not None and ('!' in module or '+' in module):
3015 raise ValueError, "Invalid module name: %s" % module
3016 if function is not None and ('!' in function or '+' in function):
3017 raise ValueError, "Invalid function name: %s" % function
3018
3019
3020 if module:
3021 if function:
3022 if offset:
3023 label = "%s!%s+0x%x" % (module, function, offset)
3024 else:
3025 label = "%s!%s" % (module, function)
3026 else:
3027 if offset:
3028
3029 label = "%s!0x%x" % (module, offset)
3030 else:
3031 label = "%s!" % module
3032 else:
3033 if function:
3034 if offset:
3035 label = "!%s+0x%x" % (function, offset)
3036 else:
3037 label = "!%s" % function
3038 else:
3039 if offset:
3040 label = "0x%x" % offset
3041 else:
3042 label = "0x0"
3043
3044 return label
3045
3046 @staticmethod
3048 """
3049 Splits a label created with L{parse_label}.
3050
3051 To parse labels with a less strict syntax, use the L{split_label_fuzzy}
3052 method instead.
3053
3054 @warning: This method only parses the label, it doesn't make sure the
3055 label actually points to a valid memory location.
3056
3057 @type label: str
3058 @param label: Label to split.
3059
3060 @rtype: tuple( str or None, str or int or None, int or None )
3061 @return: Tuple containing the C{module} name,
3062 the C{function} name or ordinal, and the C{offset} value.
3063
3064 If the label doesn't specify a module,
3065 then C{module} is C{None}.
3066
3067 If the label doesn't specify a function,
3068 then C{function} is C{None}.
3069
3070 If the label doesn't specify an offset,
3071 then C{offset} is C{0}.
3072
3073 @raise ValueError: The label is malformed.
3074 """
3075 module = function = None
3076 offset = 0
3077
3078
3079 if not label:
3080 label = "0x0"
3081 else:
3082
3083
3084 label = label.replace(' ', '')
3085 label = label.replace('\t', '')
3086 label = label.replace('\r', '')
3087 label = label.replace('\n', '')
3088
3089
3090 if not label:
3091 label = "0x0"
3092
3093
3094 if '!' in label:
3095 try:
3096 module, function = label.split('!')
3097 except ValueError:
3098 raise ValueError, "Malformed label: %s" % label
3099
3100
3101 if function:
3102 if '+' in module:
3103 raise ValueError, "Malformed label: %s" % label
3104
3105
3106 if '+' in function:
3107 try:
3108 function, offset = function.split('+')
3109 except ValueError:
3110 raise ValueError, "Malformed label: %s" % label
3111 try:
3112 offset = HexInput.integer(offset)
3113 except ValueError:
3114 raise ValueError, "Malformed label: %s" % label
3115 else:
3116
3117
3118 try:
3119 offset = HexInput.integer(function)
3120 function = None
3121 except ValueError:
3122 pass
3123 else:
3124
3125
3126 if '+' in module:
3127 try:
3128 module, offset = module.split('+')
3129 except ValueError:
3130 raise ValueError, "Malformed label: %s" % label
3131 try:
3132 offset = HexInput.integer(offset)
3133 except ValueError:
3134 raise ValueError, "Malformed label: %s" % label
3135
3136 else:
3137
3138
3139 try:
3140 offset = HexInput.integer(module)
3141 module = None
3142
3143
3144 except ValueError:
3145 pass
3146
3147 if not module:
3148 module = None
3149 if not function:
3150 function = None
3151
3152
3153 else:
3154
3155
3156 try:
3157 offset = HexInput.integer(label)
3158
3159
3160 except ValueError:
3161 if label.startswith('#'):
3162 function = label
3163 try:
3164 HexInput.integer(function[1:])
3165
3166
3167
3168 except ValueError:
3169 raise ValueError, "Ambiguous label: %s" % label
3170
3171
3172
3173 else:
3174 raise ValueError, "Ambiguous label: %s" % label
3175
3176
3177 if function and function.startswith('#'):
3178 try:
3179 function = HexInput.integer(function[1:])
3180 except ValueError:
3181 pass
3182
3183
3184 if not offset:
3185 offset = None
3186
3187 return (module, function, offset)
3188
3190 """
3191 Splits a label entered as user input.
3192
3193 It's more flexible in it's syntax parsing than the L{split_label_strict}
3194 method, as it allows the exclamation mark (B{C{!}}) to be omitted. The
3195 ambiguity is resolved by searching the modules in the snapshot to guess
3196 if a label refers to a module or a function. It also tries to rebuild
3197 labels when they contain hardcoded addresses.
3198
3199 @warning: This method only parses the label, it doesn't make sure the
3200 label actually points to a valid memory location.
3201
3202 @type label: str
3203 @param label: Label to split.
3204
3205 @rtype: tuple( str or None, str or int or None, int or None )
3206 @return: Tuple containing the C{module} name,
3207 the C{function} name or ordinal, and the C{offset} value.
3208
3209 If the label doesn't specify a module,
3210 then C{module} is C{None}.
3211
3212 If the label doesn't specify a function,
3213 then C{function} is C{None}.
3214
3215 If the label doesn't specify an offset,
3216 then C{offset} is C{0}.
3217
3218 @raise ValueError: The label is malformed.
3219 """
3220 module = function = None
3221 offset = 0
3222
3223
3224 if not label:
3225 label = "0x0"
3226 else:
3227
3228
3229 label = label.replace(' ', '')
3230 label = label.replace('\t', '')
3231 label = label.replace('\r', '')
3232 label = label.replace('\n', '')
3233
3234
3235 if not label:
3236 label = "0x0"
3237
3238
3239 if '!' in label:
3240 return self.split_label_strict(label)
3241
3242
3243
3244
3245
3246
3247
3248
3249 if '+' in label:
3250 try:
3251 prefix, offset = label.split('+')
3252 except ValueError:
3253 raise ValueError, "Malformed label: %s" % label
3254 try:
3255 offset = HexInput.integer(offset)
3256 except ValueError:
3257 raise ValueError, "Malformed label: %s" % label
3258 label = prefix
3259
3260
3261 modobj = self.get_module_by_name(label)
3262 if modobj:
3263
3264
3265
3266 module = modobj.get_name()
3267
3268 else:
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279 try:
3280 address = HexInput.integer(label)
3281
3282 if offset:
3283
3284
3285
3286
3287
3288
3289 offset = address + offset
3290 else:
3291
3292 offset = address
3293
3294
3295
3296
3297
3298
3299 try:
3300 new_label = self.get_label_at_address(offset)
3301 module, function, offset = \
3302 self.split_label_strict(new_label)
3303 except ValueError:
3304 pass
3305
3306
3307
3308 except ValueError:
3309 function = label
3310
3311
3312 if function and function.startswith('#'):
3313 try:
3314 function = HexInput.integer(function[1:])
3315 except ValueError:
3316 pass
3317
3318
3319 if not offset:
3320 offset = None
3321
3322 return (module, function, offset)
3323
3324 @classmethod
3326 """
3327 Splits a label into it's C{module}, C{function} and C{offset}
3328 components, as used in L{parse_label}.
3329
3330 When called as a static method, the strict syntax mode is used::
3331
3332 winappdbg.Process.split_label( "kernel32!CreateFileA" )
3333
3334 When called as an instance method, the fuzzy syntax mode is used::
3335
3336 aProcessInstance.split_label( "CreateFileA" )
3337
3338 @see: L{split_label_strict}, L{split_label_fuzzy}
3339
3340 @type label: str
3341 @param label: Label to split.
3342
3343 @rtype: tuple( str or None, str or int or None, int or None )
3344 @return:
3345 Tuple containing the C{module} name,
3346 the C{function} name or ordinal, and the C{offset} value.
3347
3348 If the label doesn't specify a module,
3349 then C{module} is C{None}.
3350
3351 If the label doesn't specify a function,
3352 then C{function} is C{None}.
3353
3354 If the label doesn't specify an offset,
3355 then C{offset} is C{0}.
3356
3357 @raise ValueError: The label is malformed.
3358 """
3359
3360
3361
3362
3363
3364
3365
3366 return cls.split_label_strict(label)
3367
3368
3372
3373
3375 """
3376 Converts a label taken from user input into a well-formed label.
3377
3378 @type label: str
3379 @param label: Label taken from user input.
3380
3381 @rtype: str
3382 @return: Sanitized label.
3383 """
3384 (module, function, offset) = self.split_label_fuzzy(label)
3385 label = self.parse_label(module, function, offset)
3386 return label
3387
3389 """
3390 Resolve the memory address of the given label.
3391
3392 @note:
3393 If multiple modules with the same name are loaded,
3394 the label may be resolved at any of them. For a more precise
3395 way to resolve functions use the base address to get the L{Module}
3396 object (see L{Process.get_module}) and then call L{Module.resolve}.
3397
3398 If no module name is specified in the label, the function may be
3399 resolved in any loaded module. If you want to resolve all functions
3400 with that name in all processes, call L{Process.iter_modules} to
3401 iterate through all loaded modules, and then try to resolve the
3402 function in each one of them using L{Module.resolve}.
3403
3404 @type label: str
3405 @param label: Label to resolve.
3406
3407 @rtype: int
3408 @return: Memory address pointed to by the label.
3409
3410 @raise ValueError: The label is malformed or impossible to resolve.
3411 @raise RuntimeError: Cannot resolve the module or function.
3412 """
3413
3414
3415 address = 0
3416
3417
3418 module, function, offset = self.split_label_fuzzy(label)
3419
3420
3421 if module:
3422 modobj = self.get_module_by_name(module)
3423 if not modobj:
3424 msg = "Module %r not found" % module
3425 raise RuntimeError, msg
3426
3427
3428
3429 if function:
3430 address = modobj.resolve(function)
3431 if address is None:
3432 address = modobj.resolve_symbol(function)
3433 if address is None:
3434 if function == "start":
3435 address = modobj.get_entry_point()
3436 if address is None:
3437 msg = "Symbol %r not found in module %s"
3438 msg = msg % (function, module)
3439 raise RuntimeError, msg
3440
3441
3442 else:
3443 address = modobj.get_base()
3444
3445
3446 elif function:
3447 for modobj in self.iter_modules():
3448 address = modobj.resolve(function)
3449 if address is not None:
3450 break
3451 if address is None:
3452 msg = "Function %r not found in any module" % function
3453 raise RuntimeError, msg
3454
3455
3456 if offset:
3457 address = address + offset
3458 return address
3459
3461 """
3462 Creates a label from the given memory address.
3463
3464 @warning: This method uses the name of the nearest currently loaded
3465 module. If that module is unloaded later, the label becomes
3466 impossible to resolve.
3467
3468 @type address: int
3469 @param address: Memory address.
3470
3471 @type offset: None or int
3472 @param offset: (Optional) Offset value.
3473
3474 @rtype: str
3475 @return: Label pointing to the given address.
3476 """
3477 if offset:
3478 address = address + offset
3479 modobj = self.get_module_at_address(address)
3480 if modobj:
3481 label = modobj.get_label_at_address(address)
3482 else:
3483 label = self.parse_label(None, None, address)
3484 return label
3485
3486
3487
3488
3505
3506
3507
3508
3510 """
3511 @rtype: int or None
3512 @return: Memory address of the system breakpoint
3513 within the process address space.
3514 Returns C{None} on error.
3515 """
3516 try:
3517 return self.resolve_label("ntdll!DbgBreakPoint")
3518 except Exception:
3519 return None
3520
3521
3523 """
3524 @rtype: int or None
3525 @return: Memory address of the Wow64 system breakpoint
3526 within the process address space.
3527 Returns C{None} on error.
3528 """
3529 try:
3530 return self.resolve_label("ntdll32!DbgBreakPoint")
3531 except Exception:
3532 return None
3533
3534
3536 """
3537 @rtype: int or None
3538 @return: Memory address of the user breakpoint
3539 within the process address space.
3540 Returns C{None} on error.
3541 """
3542 try:
3543 return self.resolve_label("ntdll!DbgUserBreakPoint")
3544 except Exception:
3545 return None
3546
3547
3549 """
3550 @rtype: int or None
3551 @return: Memory address of the Wow64 user breakpoint
3552 within the process address space.
3553 Returns C{None} on error.
3554 """
3555 try:
3556 return self.resolve_label("ntdll32!DbgUserBreakPoint")
3557 except Exception:
3558 return None
3559
3560
3561
3563 """
3564 @rtype: int or None
3565 @return: Memory address of the remote breakin breakpoint
3566 within the process address space.
3567 Returns C{None} on error.
3568 """
3569 try:
3570 return self.resolve_label("ntdll!DbgUiRemoteBreakin")
3571 except Exception:
3572 return None
3573
3574
3576 """
3577 @rtype: int or None
3578 @return: Memory address of the Wow64 remote breakin breakpoint
3579 within the process address space.
3580 Returns C{None} on error.
3581 """
3582 try:
3583 return self.resolve_label("ntdll32!DbgUiRemoteBreakin")
3584 except Exception:
3585 return None
3586
3590
3594
3596 symbols = list()
3597 for aModule in self.iter_modules():
3598 for symbol in aModule.iter_symbols():
3599 symbols.append(symbol)
3600 return symbols
3601
3606
3608 symbol = symbol.lower()
3609 for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols():
3610 if symbol == SymbolName.lower():
3611 return SymbolAddress
3612
3614 found = None
3615 for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols():
3616 if SymbolAddress <= address:
3617 if SymbolAddress + SymbolSize > address:
3618 if not found or found[1] < SymbolAddress:
3619 found = (SymbolName, SymbolAddress, SymbolSize)
3620 return found
3621
3628 """
3629 Encapsulates several useful debugging routines for threads.
3630
3631 @group Properties:
3632 get_teb, get_teb_address, is_wow64
3633
3634 @group Disassembly:
3635 disassemble, disassemble_around, disassemble_around_pc,
3636 disassemble_string, disassemble_instruction, disassemble_current
3637
3638 @group Stack:
3639 get_stack_frame, get_stack_frame_range, get_stack_range,
3640 get_stack_trace, get_stack_trace_with_labels,
3641 read_stack_data, read_stack_dwords,
3642 peek_stack_data, peek_stack_dwords
3643
3644 @group Miscellaneous:
3645 read_code_bytes, peek_code_bytes,
3646 peek_pointers_in_data, peek_pointers_in_registers,
3647 get_linear_address, get_label_at_pc,
3648 get_seh_chain, get_wait_chain
3649 """
3650
3652 """
3653 Determines if the thread is running under WOW64.
3654
3655 @rtype: bool
3656 @return:
3657 C{True} if the thread is running under WOW64. That is, it belongs
3658 to a 32-bit application running in a 64-bit Windows.
3659
3660 C{False} if the thread belongs to either a 32-bit application
3661 running in a 32-bit Windows, or a 64-bit application running in a
3662 64-bit Windows.
3663
3664 @raise WindowsError: On error an exception is raised.
3665
3666 @see: U{http://msdn.microsoft.com/en-us/library/aa384249(VS.85).aspx}
3667 """
3668 return self.get_process().is_wow64()
3669
3670
3671
3672
3673
3675 """
3676 Returns a copy of the TEB.
3677 To dereference pointers in it call L{Process.read_structure}.
3678
3679 @rtype: L{TEB}
3680 @return: TEB structure.
3681 @raise WindowsError: An exception is raised on error.
3682 """
3683 return self.get_process().read_structure( self.get_teb_address(),
3684 win32.TEB )
3685
3703
3705 """
3706 Translates segment-relative addresses to linear addresses.
3707
3708 Linear addresses can be used to access a process memory,
3709 calling L{Process.read} and L{Process.write}.
3710
3711 @type segment: str
3712 @param segment: Segment register name.
3713
3714 @type address: int
3715 @param address: Segment relative memory address.
3716
3717 @rtype: int
3718 @return: Linear memory address.
3719
3720 @raise ValueError: Address is too large for selector.
3721
3722 @raise WindowsError:
3723 The current architecture does not support selectors.
3724 Selectors only exist in x86-based systems.
3725 """
3726 selector = self.get_register(segment)
3727 ldt = win32.GetThreadSelectorEntry(self.get_handle(), selector)
3728 BaseLow = ldt.BaseLow
3729 BaseMid = ldt.HighWord.Bytes.BaseMid << 16
3730 BaseHi = ldt.HighWord.Bytes.BaseHi << 24
3731 Base = BaseLow | BaseMid | BaseHi
3732 LimitLow = ldt.LimitLow
3733 LimitHi = ldt.HighWord.Bits.LimitHi << 16
3734 Limit = LimitLow | LimitHi
3735 if address > Limit:
3736 msg = "Address %s too large for segment %s (selector %d)"
3737 msg = msg % (HexDump.address(address), segment, selector)
3738 raise ValueError, msg
3739 return Base + address
3740
3747
3749 """
3750 @rtype: list of tuple( int, int )
3751 @return: List of structured exception handlers.
3752 Each SEH is represented as a tuple of two addresses:
3753 - Address of the SEH block
3754 - Address of the SEH callback function
3755
3756 @raise NotImplementedError:
3757 This method is only supported in 32 bits versions of Windows.
3758 """
3759 if System.arch != 'i386':
3760 raise NotImplementedError, \
3761 "SEH chain parsing is only supported in 32-bit Windows."
3762 process = self.get_process()
3763 seh_chain = list()
3764 try:
3765 seh = process.read_uint( self.get_linear_address('SegFs', 0) )
3766 while seh != 0xFFFFFFFF:
3767 seh_func = process.read_uint( seh + 4 )
3768 seh_chain.append( (seh, seh_func) )
3769 seh = process.read_uint( seh )
3770 except WindowsError, e:
3771 pass
3772 return seh_chain
3773
3775 """
3776 @rtype:
3777 tuple of (
3778 list of L{win32.WAITCHAIN_NODE_INFO} structures,
3779 bool)
3780 @return:
3781 Wait chain for the thread.
3782 The boolean indicates if there's a cycle in the chain.
3783 @raise AttributeError:
3784 This method is only suppported in Windows Vista and above.
3785 @see:
3786 U{http://msdn.microsoft.com/en-us/library/ms681622%28VS.85%29.aspx}
3787 """
3788 hWct = win32.OpenThreadWaitChainSession()
3789 try:
3790 return win32.GetThreadWaitChain(hWct, None, 0, self.get_tid())
3791 finally:
3792 win32.CloseThreadWaitChainSession(hWct)
3793
3795 """
3796 @rtype: tuple( int, int )
3797 @return: Stack beginning and end pointers, in memory addresses order.
3798 That is, the first pointer is the stack top, and the second pointer
3799 is the stack bottom, since the stack grows towards lower memory
3800 addresses.
3801 @raise WindowsError: Raises an exception on error.
3802 """
3803 teb = self.get_teb()
3804 tib = teb.NtTib
3805 return ( tib.StackLimit, tib.StackBase )
3806
3807 - def __get_stack_trace(self, depth = 16, bUseLabels = True,
3808 bMakePretty = True):
3809 """
3810 Tries to get a stack trace for the current function.
3811 Only works for functions with standard prologue and epilogue.
3812
3813 @type depth: int
3814 @param depth: Maximum depth of stack trace.
3815
3816 @type bUseLabels: bool
3817 @param bUseLabels: C{True} to use labels, C{False} to use addresses.
3818
3819 @rtype: tuple of tuple( int, int, str )
3820 @return: Stack trace of the thread as a tuple of
3821 ( return address, frame pointer address, module filename )
3822 when C{bUseLabels} is C{True}, or a tuple of
3823 ( return address, frame pointer label )
3824 when C{bUseLabels} is C{False}.
3825
3826 @raise WindowsError: Raises an exception on error.
3827 """
3828 aProcess = self.get_process()
3829 st, sb = self.get_stack_range()
3830 fp = self.get_fp()
3831 trace = list()
3832 if aProcess.get_module_count() == 0:
3833 aProcess.scan_modules()
3834 while depth > 0:
3835 if fp == 0:
3836 break
3837 if not st <= fp < sb:
3838 break
3839 ra = aProcess.peek_pointer(fp + 4)
3840 if ra == 0:
3841 break
3842 lib = aProcess.get_module_at_address(ra)
3843 if lib is None:
3844 lib = ""
3845 else:
3846 if lib.fileName:
3847 lib = lib.fileName
3848 else:
3849 lib = "%s" % HexDump.address(lib.lpBaseOfDll)
3850 if bUseLabels:
3851 label = aProcess.get_label_at_address(ra)
3852 if bMakePretty:
3853 label = '%s (%s)' % (HexDump.address(ra), label)
3854 trace.append( (fp, label) )
3855 else:
3856 trace.append( (fp, ra, lib) )
3857 fp = aProcess.peek_pointer(fp)
3858 return tuple(trace)
3859
3861 """
3862 Tries to get a stack trace for the current function.
3863 Only works for functions with standard prologue and epilogue.
3864
3865 @type depth: int
3866 @param depth: Maximum depth of stack trace.
3867
3868 @rtype: tuple of tuple( int, int, str )
3869 @return: Stack trace of the thread as a tuple of
3870 ( return address, frame pointer address, module filename ).
3871
3872 @raise WindowsError: Raises an exception on error.
3873 """
3874 return self.__get_stack_trace(depth, False)
3875
3877 """
3878 Tries to get a stack trace for the current function.
3879 Only works for functions with standard prologue and epilogue.
3880
3881 @type depth: int
3882 @param depth: Maximum depth of stack trace.
3883
3884 @type bMakePretty: bool
3885 @param bMakePretty:
3886 C{True} for user readable labels,
3887 C{False} for labels that can be passed to L{Process.resolve_label}.
3888
3889 "Pretty" labels look better when producing output for the user to
3890 read, while pure labels are more useful programatically.
3891
3892 @rtype: tuple of tuple( int, int, str )
3893 @return: Stack trace of the thread as a tuple of
3894 ( return address, frame pointer label ).
3895
3896 @raise WindowsError: Raises an exception on error.
3897 """
3898 return self.__get_stack_trace(depth, True)
3899
3901 """
3902 Returns the starting and ending addresses of the stack frame.
3903 Only works for functions with standard prologue and epilogue.
3904
3905 @rtype: tuple( int, int )
3906 @return: Stack frame range.
3907 May not be accurate, depending on the compiler used.
3908
3909 @raise RuntimeError: The stack frame is invalid,
3910 or the function doesn't have a standard prologue
3911 and epilogue.
3912
3913 @raise WindowsError: An error occured when getting the thread context.
3914 """
3915 st, sb = self.get_stack_range()
3916 sp = self.get_sp()
3917 fp = self.get_fp()
3918 size = fp - sp
3919 if not st <= sp < sb:
3920 raise RuntimeError, 'Stack pointer lies outside the stack'
3921 if not st <= fp < sb:
3922 raise RuntimeError, 'Frame pointer lies outside the stack'
3923 if sp > fp:
3924 raise RuntimeError, 'No valid stack frame found'
3925 return (sp, fp)
3926
3928 """
3929 Reads the contents of the current stack frame.
3930 Only works for functions with standard prologue and epilogue.
3931
3932 @type max_size: int
3933 @param max_size: (Optional) Maximum amount of bytes to read.
3934
3935 @rtype: str
3936 @return: Stack frame data.
3937 May not be accurate, depending on the compiler used.
3938 May return an empty string.
3939
3940 @raise RuntimeError: The stack frame is invalid,
3941 or the function doesn't have a standard prologue
3942 and epilogue.
3943
3944 @raise WindowsError: An error occured when getting the thread context
3945 or reading data from the process memory.
3946 """
3947 sp, fp = self.get_stack_frame_range()
3948 size = fp - sp
3949 if max_size and size > max_size:
3950 size = max_size
3951 return self.get_process().peek(sp, size)
3952
3954 """
3955 Reads the contents of the top of the stack.
3956
3957 @type size: int
3958 @param size: Number of bytes to read.
3959
3960 @type offset: int
3961 @param offset: Offset from the stack pointer to begin reading.
3962
3963 @rtype: str
3964 @return: Stack data.
3965
3966 @raise WindowsError: Could not read the requested data.
3967 """
3968 aProcess = self.get_process()
3969 return aProcess.read(self.get_sp() + offset, size)
3970
3972 """
3973 Tries to read the contents of the top of the stack.
3974
3975 @type size: int
3976 @param size: Number of bytes to read.
3977
3978 @type offset: int
3979 @param offset: Offset from the stack pointer to begin reading.
3980
3981 @rtype: str
3982 @return: Stack data.
3983 Returned data may be less than the requested size.
3984 """
3985 aProcess = self.get_process()
3986 return aProcess.peek(self.get_sp() + offset, size)
3987
3989 """
3990 Reads DWORDs from the top of the stack.
3991
3992 @type count: int
3993 @param count: Number of DWORDs to read.
3994
3995 @type offset: int
3996 @param offset: Offset from the stack pointer to begin reading.
3997
3998 @rtype: tuple( int... )
3999 @return: Tuple of integers read from the stack.
4000
4001 @raise WindowsError: Could not read the requested data.
4002 """
4003 stackData = self.read_stack_data(count * 4, offset)
4004 return struct.unpack('<'+('L'*count), stackData)
4005
4007 """
4008 Tries to read DWORDs from the top of the stack.
4009
4010 @type count: int
4011 @param count: Number of DWORDs to read.
4012
4013 @type offset: int
4014 @param offset: Offset from the stack pointer to begin reading.
4015
4016 @rtype: tuple( int... )
4017 @return: Tuple of integers read from the stack.
4018 May be less than the requested number of DWORDs.
4019 """
4020 stackData = self.peek_stack_data(count * 4, offset)
4021 if len(stackData) & 3:
4022 stackData = stackData[:-len(stackData) & 3]
4023 if not stackData:
4024 return ()
4025 return struct.unpack('<'+('L'*count), stackData)
4026
4028 """
4029 Reads QWORDs from the top of the stack.
4030
4031 @type count: int
4032 @param count: Number of QWORDs to read.
4033
4034 @type offset: int
4035 @param offset: Offset from the stack pointer to begin reading.
4036
4037 @rtype: tuple( int... )
4038 @return: Tuple of integers read from the stack.
4039
4040 @raise WindowsError: Could not read the requested data.
4041 """
4042 stackData = self.read_stack_data(count * 8, offset)
4043 return struct.unpack('<'+('Q'*count), stackData)
4044
4046 """
4047 Tries to read QWORDs from the top of the stack.
4048
4049 @type count: int
4050 @param count: Number of QWORDs to read.
4051
4052 @type offset: int
4053 @param offset: Offset from the stack pointer to begin reading.
4054
4055 @rtype: tuple( int... )
4056 @return: Tuple of integers read from the stack.
4057 May be less than the requested number of QWORDs.
4058 """
4059 stackData = self.peek_stack_data(count * 8, offset)
4060 if len(stackData) & 7:
4061 stackData = stackData[:-len(stackData) & 7]
4062 if not stackData:
4063 return ()
4064 return struct.unpack('<'+('Q'*count), stackData)
4065
4067 """
4068 Tries to read some bytes of the code currently being executed.
4069
4070 @type size: int
4071 @param size: Number of bytes to read.
4072
4073 @type offset: int
4074 @param offset: Offset from the program counter to begin reading.
4075
4076 @rtype: str
4077 @return: Bytes read from the process memory.
4078
4079 @raise WindowsError: Could not read the requested data.
4080 """
4081 return self.get_process().read(self.get_pc() + offset, size)
4082
4084 """
4085 Tries to read some bytes of the code currently being executed.
4086
4087 @type size: int
4088 @param size: Number of bytes to read.
4089
4090 @type offset: int
4091 @param offset: Offset from the program counter to begin reading.
4092
4093 @rtype: str
4094 @return: Bytes read from the process memory.
4095 May be less than the requested number of bytes.
4096 """
4097 return self.get_process().peek(self.get_pc() + offset, size)
4098
4100 """
4101 Tries to guess which values in the registers are valid pointers,
4102 and reads some data from them.
4103
4104 @type peekSize: int
4105 @param peekSize: Number of bytes to read from each pointer found.
4106
4107 @type context: dict( str S{->} int )
4108 @param context: (Optional)
4109 Dictionary mapping register names to their values.
4110 If not given, the current thread context will be used.
4111
4112 @rtype: dict( str S{->} str )
4113 @return: Dictionary mapping register names to the data they point to.
4114 """
4115 peekable_registers = (
4116 'Eax', 'Ebx', 'Ecx', 'Edx', 'Esi', 'Edi', 'Ebp'
4117 )
4118 if not context:
4119 context = self.get_context(win32.CONTEXT_CONTROL | \
4120 win32.CONTEXT_INTEGER)
4121 aProcess = self.get_process()
4122 data = dict()
4123 for (reg_name, reg_value) in context.iteritems():
4124 if reg_name not in peekable_registers:
4125 continue
4126
4127
4128
4129
4130
4131
4132 reg_data = aProcess.peek(reg_value, peekSize)
4133 if reg_data:
4134 data[reg_name] = reg_data
4135 return data
4136
4137
4138
4140 """
4141 Tries to guess which values in the given data are valid pointers,
4142 and reads some data from them.
4143
4144 @type data: str
4145 @param data: Binary data to find pointers in.
4146
4147 @type peekSize: int
4148 @param peekSize: Number of bytes to read from each pointer found.
4149
4150 @type peekStep: int
4151 @param peekStep: Expected data alignment.
4152 Tipically you specify 1 when data alignment is unknown,
4153 or 4 when you expect data to be DWORD aligned.
4154 Any other value may be specified.
4155
4156 @rtype: dict( str S{->} str )
4157 @return: Dictionary mapping stack offsets to the data they point to.
4158 """
4159 aProcess = self.get_process()
4160 return aProcess.peek_pointers_in_data(data, peekSize, peekStep)
4161
4162
4163
4164
4165
4166
4167
4169 """
4170 Disassemble instructions from a block of binary code.
4171
4172 @type lpAddress: int
4173 @param lpAddress: Memory address where the code was read from.
4174
4175 @type code: str
4176 @param code: Binary code to disassemble.
4177
4178 @rtype: list of tuple( long, int, str, str )
4179 @return: List of tuples. Each tuple represents an assembly instruction
4180 and contains:
4181 - Memory address of instruction.
4182 - Size of instruction in bytes.
4183 - Disassembly line of instruction.
4184 - Hexadecimal dump of instruction.
4185 """
4186 aProcess = self.get_process()
4187 return aProcess.disassemble_string(lpAddress, code)
4188
4190 """
4191 Disassemble instructions from the address space of the process.
4192
4193 @type lpAddress: int
4194 @param lpAddress: Memory address where to read the code from.
4195
4196 @type dwSize: int
4197 @param dwSize: Size of binary code to disassemble.
4198
4199 @rtype: list of tuple( long, int, str, str )
4200 @return: List of tuples. Each tuple represents an assembly instruction
4201 and contains:
4202 - Memory address of instruction.
4203 - Size of instruction in bytes.
4204 - Disassembly line of instruction.
4205 - Hexadecimal dump of instruction.
4206 """
4207 aProcess = self.get_process()
4208 return aProcess.disassemble(lpAddress, dwSize)
4209
4211 """
4212 Disassemble around the given address.
4213
4214 @type lpAddress: int
4215 @param lpAddress: Memory address where to read the code from.
4216
4217 @type dwSize: int
4218 @param dwSize: Delta offset.
4219 Code will be read from lpAddress - dwSize to lpAddress + dwSize.
4220
4221 @rtype: list of tuple( long, int, str, str )
4222 @return: List of tuples. Each tuple represents an assembly instruction
4223 and contains:
4224 - Memory address of instruction.
4225 - Size of instruction in bytes.
4226 - Disassembly line of instruction.
4227 - Hexadecimal dump of instruction.
4228 """
4229 aProcess = self.get_process()
4230 return aProcess.disassemble_around(lpAddress, dwSize)
4231
4233 """
4234 Disassemble around the program counter of the given thread.
4235
4236 @type dwSize: int
4237 @param dwSize: Delta offset.
4238 Code will be read from pc - dwSize to pc + dwSize.
4239
4240 @rtype: list of tuple( long, int, str, str )
4241 @return: List of tuples. Each tuple represents an assembly instruction
4242 and contains:
4243 - Memory address of instruction.
4244 - Size of instruction in bytes.
4245 - Disassembly line of instruction.
4246 - Hexadecimal dump of instruction.
4247 """
4248 aProcess = self.get_process()
4249 return aProcess.disassemble_around(self.get_pc(), dwSize)
4250
4252 """
4253 Disassemble the instruction at the given memory address.
4254
4255 @type lpAddress: int
4256 @param lpAddress: Memory address where to read the code from.
4257
4258 @rtype: tuple( long, int, str, str )
4259 @return: The tuple represents an assembly instruction
4260 and contains:
4261 - Memory address of instruction.
4262 - Size of instruction in bytes.
4263 - Disassembly line of instruction.
4264 - Hexadecimal dump of instruction.
4265 """
4266 aProcess = self.get_process()
4267 return aProcess.disassemble(lpAddress, 15)[0]
4268
4270 """
4271 Disassemble the instruction at the program counter of the given thread.
4272
4273 @rtype: tuple( long, int, str, str )
4274 @return: The tuple represents an assembly instruction
4275 and contains:
4276 - Memory address of instruction.
4277 - Size of instruction in bytes.
4278 - Disassembly line of instruction.
4279 - Hexadecimal dump of instruction.
4280 """
4281 return self.disassemble_instruction(self.get_pc())
4282
4289 """
4290 Encapsulates several useful debugging routines for processes.
4291
4292 @group Properties:
4293 get_peb, get_peb_address,
4294 get_main_module, get_image_base, get_image_name,
4295 is_wow64
4296
4297 @group Disassembly:
4298 disassemble, disassemble_around, disassemble_around_pc,
4299 disassemble_string, disassemble_instruction, disassemble_current
4300
4301 @group Debugging:
4302 flush_instruction_cache, debug_break, peek_pointers_in_data
4303 """
4304
4305 __hexa_parameter = re.compile('0x[0-9A-Za-z]+')
4306
4308 for index in xrange(len(disasm)):
4309 (address, size, text, dump) = disasm[index]
4310 m = self.__hexa_parameter.search(text)
4311 while m:
4312 s, e = m.span()
4313 value = text[s:e]
4314 try:
4315 label = self.get_label_at_address( int(value, 0x10) )
4316 except Exception, e:
4317 label = None
4318 if label:
4319 text = text[:s] + label + text[e:]
4320 e = s + len(value)
4321 m = self.__hexa_parameter.search(text, e)
4322 disasm[index] = (address, size, text, dump)
4323
4325 """
4326 Disassemble instructions from a block of binary code.
4327
4328 @type lpAddress: int
4329 @param lpAddress: Memory address where the code was read from.
4330
4331 @type code: str
4332 @param code: Binary code to disassemble.
4333
4334 @rtype: list of tuple( long, int, str, str )
4335 @return: List of tuples. Each tuple represents an assembly instruction
4336 and contains:
4337 - Memory address of instruction.
4338 - Size of instruction in bytes.
4339 - Disassembly line of instruction.
4340 - Hexadecimal dump of instruction.
4341 """
4342 if System.arch not in ('i386', 'amd64'):
4343 raise NotImplementedError
4344 if (not System.wow64 and System.bits == 32) or self.is_wow64():
4345 return Decode(lpAddress, code, Decode32Bits)
4346 return Decode(lpAddress, code, Decode64Bits)
4347
4349 """
4350 Disassemble instructions from the address space of the process.
4351
4352 @type lpAddress: int
4353 @param lpAddress: Memory address where to read the code from.
4354
4355 @type dwSize: int
4356 @param dwSize: Size of binary code to disassemble.
4357
4358 @rtype: list of tuple( long, int, str, str )
4359 @return: List of tuples. Each tuple represents an assembly instruction
4360 and contains:
4361 - Memory address of instruction.
4362 - Size of instruction in bytes.
4363 - Disassembly line of instruction.
4364 - Hexadecimal dump of instruction.
4365 """
4366 data = self.read(lpAddress, dwSize)
4367 disasm = self.disassemble_string(lpAddress, data)
4368 self.__fixup_labels(disasm)
4369 return disasm
4370
4371
4372
4374 """
4375 Disassemble around the given address.
4376
4377 @type lpAddress: int
4378 @param lpAddress: Memory address where to read the code from.
4379
4380 @type dwSize: int
4381 @param dwSize: Delta offset.
4382 Code will be read from lpAddress - dwSize to lpAddress + dwSize.
4383
4384 @rtype: list of tuple( long, int, str, str )
4385 @return: List of tuples. Each tuple represents an assembly instruction
4386 and contains:
4387 - Memory address of instruction.
4388 - Size of instruction in bytes.
4389 - Disassembly line of instruction.
4390 - Hexadecimal dump of instruction.
4391 """
4392 dwDelta = int(float(dwSize) / 2.0)
4393 addr_1 = lpAddress - dwDelta
4394 addr_2 = lpAddress
4395 size_1 = dwDelta
4396 size_2 = dwSize - dwDelta
4397 data = self.read(addr_1, dwSize)
4398 data_1 = data[:size_1]
4399 data_2 = data[size_1:]
4400 disasm_1 = self.disassemble_string(addr_1, data_1)
4401 disasm_2 = self.disassemble_string(addr_2, data_2)
4402 disasm = disasm_1 + disasm_2
4403 self.__fixup_labels(disasm)
4404 return disasm
4405
4407 """
4408 Disassemble around the program counter of the given thread.
4409
4410 @type dwThreadId: int
4411 @param dwThreadId: Global thread ID.
4412 The program counter for this thread will be used as the disassembly
4413 address.
4414
4415 @type dwSize: int
4416 @param dwSize: Delta offset.
4417 Code will be read from pc - dwSize to pc + dwSize.
4418
4419 @rtype: list of tuple( long, int, str, str )
4420 @return: List of tuples. Each tuple represents an assembly instruction
4421 and contains:
4422 - Memory address of instruction.
4423 - Size of instruction in bytes.
4424 - Disassembly line of instruction.
4425 - Hexadecimal dump of instruction.
4426 """
4427 aThread = self.get_thread(dwThreadId)
4428 return self.disassemble_around(aThread.get_pc(), dwSize)
4429
4431 """
4432 Disassemble the instruction at the given memory address.
4433
4434 @type lpAddress: int
4435 @param lpAddress: Memory address where to read the code from.
4436
4437 @rtype: tuple( long, int, str, str )
4438 @return: The tuple represents an assembly instruction
4439 and contains:
4440 - Memory address of instruction.
4441 - Size of instruction in bytes.
4442 - Disassembly line of instruction.
4443 - Hexadecimal dump of instruction.
4444 """
4445 return self.disassemble(lpAddress, 15)[0]
4446
4448 """
4449 Disassemble the instruction at the program counter of the given thread.
4450
4451 @type dwThreadId: int
4452 @param dwThreadId: Global thread ID.
4453 The program counter for this thread will be used as the disassembly
4454 address.
4455
4456 @rtype: tuple( long, int, str, str )
4457 @return: The tuple represents an assembly instruction
4458 and contains:
4459 - Memory address of instruction.
4460 - Size of instruction in bytes.
4461 - Disassembly line of instruction.
4462 - Hexadecimal dump of instruction.
4463 """
4464 aThread = self.get_thread(dwThreadId)
4465 return self.disassemble_instruction(aThread.get_pc())
4466
4467
4468
4470 """
4471 Flush the instruction cache. This is required if the process memory is
4472 modified and one or more threads are executing nearby the modified
4473 memory region.
4474
4475 @see: U{http://blogs.msdn.com/oldnewthing/archive/2003/12/08/55954.aspx#55958}
4476
4477 @raise WindowsError: Raises exception on error.
4478 """
4479 win32.FlushInstructionCache( self.get_handle() )
4480
4482 """
4483 Triggers the system breakpoint in the process.
4484
4485 @raise WindowsError: On error an exception is raised.
4486 """
4487
4488
4489
4490 win32.DebugBreakProcess( self.get_handle() )
4491
4493 """
4494 Determines if the process is running under WOW64.
4495
4496 @rtype: bool
4497 @return:
4498 C{True} if the process is running under WOW64. That is, a 32-bit
4499 application running in a 64-bit Windows.
4500
4501 C{False} if the process is either a 32-bit application running in
4502 a 32-bit Windows, or a 64-bit application running in a 64-bit
4503 Windows.
4504
4505 @raise WindowsError: On error an exception is raised.
4506
4507 @see: U{http://msdn.microsoft.com/en-us/library/aa384249(VS.85).aspx}
4508 """
4509 hProcess = self.get_handle()
4510 try:
4511 return win32.IsWow64Process(hProcess)
4512 except AttributeError:
4513 return False
4514
4515
4516
4518 """
4519 Returns a copy of the PEB.
4520 To dereference pointers in it call L{Process.read_structure}.
4521
4522 @rtype: L{win32.PEB}
4523 @return: PEB structure.
4524 @raise WindowsError: An exception is raised on error.
4525 """
4526 return self.read_structure(self.get_peb_address(), win32.PEB)
4527
4539
4540 - def get_main_module(self):
4541 """
4542 @rtype: L{Module}
4543 @return: Module object for the process main module.
4544 """
4545 return self.get_module(self.get_image_base())
4546
4548 """
4549 @rtype: int
4550 @return: Image base address for the process main module.
4551 """
4552 return self.get_peb().ImageBaseAddress
4553
4554
4555
4556
4557
4558
4560 """
4561 @rtype: int
4562 @return: Filename of the process main module.
4563
4564 This method does it's best to retrieve the filename.
4565 However sometimes this is not possible, so C{None} may
4566 be returned instead.
4567 """
4568
4569 name = None
4570
4571
4572
4573
4574 if not name:
4575 try:
4576 name = self.get_main_module().fileName
4577 if not name:
4578 name = None
4579 except (KeyError, AttributeError, WindowsError):
4580 name = None
4581
4582
4583
4584 if not name:
4585 try:
4586 name = win32.QueryFullProcessImageName(self.get_handle())
4587 except (AttributeError, WindowsError):
4588 name = None
4589
4590
4591
4592
4593 if not name:
4594 try:
4595 name = win32.GetProcessImageFileName(self.get_handle())
4596 if name:
4597 name = PathOperations.native_to_win32_pathname(name)
4598 else:
4599 name = None
4600 except (AttributeError, WindowsError):
4601 if not name:
4602 name = None
4603
4604
4605
4606 if not name:
4607 try:
4608 name = win32.GetModuleFileNameEx(self.get_handle(), win32.NULL)
4609 if name:
4610 name = PathOperations.native_to_win32_pathname(name)
4611 else:
4612 name = None
4613 except (AttributeError, WindowsError):
4614 if not name:
4615 name = None
4616
4617
4618
4619 if not name:
4620 try:
4621 peb = self.get_peb()
4622 pp = self.read_structure(peb.ProcessParameters,
4623 win32.RTL_USER_PROCESS_PARAMETERS)
4624 s = pp.ImagePathName
4625 name = self.peek_string(s.Buffer,
4626 dwMaxSize=s.MaximumLength, fUnicode=True)
4627 if name:
4628 name = PathOperations.native_to_win32_pathname(name)
4629 else:
4630 name = None
4631 except (AttributeError, WindowsError):
4632 name = None
4633
4634
4635
4636
4637
4638
4639 if not name:
4640 try:
4641 name = self.get_main_module().get_filename()
4642 except (KeyError, AttributeError, WindowsError):
4643 name = None
4644
4645
4646 return name
4647
4663
4664
4665
4666
4667
4669 """
4670 Tries to guess which values in the given data are valid pointers,
4671 and reads some data from them.
4672
4673 @type data: str
4674 @param data: Binary data to find pointers in.
4675
4676 @type peekSize: int
4677 @param peekSize: Number of bytes to read from each pointer found.
4678
4679 @type peekStep: int
4680 @param peekStep: Expected data alignment.
4681 Tipically you specify 1 when data alignment is unknown,
4682 or 4 when you expect data to be DWORD aligned.
4683 Any other value may be specified.
4684
4685 @rtype: dict( str S{->} str )
4686 @return: Dictionary mapping stack offsets to the data they point to.
4687 """
4688 result = dict()
4689 ptrSize = win32.sizeof(win32.LPVOID)
4690 if ptrSize == 4:
4691 ptrFmt = '<L'
4692 else:
4693 ptrFmt = '<Q'
4694 if len(data) > 0:
4695 for i in xrange(0, len(data), peekStep):
4696 packed = data[i:i+ptrSize]
4697 if len(packed) == ptrSize:
4698 address = struct.unpack(ptrFmt, packed)[0]
4699
4700 peek_data = self.peek(address, peekSize)
4701 if peek_data:
4702 result[i] = peek_data
4703 return result
4704
4705
4706
4707 -class Window (object):
4708
4709 - def __init__(self, hWnd = None, process = None, thread = None):
4710 self.hWnd = hWnd
4711 self.process = process
4712 self.thread = thread
4713 self.dwProcessId = None
4714 self.dwThreadId = None
4715
4717 if self.hWnd is None:
4718 raise ValueError, "No window handle set!"
4719 return self.hWnd
4720
4727
4734
4738
4743
4745 if not self.thread:
4746 self.thread = Thread( self.get_tid() )
4747 return self.thread
4748
4751
4752 - def get_text(self):
4753 buffer = ctypes.create_string_buffer("", 0x10000)
4754 win32.SendMessageA(self.get_handle(), win32.WM_GETTEXT, ctypes.byref(buffer), 0x10000)
4755 return buffer.value
4756
4757 - def set_text(self, text):
4759
4763
4769
4775
4777 hWnd = self.get_handle()
4778 hPrevWnd = hWnd
4779 while hWnd:
4780 hPrevWnd = hWnd
4781 hWnd = win32.GetParent(hWnd)
4782 return Window(hPrevWnd)
4783
4786
4789
4790 - def show(self, bAsync = True):
4795
4796 - def hide(self, bAsync = True):
4801
4807
4813
4814 - def restore(self, bAsync = True):
4819
4820
4821
4822 -class Module (SymbolContainer):
4823 """
4824 Interface to a DLL library loaded in the context of another process.
4825
4826 @group Properties:
4827 get_base, get_filename, get_name, get_size, get_entry_point,
4828 get_process, get_pid
4829
4830 @group Labels:
4831 get_label, get_label_at_address, is_address_here,
4832 resolve, resolve_label, match_name
4833
4834 @group Handle:
4835 get_handle, open_handle, close_handle
4836
4837 @type unknown: str
4838 @cvar unknown: Suggested tag for unknown modules.
4839
4840 @type lpBaseOfDll: int
4841 @ivar lpBaseOfDll: Base of DLL module.
4842 Use L{get_base} instead.
4843
4844 @type hFile: L{FileHandle}
4845 @ivar hFile: Handle to the module file.
4846 Use L{get_handle} instead.
4847
4848 @type fileName: str
4849 @ivar fileName: Module filename.
4850 Use L{get_filename} instead.
4851
4852 @type SizeOfImage: int
4853 @ivar SizeOfImage: Size of the module.
4854 Use L{get_size} instead.
4855
4856 @type EntryPoint: int
4857 @ivar EntryPoint: Entry point of the module.
4858 Use L{get_entry_point} instead.
4859
4860 @type process: L{Process}
4861 @ivar process: Process where the module is loaded.
4862 Use L{get_process} instead.
4863 """
4864
4865 unknown = '<unknown>'
4866
4867 - def __init__(self, lpBaseOfDll, hFile = None, fileName = None,
4868 SizeOfImage = None,
4869 EntryPoint = None,
4870 process = None):
4871 """
4872 @type lpBaseOfDll: str
4873 @param lpBaseOfDll: Base address of the module.
4874
4875 @type hFile: L{FileHandle}
4876 @param hFile: (Optional) Handle to the module file.
4877
4878 @type fileName: str
4879 @param fileName: (Optional) Module filename.
4880
4881 @type SizeOfImage: int
4882 @param SizeOfImage: (Optional) Size of the module.
4883
4884 @type EntryPoint: int
4885 @param EntryPoint: (Optional) Entry point of the module.
4886
4887 @type process: L{Process}
4888 @param process: (Optional) Process where the module is loaded.
4889 """
4890 super(Module, self).__init__()
4891 self.lpBaseOfDll = lpBaseOfDll
4892 self.hFile = hFile
4893 self.fileName = fileName
4894 self.SizeOfImage = SizeOfImage
4895 self.EntryPoint = EntryPoint
4896 self.process = process
4897
4899 """
4900 @rtype: int or None
4901 @return: Base address of the module.
4902 Returns C{None} if unknown.
4903 """
4904 return self.lpBaseOfDll
4905
4915
4916 - def get_entry_point(self):
4917 """
4918 @rtype: int or None
4919 @return: Entry point of the module.
4920 Returns C{None} if unknown.
4921 """
4922 if not self.EntryPoint:
4923 self.__get_size_and_entry_point()
4924 return self.EntryPoint
4925
4927 "Get the size and entry point of the module using the Win32 API."
4928 process = self.get_process()
4929 if process:
4930 try:
4931 handle = process.get_handle()
4932 base = self.get_base()
4933 mi = win32.GetModuleInformation(handle, base)
4934 self.SizeOfImage = mi.SizeOfImage
4935 self.EntryPoint = mi.EntryPoint
4936 except WindowsError:
4937
4938 pass
4939
4941 """
4942 @rtype: str or None
4943 @return: Module filename.
4944 Returns C{None} if unknown.
4945 """
4946 if self.fileName is None:
4947 if self.hFile not in (None, win32.INVALID_HANDLE_VALUE):
4948 self.fileName = self.hFile.get_filename()
4949 return self.fileName
4950
4952 """
4953 @type pathname: str
4954 @param pathname: Pathname to a module.
4955
4956 @rtype: str
4957 @return: Module name.
4958 """
4959 filename = PathOperations.pathname_to_filename(pathname)
4960 if filename:
4961 filename = filename.lower()
4962 filepart, extpart = PathOperations.split_extension(filename)
4963 if filepart and extpart:
4964 modName = filepart
4965 else:
4966 modName = filename
4967 else:
4968 modName = pathname
4969 return modName
4970
4972 """
4973 @rtype: str
4974 @return: Module name, as used in labels.
4975
4976 @warning: Names are B{NOT} guaranteed to be unique.
4977
4978 If you need unique identification for a loaded module,
4979 use the base address instead.
4980
4981 @see: L{get_label}
4982 """
4983 pathname = self.get_filename()
4984 if pathname:
4985 modName = self.__filename_to_modname(pathname)
4986 else:
4987 modName = "0x%x" % self.get_base()
4988 return modName
4989
4991 """
4992 @rtype: bool
4993 @return:
4994 C{True} if the given name could refer to this module.
4995 It may not be exactly the same returned by L{get_name}.
4996 """
4997
4998
4999
5000 my_name = self.get_name().lower()
5001 if name.lower() == my_name:
5002 return True
5003
5004
5005 try:
5006 base = HexInput.integer(name)
5007 except ValueError:
5008 base = None
5009 if base is not None and base == self.get_base():
5010 return True
5011
5012
5013
5014 modName = self.__filename_to_modname(name)
5015 if modName.lower() == my_name:
5016 return True
5017
5018
5019 return False
5020
5022 """
5023 @rtype: L{Process} or None
5024 @return: Parent Process object.
5025 Returns C{None} on error.
5026 """
5027 return self.process
5028
5030 """
5031 @rtype: int or None
5032 @return: Parent process global ID.
5033 Returns C{None} on error.
5034 """
5035 if self.process is None:
5036 return None
5037 return self.process.get_pid()
5038
5039
5040
5058
5070
5079
5080
5081
5082 - def get_label(self, function = None, offset = None):
5083 """
5084 Retrieves the label for the given function of this module or the module
5085 base address if no function name is given.
5086
5087 @type function: str
5088 @param function: (Optional) Exported function name.
5089
5090 @type offset: int
5091 @param offset: (Optional) Offset from the module base address.
5092
5093 @rtype: str
5094 @return: Label for the module base address, plus the offset if given.
5095 """
5096 return SymbolOperations.parse_label(self.get_name(), function, offset)
5097
5099 """
5100 Creates a label from the given memory address.
5101
5102 If the address belongs to the module, the label is made relative to
5103 it's base address.
5104
5105 @type address: int
5106 @param address: Memory address.
5107
5108 @type offset: None or int
5109 @param offset: (Optional) Offset value.
5110
5111 @rtype: str
5112 @return: Label pointing to the given address.
5113 """
5114
5115
5116 if offset:
5117 address = address + offset
5118
5119
5120 module = self.get_name()
5121 function = None
5122 offset = address - self.get_base()
5123
5124
5125
5126 start = self.get_entry_point()
5127 if start and start <= address:
5128 function = "start"
5129 offset = address - start
5130
5131
5132
5133 try:
5134 symbol = self.get_symbol_at_address(address)
5135 if symbol:
5136 (SymbolName, SymbolAddress, SymbolSize) = symbol
5137 new_offset = address - SymbolAddress
5138 if new_offset <= offset:
5139 function = SymbolName
5140 offset = new_offset
5141 except WindowsError, e:
5142 pass
5143
5144
5145 return SymbolOperations.parse_label(module, function, offset)
5146
5148 """
5149 Tries to determine if the given address belongs to this module.
5150
5151 @type address: int
5152 @param address: Memory address.
5153
5154 @rtype: bool or None
5155 @return: C{True} if the address belongs to the module,
5156 C{False} if it doesn't,
5157 and C{None} if it can't be determined.
5158 """
5159 base = self.get_base()
5160 size = self.get_size()
5161 if base and size:
5162 return base <= address < (base + size)
5163 return None
5164
5207
5209 """
5210 Resolves a label for this module only. If the label refers to another
5211 module, an exception is raised.
5212
5213 @type label: str
5214 @param label: Label to resolve.
5215
5216 @rtype: int
5217 @return: Memory address pointed to by the label.
5218
5219 @raise ValueError: The label is malformed or impossible to resolve.
5220 @raise RuntimeError: Cannot resolve the module or function.
5221 """
5222
5223
5224
5225 aProcess = self.get_process()
5226 if aProcess is not None:
5227 (module, procedure, offset) = aProcess.split_label(label)
5228 else:
5229 (module, procedure, offset) = Process.split_label(label)
5230
5231
5232
5233 if module and not self.match_name(module):
5234 raise RuntimeError, "Label does not belong to this module"
5235
5236
5237 if procedure:
5238 address = self.resolve(procedure)
5239 if address is None:
5240
5241
5242 address = self.resolve_symbol(procedure)
5243
5244
5245 if address is None and procedure == "start":
5246 address = self.get_entry_point()
5247
5248
5249 if address is None:
5250 if not module:
5251 module = self.get_name()
5252 msg = "Can't find procedure %s in module %s"
5253 msg = msg % (procedure, module)
5254 raise RuntimeError, msg
5255
5256
5257 else:
5258 address = self.get_base()
5259
5260
5261 if offset:
5262 address = address + offset
5263 return address
5264
5265
5266
5267 -class Thread (ThreadDebugOperations):
5268 """
5269 Interface to a thread in another process.
5270
5271 @group Properties:
5272 get_tid, get_pid, get_process, get_exit_code, is_alive,
5273 get_name, set_name
5274 @group Instrumentation:
5275 suspend, resume, kill, wait
5276 @group Registers:
5277 get_context,
5278 get_register,
5279 get_flags, get_flag_value,
5280 get_pc, get_sp, get_fp,
5281 get_cf, get_df, get_sf, get_tf, get_zf,
5282 set_context,
5283 set_register,
5284 set_flags, set_flag_value,
5285 set_pc, set_sp, set_fp,
5286 set_cf, set_df, set_sf, set_tf, set_zf,
5287 clear_cf, clear_df, clear_sf, clear_tf, clear_zf,
5288 Flags
5289 @group Handle:
5290 get_handle, open_handle, close_handle
5291
5292 @type dwThreadId: int
5293 @ivar dwThreadId: Global thread ID. Use L{get_tid} instead.
5294
5295 @type hThread: L{ThreadHandle}
5296 @ivar hThread: Handle to the thread. Use L{get_handle} instead.
5297
5298 @type process: L{Process}
5299 @ivar process: Parent process object. Use L{get_process} instead.
5300
5301 @type pInjectedMemory: int
5302 @ivar pInjectedMemory: If the thread was created by L{Process.inject_code},
5303 this member contains a pointer to the memory buffer for the injected
5304 code. Otherwise it's C{None}.
5305
5306 The L{kill} method uses this member to free the buffer
5307 when the injected thread is killed.
5308 """
5309
5310 - def __init__(self, dwThreadId, hThread = None, process = None):
5311 """
5312 @type dwThreadId: int
5313 @param dwThreadId: Global thread ID.
5314
5315 @type hThread: L{ThreadHandle}
5316 @param hThread: (Optional) Handle to the thread.
5317
5318 @type process: L{Process}
5319 @param process: (Optional) Parent Process object.
5320 """
5321 super(Thread, self).__init__()
5322 self.dwProcessId = None
5323 self.dwThreadId = dwThreadId
5324 self.hThread = hThread
5325 self.pInjectedMemory = None
5326 self.process = process
5327 self.set_name()
5328 if process is not None and not isinstance(process, Process):
5329 msg = "Parent process for Thread must be a Process instance, "
5330 msg += "got %s instead" % type(process)
5331 raise TypeError, msg
5332
5334 """
5335 @rtype: L{Process}
5336 @return: Parent Process object.
5337 """
5338 if self.process is None:
5339 self.process = Process(self.get_pid())
5340 return self.process
5341
5362
5381
5383 """
5384 @rtype: int
5385 @return: Thread global ID.
5386 """
5387 return self.dwThreadId
5388
5390 """
5391 @rtype: str
5392 @return: Thread name, or C{None} if the thread is nameless.
5393 """
5394 return self.name
5395
5397 """
5398 Sets the thread's name.
5399
5400 @type name: str
5401 @param name: Thread name, or C{None} if the thread is nameless.
5402 """
5403 self.name = name
5404
5405
5406
5416
5428
5437
5438
5439
5440 - def wait(self, dwTimeout = None):
5441 """
5442 Waits for the thread to finish executing.
5443
5444 @type dwTimeout: int
5445 @param dwTimeout: (Optional) Timeout value in milliseconds.
5446 Use C{INFINITE} or C{None} for no timeout.
5447 """
5448 self.get_handle().wait(dwTimeout)
5449
5450 - def kill(self, dwExitCode = 0):
5451 """
5452 Terminates the thread execution.
5453
5454 @note: If the C{lpInjectedMemory} member contains a valid pointer,
5455 the memory is freed.
5456
5457 @type dwExitCode: int
5458 @param dwExitCode: (Optional) Thread exit code.
5459 """
5460 win32.TerminateThread(self.get_handle(), dwExitCode)
5461 if self.pInjectedMemory is not None:
5462 try:
5463 self.get_process().free(self.pInjectedMemory)
5464 self.pInjectedMemory = None
5465 except Exception:
5466 pass
5467
5468
5470 """
5471 Suspends the thread execution.
5472
5473 @rtype: int
5474 @return: Suspend count. If zero, the thread is running.
5475 """
5476 return win32.SuspendThread(self.get_handle())
5477
5479 """
5480 Resumes the thread execution.
5481
5482 @rtype: int
5483 @return: Suspend count. If zero, the thread is running.
5484 """
5485 return win32.ResumeThread(self.get_handle())
5486
5488 """
5489 @rtype: bool
5490 @return: C{True} if the thread if currently running.
5491 """
5492 try:
5493 hProcess = self.get_handle()
5494 except WindowsError:
5495 return False
5496 try:
5497 hProcess.wait(0)
5498 except WindowsError:
5499 return False
5500 return True
5501
5503 """
5504 @rtype: int
5505 @return: Thread exit code, or C{STILL_ACTIVE} if it's still alive.
5506 """
5507 return win32.GetExitCodeThread(self.get_handle())
5508
5509
5510
5512 """
5513 @rtype: list of L{Window}
5514 @return: Returns a list of windows handled by this thread.
5515 """
5516 try:
5517 process = self.get_process()
5518 except Exception:
5519 process = None
5520 return [
5521 Window( hWnd, process, self ) \
5522 for hWnd in win32.EnumThreadWindows( self.get_tid() )
5523 ]
5524
5525
5526
5527
5528
5529 - def get_context(self, ContextFlags = None):
5530 """
5531 @type ContextFlags: int
5532 @param ContextFlags: Optional, specify which registers to retrieve.
5533 Defaults to C{win32.CONTEXT_ALL} which retrieves all registes
5534 for the current platform.
5535
5536 @rtype: dict( str S{->} int )
5537 @return: Dictionary mapping register names to their values.
5538
5539 @see: L{set_context}
5540 """
5541
5542
5543 hThread = self.get_handle()
5544
5545
5546
5547 try:
5548 self.suspend()
5549 bSuspended = True
5550 except WindowsError:
5551 bSuspended = False
5552
5553
5554 try:
5555
5556
5557 if not System.wow64:
5558
5559
5560
5561
5562
5563
5564
5565 ctx = win32.GetThreadContext(hThread,
5566 ContextFlags = ContextFlags)
5567
5568
5569 else:
5570 if self.is_wow64():
5571 ctx = win32.GetThreadContext(hThread,
5572 ContextFlags = ContextFlags)
5573 else:
5574
5575 if System.arch != 'i386':
5576 raise NotImplementedError
5577 if ContextFlags is not None:
5578 ContextFlags = ContextFlags & (~win32.ContextArchMask)
5579 ContextFlags = ContextFlags | win32.context_amd64.CONTEXT_AMD64
5580 ctx = win32.context_amd64.GetThreadContext(hThread,
5581 ContextFlags = ContextFlags)
5582 finally:
5583 if bSuspended:
5584 self.resume()
5585 return ctx
5586
5587 - def set_context(self, context):
5588 """
5589 Sets the values of the registers.
5590
5591 @see: L{get_context}
5592
5593 @type context: dict( str S{->} int )
5594 @param context: Dictionary mapping register names to their values.
5595 """
5596
5597
5598 self.suspend()
5599 try:
5600 if System.bits == 64 and self.is_wow64():
5601 win32.Wow64SetThreadContext(self.get_handle(), context)
5602 else:
5603 win32.SetThreadContext(self.get_handle(), context)
5604 finally:
5605 self.resume()
5606
5608 """
5609 @type register: str
5610 @param register: Register name.
5611
5612 @rtype: int
5613 @return: Value of the requested register.
5614 """
5615 'Returns the value of a specific register.'
5616 context = self.get_context()
5617 return context[register]
5618
5620 """
5621 Sets the value of a specific register.
5622
5623 @type register: str
5624 @param register: Register name.
5625
5626 @rtype: int
5627 @return: Register value.
5628 """
5629 context = self.get_context()
5630 context[register] = value
5631 self.set_context(context)
5632
5633
5634
5635 if win32.CONTEXT.arch in ('i386', 'amd64'):
5636
5638 """
5639 @rtype: int
5640 @return: Value of the program counter register.
5641 """
5642 context = self.get_context(win32.CONTEXT_CONTROL)
5643 return context.pc
5644
5646 """
5647 Sets the value of the program counter register.
5648
5649 @type pc: int
5650 @param pc: Value of the program counter register.
5651 """
5652 context = self.get_context(win32.CONTEXT_CONTROL)
5653 context.pc = pc
5654 self.set_context(context)
5655
5663
5665 """
5666 Sets the value of the stack pointer register.
5667
5668 @type sp: int
5669 @param sp: Value of the stack pointer register.
5670 """
5671 context = self.get_context(win32.CONTEXT_CONTROL)
5672 context.sp = sp
5673 self.set_context(context)
5674
5682
5684 """
5685 Sets the value of the frame pointer register.
5686
5687 @type fp: int
5688 @param fp: Value of the frame pointer register.
5689 """
5690 context = self.get_context(win32.CONTEXT_CONTROL)
5691 context.fp = fp
5692 self.set_context(context)
5693
5694 elif win32.CONTEXT.arch == 'ia64':
5695
5703
5705 """
5706 Sets the value of the frame pointer register.
5707
5708 @type gp: int
5709 @param gp: Value of the GP register.
5710 """
5711 context = self.get_context(win32.CONTEXT_CONTROL)
5712 context.gp = gp
5713 self.set_context(context)
5714
5722
5724 """
5725 Sets the value of the SP register.
5726
5727 @type sp: int
5728 @param sp: Value of the SP register.
5729 """
5730 context = self.get_context(win32.CONTEXT_CONTROL)
5731 context.sp = sp
5732 self.set_context(context)
5733
5741
5743 """
5744 Sets the value of the RP register.
5745
5746 @type rp: int
5747 @param rp: Value of the RP register.
5748 """
5749 context = self.get_context(win32.CONTEXT_CONTROL)
5750 context.rp = rp
5751 self.set_context(context)
5752
5753
5754
5755 if win32.CONTEXT.arch in ('i386', 'amd64'):
5756
5771
5772 - def get_flags(self, FlagMask = 0xFFFFFFFF):
5773 """
5774 @type FlagMask: int
5775 @param FlagMask: (Optional) Bitwise-AND mask.
5776
5777 @rtype: int
5778 @return: Flags register contents, optionally masking out some bits.
5779 """
5780 context = self.get_context(win32.CONTEXT_CONTROL)
5781 return context['EFlags'] & FlagMask
5782
5783 - def set_flags(self, eflags, FlagMask = 0xFFFFFFFF):
5784 """
5785 Sets the flags register, optionally masking some bits.
5786
5787 @type eflags: int
5788 @param eflags: Flags register contents.
5789
5790 @type FlagMask: int
5791 @param FlagMask: (Optional) Bitwise-AND mask.
5792 """
5793 context = self.get_context(win32.CONTEXT_CONTROL)
5794 context['EFlags'] = (context['EFlags'] & FlagMask) | eflags
5795 self.set_context(context)
5796
5798 """
5799 @type FlagBit: int
5800 @param FlagBit: One of the L{Flags}.
5801
5802 @rtype: bool
5803 @return: Boolean value of the requested flag.
5804 """
5805 return bool( self.get_flags(FlagBit) )
5806
5808 """
5809 Sets a single flag, leaving the others intact.
5810
5811 @type FlagBit: int
5812 @param FlagBit: One of the L{Flags}.
5813
5814 @type FlagValue: bool
5815 @param FlagValue: Boolean value of the flag.
5816 """
5817 if FlagValue:
5818 eflags = FlagBit
5819 else:
5820 eflags = 0
5821 FlagMask = 0xFFFFFFFF ^ FlagBit
5822 self.set_flags(eflags, FlagMask)
5823
5825 """
5826 @rtype: bool
5827 @return: Boolean value of the Zero flag.
5828 """
5829 return self.get_flag_value(self.Flags.Zero)
5830
5832 """
5833 @rtype: bool
5834 @return: Boolean value of the Carry flag.
5835 """
5836 return self.get_flag_value(self.Flags.Carry)
5837
5839 """
5840 @rtype: bool
5841 @return: Boolean value of the Sign flag.
5842 """
5843 return self.get_flag_value(self.Flags.Sign)
5844
5846 """
5847 @rtype: bool
5848 @return: Boolean value of the Direction flag.
5849 """
5850 return self.get_flag_value(self.Flags.Direction)
5851
5853 """
5854 @rtype: bool
5855 @return: Boolean value of the Trap flag.
5856 """
5857 return self.get_flag_value(self.Flags.Trap)
5858
5862
5866
5870
5874
5878
5882
5886
5890
5894
5898
5899
5900
5901 -class Process (MemoryOperations, ProcessDebugOperations, SymbolOperations, \
5902 ThreadContainer, ModuleContainer):
5903 """
5904 Interface to a process. Contains threads and modules snapshots.
5905
5906 @group Properties:
5907 get_pid, get_filename, get_exit_code,
5908 is_alive, is_debugged
5909
5910 @group Instrumentation:
5911 kill, wait, suspend, resume, inject_code, inject_dll
5912
5913 @group Processes snapshot:
5914 scan, clear, __contains__, __iter__, __len__
5915
5916 @group Handle:
5917 get_handle, open_handle, close_handle
5918
5919 @type dwProcessId: int
5920 @ivar dwProcessId: Global process ID. Use L{get_pid} instead.
5921
5922 @type hProcess: L{ProcessHandle}
5923 @ivar hProcess: Handle to the process. Use L{get_handle} instead.
5924
5925 @type fileName: str
5926 @ivar fileName: Filename of the main module. Use L{get_filename} instead.
5927 """
5928
5929 - def __init__(self, dwProcessId, hProcess = None, fileName = None):
5949
5951 """
5952 @rtype: int
5953 @return: Process global ID.
5954 """
5955 return self.dwProcessId
5956
5958 """
5959 @rtype: str
5960 @return: Filename of the main module of the process.
5961 """
5962 if not self.fileName:
5963 self.fileName = self.get_image_name()
5964 return self.fileName
5965
5976
5988
5997
5998
5999
6001 """
6002 The same as: C{self.has_thread(anObject) or self.has_module(anObject)}
6003
6004 @type anObject: L{Thread}, L{Module} or int
6005 @param anObject: Object to look for.
6006 Can be a Thread, Module, thread global ID or module base address.
6007
6008 @rtype: bool
6009 @return: C{True} if the requested object was found in the snapshot.
6010 """
6011 return ThreadContainer.__contains__(self, anObject) or \
6012 ModuleContainer.__contains__(self, anObject)
6013
6015 """
6016 @see: L{get_thread_count}, L{get_module_count}
6017 @rtype: int
6018 @return: Count of L{Thread} and L{Module} objects in this snapshot.
6019 """
6020 return ThreadContainer.__len__(self) + \
6021 ModuleContainer.__len__(self)
6022
6024 """
6025 Iterator object for L{Process} objects.
6026 Iterates through L{Thread} objects first, L{Module} objects next.
6027 """
6028
6030 """
6031 @type container: L{Process}
6032 @param container: L{Thread} and L{Module} container.
6033 """
6034 self.__container = container
6035 self.__iterator = None
6036 self.__state = 0
6037
6039 'x.next() -> the next value, or raise StopIteration'
6040 if self.__state == 0:
6041 self.__iterator = self.__container.iter_threads()
6042 self.__state = 1
6043 if self.__state == 1:
6044 try:
6045 return self.__iterator.next()
6046 except StopIteration:
6047 self.__iterator = self.__container.iter_modules()
6048 self.__state = 2
6049 if self.__state == 2:
6050 try:
6051 return self.__iterator.next()
6052 except StopIteration:
6053 self.__iterator = None
6054 self.__state = 3
6055 raise StopIteration
6056
6058 """
6059 @see: L{iter_threads}, L{iter_modules}
6060 @rtype: iterator
6061 @return: Iterator of L{Thread} and L{Module} objects in this snapshot.
6062 All threads are iterated first, then all modules.
6063 """
6064 return self.__ThreadsAndModulesIterator(self)
6065
6066
6067
6068 - def wait(self, dwTimeout = None):
6069 """
6070 Waits for the process to finish executing.
6071
6072 @raise WindowsError: On error an exception is raised.
6073 """
6074 self.get_handle().wait(dwTimeout)
6075
6076 - def kill(self, dwExitCode = 0):
6083
6085 """
6086 Suspends execution on all threads of the process.
6087
6088 @raise WindowsError: On error an exception is raised.
6089 """
6090 if self.get_thread_count() == 0:
6091 self.scan_threads()
6092 suspended = list()
6093 try:
6094 for aThread in self.iter_threads():
6095 aThread.suspend()
6096 suspended.append(aThread)
6097 except Exception:
6098 for aThread in suspended:
6099 try:
6100 aThread.resume()
6101 except Exception:
6102 pass
6103 raise
6104
6106 """
6107 Resumes execution on all threads of the process.
6108
6109 @raise WindowsError: On error an exception is raised.
6110 """
6111 if self.get_thread_count() == 0:
6112 self.scan_threads()
6113 resumed = list()
6114 try:
6115 for aThread in self.iter_threads():
6116 aThread.resume()
6117 resumed.append(aThread)
6118 except Exception:
6119 for aThread in resumed:
6120 try:
6121 aThread.suspend()
6122 except Exception:
6123 pass
6124 raise
6125
6127 """
6128 Tries to determine if the process is being debugged by another process.
6129 It may detect other debuggers besides WinAppDbg.
6130
6131 @rtype: bool
6132 @return: C{True} if the process has a debugger attached.
6133
6134 @warning:
6135 May return inaccurate results when some anti-debug techniques are
6136 used by the target process.
6137
6138 @note: To know if a process currently being debugged by a L{Debug}
6139 object, call L{Debug.is_debugee} instead.
6140 """
6141 return win32.CheckRemoteDebuggerPresent(self.get_handle())
6142
6144 """
6145 @rtype: bool
6146 @return: C{True} if the process is currently running.
6147 """
6148 try:
6149 self.wait(0)
6150 except WindowsError, e:
6151 return e.winerror == win32.WAIT_TIMEOUT
6152 return False
6153
6155 """
6156 @rtype: int
6157 @return: Process exit code, or C{STILL_ACTIVE} if it's still alive.
6158
6159 @warning: If a process returns C{STILL_ACTIVE} as it's exit code,
6160 you may not be able to determine if it's active or not with this
6161 method. Use L{is_alive} to check if the process is still active.
6162 Alternatively you can call L{get_handle} to get the handle object
6163 and then L{ProcessHandle.wait} on it to wait until the process
6164 finishes running.
6165 """
6166 return win32.GetExitCodeProcess(self.get_handle())
6167
6168
6169
6176
6183
6184
6185
6187 """
6188 @rtype: list of L{Window}
6189 @return: Returns a list of windows handled by this process.
6190 """
6191 window_list = list()
6192 for thread in self.iter_threads():
6193 window_list.extend( thread.get_windows() )
6194 return window_list
6195
6196
6197
6199 """
6200 Injects relocatable code into the process memory and executes it.
6201
6202 @see: L{inject_dll}
6203
6204 @type payload: str
6205 @param payload: Relocatable code to run in a new thread.
6206
6207 @type lpParameter: int
6208 @param lpParameter: (Optional) Parameter to be pushed in the stack.
6209
6210 @rtype: tuple( L{Thread}, int )
6211 @return: The injected Thread object
6212 and the memory address where the code was written.
6213
6214 @raise WindowsError: An exception is raised on error.
6215 """
6216
6217
6218
6219
6220
6221 lpStartAddress = self.malloc(len(payload))
6222
6223
6224 try:
6225
6226
6227 self.write(lpStartAddress, payload)
6228
6229
6230 aThread = self.start_thread(lpStartAddress, lpParameter,
6231 bSuspended = False)
6232
6233
6234
6235
6236
6237
6238 aThread.pInjectedMemory = lpStartAddress
6239
6240
6241 except Exception, e:
6242 self.free(lpStartAddress)
6243 raise
6244
6245
6246 return aThread, lpStartAddress
6247
6248
6249
6250
6251
6252 - def inject_dll(self, dllname, procname = None, lpParameter = 0,
6253 bWait = True, dwTimeout = None):
6254 """
6255 Injects a DLL into the process memory.
6256
6257 @warning: Setting C{bWait} to C{True} when the process is frozen by a
6258 debug event will cause a deadlock in your debugger.
6259
6260 @see: L{inject_code}
6261
6262 @type dllname: str
6263 @param dllname: Name of the DLL module to load.
6264
6265 @type procname: str
6266 @param procname: (Optional) Procedure to call when the DLL is loaded.
6267
6268 @type lpParameter: int
6269 @param lpParameter: (Optional) Parameter to the C{procname} procedure.
6270
6271 @type bWait: bool
6272 @param bWait: C{True} to wait for the process to finish.
6273 C{False} to return immediately.
6274
6275 @type dwTimeout: int
6276 @param dwTimeout: (Optional) Timeout value in milliseconds.
6277 Ignored if C{bWait} is C{False}.
6278
6279 @raise NotImplementedError: The target platform is not supported.
6280 Currently calling a procedure in the library is only supported in
6281 the I{i386} architecture.
6282
6283 @raise WindowsError: An exception is raised on error.
6284 """
6285
6286
6287 aModule = self.get_module_by_name('kernel32.dll')
6288 if aModule is None:
6289 self.scan_modules()
6290 aModule = self.get_module_by_name('kernel32.dll')
6291 if aModule is None:
6292 raise RuntimeError, \
6293 "Cannot resolve kernel32.dll in the remote process"
6294
6295
6296 if procname:
6297 if System.arch != 'i386':
6298 raise NotImplementedError
6299 dllname = str(dllname)
6300
6301
6302 pllib = aModule.resolve('LoadLibraryA')
6303 if not pllib:
6304 raise RuntimeError, \
6305 "Cannot resolve kernel32.dll!LoadLibraryA in the remote process"
6306
6307
6308 pgpad = aModule.resolve('GetProcAddress')
6309 if not pgpad:
6310 raise RuntimeError, \
6311 "Cannot resolve kernel32.dll!GetProcAddress in the remote process"
6312
6313
6314 pvf = aModule.resolve('VirtualFree')
6315 if not pvf:
6316 raise RuntimeError, \
6317 "Cannot resolve kernel32.dll!VirtualFree in the remote process"
6318
6319
6320 code = ''.encode('utf8')
6321
6322
6323 code += '\xe8' + struct.pack('<L', len(dllname) + 1) + dllname + '\0'
6324
6325
6326 code += '\xb8' + struct.pack('<L', pllib)
6327
6328
6329 code += '\xff\xd0'
6330
6331 if procname:
6332
6333
6334 code += '\xe8' + struct.pack('<L', len(procname) + 1)
6335 code += procname + '\0'
6336
6337
6338 code += '\x50'
6339
6340
6341 code += '\xb8' + struct.pack('<L', pgpad)
6342
6343
6344 code += '\xff\xd0'
6345
6346
6347 code += '\x8b\xec'
6348
6349
6350 code += '\x68' + struct.pack('<L', lpParameter)
6351
6352
6353 code += '\xff\xd0'
6354
6355
6356 code += '\x8b\xe5'
6357
6358
6359 code += '\x5a'
6360
6361
6362 code += '\x68' + struct.pack('<L', win32.MEM_RELEASE)
6363
6364
6365 code += '\x68' + struct.pack('<L', 0x1000)
6366
6367
6368 code += '\xe8\x00\x00\x00\x00'
6369
6370
6371 code += '\x81\x24\x24\x00\xf0\xff\xff'
6372
6373
6374 code += '\xb8' + struct.pack('<L', pvf)
6375
6376
6377 code += '\x52'
6378
6379
6380 code += '\xff\xe0'
6381
6382
6383 aThread, lpStartAddress = self.inject_code(code, lpParameter)
6384
6385
6386
6387 aThread.pInjectedMemory = None
6388
6389
6390 else:
6391
6392
6393 if type(dllname) == type(u''):
6394 pllibname = 'LoadLibraryW'
6395 bufferlen = (len(dllname) + 1) * 2
6396 dllname = win32.ctypes.create_unicode_buffer(dllname).raw[:bufferlen + 1]
6397 else:
6398 pllibname = 'LoadLibraryA'
6399 dllname = str(dllname) + '\x00'
6400 bufferlen = len(dllname)
6401 pllib = aModule.resolve(pllibname)
6402 if not pllib:
6403 msg = "Cannot resolve kernel32.dll!%s in the remote process"
6404 raise RuntimeError, msg % pllibname
6405
6406
6407 pbuffer = self.malloc(bufferlen)
6408 try:
6409 self.write(pbuffer, dllname)
6410
6411
6412 aThread = self.start_thread(pllib, pbuffer)
6413
6414
6415
6416
6417
6418 aThread.pInjectedMemory = pbuffer
6419
6420
6421 except Exception:
6422 self.free(pbuffer, bufferlen)
6423 raise
6424
6425
6426 if bWait:
6427 aThread.wait(dwTimeout)
6428
6429 - def clean_exit(self, dwExitCode = 0, bWait = False, dwTimeout = None):
6430 """
6431 Injects a new thread to call ExitProcess().
6432 Optionally waits for the injected thread to finish.
6433
6434 @warning: Setting C{bWait} to C{True} when the process is frozen by a
6435 debug event will cause a deadlock in your debugger.
6436
6437 @type dwExitCode: int
6438 @param dwExitCode: Process exit code.
6439
6440 @type bWait: bool
6441 @param bWait: C{True} to wait for the process to finish.
6442 C{False} to return immediately.
6443
6444 @type dwTimeout: int
6445 @param dwTimeout: (Optional) Timeout value in milliseconds.
6446 Ignored if C{bWait} is C{False}.
6447
6448 @raise WindowsError: An exception is raised on error.
6449 """
6450 if not dwExitCode:
6451 dwExitCode = 0
6452 pExitProcess = self.resolve_label('kernel32!ExitProcess')
6453 aThread = self.start_thread(pExitProcess, dwExitCode)
6454 if bWait:
6455 aThread.wait(dwTimeout)
6456
6457
6458
6460 """
6461 Notify the creation of a new process.
6462
6463 This is done automatically by the L{Debug} class, you shouldn't need
6464 to call it yourself.
6465
6466 @type event: L{CreateProcessEvent}
6467 @param event: Create process event.
6468 """
6469
6470 bCallHandler = ThreadContainer.notify_create_process(self, event)
6471 bCallHandler = bCallHandler and \
6472 ModuleContainer.notify_create_process(self, event)
6473 return bCallHandler
6474
6475
6476
6477 -class System (ProcessContainer):
6478 """
6479 Interface to a batch of processes, plus some system wide settings.
6480 Contains a snapshot of processes.
6481
6482 @group Global settings:
6483 arch, pageSize,
6484 set_kill_on_exit_mode, request_debug_privileges,
6485 enable_step_on_branch_mode
6486
6487 @type arch: str
6488 @cvar arch: Name of the processor architecture we're running on.
6489 For more details see L{win32.version.get_arch}.
6490
6491 @type bits: int
6492 @cvar bits: Size of the machine word in bits for the current architecture.
6493 For more details see L{win32.version.get_bits}.
6494
6495 @type os: str
6496 @cvar os: Name of the Windows version we're runing on.
6497 For more details see L{win32.version.get_os}.
6498
6499 @type wow64: bool
6500 @cvar wow64: C{True} if the debugger is a 32 bits process running in a 64
6501 bits version of Windows, C{False} otherwise.
6502
6503 @type pageSize: int
6504 @cvar pageSize: Page size in bytes. Defaults to 0x1000 but it's
6505 automatically updated on runtime when importing the module.
6506 """
6507
6508 arch = win32.version.arch
6509 bits = win32.version.bits
6510 os = win32.version.os
6511
6512
6513
6514 try:
6515 wow64 = win32.IsWow64Process( win32.GetCurrentProcess() )
6516 except Exception:
6517 wow64 = False
6518
6519
6520
6521 try:
6522 try:
6523 pageSize = win32.GetSystemInfo().dwPageSize
6524 except WindowsError:
6525 pageSize = 0x1000
6526 except NameError:
6527 pageSize = 0x1000
6528
6529
6530
6531 @staticmethod
6554
6555 @staticmethod
6557 """
6558 Automatically detach from processes when the current thread dies.
6559
6560 Works on the following platforms:
6561
6562 - Microsoft Windows XP and above.
6563 - Wine (Windows Emulator).
6564
6565 Fails on the following platforms:
6566
6567 - Microsoft Windows 2000 and below.
6568 - ReactOS.
6569
6570 @type bKillOnExit: bool
6571 @param bKillOnExit: C{True} to automatically kill processes when the
6572 debugger thread dies. C{False} to automatically detach from
6573 processes when the debugger thread dies.
6574
6575 @rtype: bool
6576 @return: C{True} on success, C{False} on error.
6577 """
6578 try:
6579
6580
6581 win32.DebugSetProcessKillOnExit(bKillOnExit)
6582 return True
6583 except (AttributeError, WindowsError):
6584 pass
6585 return False
6586
6587 @staticmethod
6589 """
6590 When tracing, call this on every single step event
6591 for step on branch mode.
6592
6593 @raise WindowsError:
6594 Raises C{ERROR_DEBUGGER_INACTIVE} if the debugger is not attached
6595 to least one process.
6596
6597 @warning:
6598 This has a HARDCODED value for a machine specific register (MSR).
6599 It could potentially brick your machine.
6600 It works on my machine, but your mileage may vary.
6601
6602 @note:
6603 It doesn't seem to work in VirtualBox machines.
6604 Maybe it fails in other virtualization/emulation environments,
6605 no extensive testing was made so far.
6606 """
6607 msr = win32.SYSDBG_MSR()
6608 msr.Address = 0x1D9
6609 msr.Data = 2
6610 return win32.NtSystemDebugControl(win32.SysDbgWriteMsr, msr)
6611