Package Libs ::
Module immlib
|
|
1
2 """
3 Immunity Debugger API for python
4
5 (c) Immunity, Inc. 2004-2007
6
7
8 U{Immunity Inc.<http://www.immunityinc.com>} Debugger API for python
9
10
11 """
12
13 __VERSION__ = '1.3'
14
15
16 import debugger
17 import immutils
18 import string
19 import time
20 import struct
21 import pickle
22 import cPickle
23 import libheap
24 import sys
25
26 from libhook import *
27 from libevent import *
28 from debugtypes import *
29 from libanalyze import *
30 from librecognition import FunctionRecognition
31 from libcontrolflow import ControlFlowAnalysis
32
33
34 BpKeys = {"VK_F2": 0x71, "VK_F4" : 0x73}
35 BpFlags = {"TY_STOPAN": 0x80L, "TY_SET": 0x100L, "TY_ACTIVE": 0x200L, "TY_DISABLED":0x400,\
36 "TY_ONESHOT": 0x800L, "TY_TEMP":0x1000L, "TY_KEEPCODE":0x2000L, "TY_KEEPCOND": 0x4000L,\
37 "TY_NOUPDATE":0x8000, "TY_RTRACE": 0x10000}
38
39
40
41 HB_FREE=0
42 HB_CODE=1
43 HB_ACCESS=2
44 HB_WRITE=3
45 HB_IO=4
46 HB_ONESHOT=5
47 HB_STOPAN=6
48 HB_TEMP=7
49
50 DebugerStatus = { "NONE":0, "STOPPED":1, "EVENT":2, "RUNNING": 3, "FINISHED":4, "CLOSING":5 }
51
52 Register = { "EAX" : 0 , "ECX" : 1, "EDX": 2, "EBX": 3, "ESP": 4, "EBP": 5, "ESI": 6, "EDI": 7, "EIP":8}
53
54 PageFlags = {0x1 : " ",0x2: "R ", 0x4:"RW ", 0x8: "RW COW", 0x10: " E",\
55 0x20: "R E", 0x40: "RWE", 0x80: "RWE COW"}
56
57 ImmFonts = {"fixed": 0, "terminal6": 1, "fixedsys":2, "courier":3, "lucida":4, "font5": 5,\
58 "font6": 6, "font7":7, "main": 8, "sys": 9, "info": 10}
59
60
61
62 BpMemFlags = {"R": 0x1, "W":0x2, "S":0x1000L}
63
64 MemoryProtection = { "PAGE_EXECUTE" :0x10, "PAGE_EXECUTE_READ" :0x20 , "PAGE_EXECUTE_READWRITE": 0x40,\
65 "PAGE_EXECUTE_WRITECOPY":0x80, "PAGE_NOACCESS":0x01, "PAGE_READONLY":0x02,\
66 "PAGE_READWRITE":0x04, "PAGE_WRITECOPY": 0x08 }
67
68
69
70 IgnoreSingleStep = {"DISABLE" : 0 , "FORCE" : 1 , "CONTINUE" : 2}
71
72
73
74
75
76
77
78
79 jmpTypeFlags = {"JUMP":0,\
80 "JUMP_COND":1,\
81 "JUMP_SWITCH":2,\
82 "CALL":3,\
83 "CALL_INTER":4}
84
85
86 NM_NONAME=0x00
87 NM_MODSEARCH=0xFD
88 NM_ANYNAME=0xFF
89
90 NM_PLUGCMD=0x30
91 NM_LABEL=0x31
92 NM_EXPORT=0x32
93 NM_IMPORT=0x33
94 NM_LIBRARY=0x34
95 NM_CONST=0x35
96 NM_COMMENT=0x36
97 NM_LIBCOMM=0x37
98 NM_BREAK=0x38
99 NM_ARG=0x39
100 NM_ANALYSE=0x3A
101 NM_BREAKEXPR=0x3B
102 NM_BREAKEXPL=0x3C
103 NM_ASSUME=0x3D
104 NM_STRUCT=0x3E
105 NM_CASE=0x3F
106
107 NM_INSPECT=0x40
108 NM_WATCH=0x41
109 NM_ASM=0x42
110 NM_FINDASM=0x43
111 NM_LASTWATCH=0x48
112 NM_SOURCE=0x49
113 NM_REFTXT=0x4A
114 NM_GOTO=0x4B
115 NM_GOTODUMP=0x4C
116 NM_TRPAUSE=0x4D
117
118 NM_DLLPARMS=0x50
119
120 NM_DEBUG=0x80
121 NM_IMPLIB=0x81
122 NM_IMPNAME=0x82
123 NM_FONT=0x83
124 NM_SCHEME=0x84
125 NM_GOTOSTACK=0x85
126 NM_HILITE=0x86
127
128 NM_IMCALL=0xFE
129
130
131 import UserDict
132
133
136 UserDict.IterableUserDict.__init__(self)
138 for k in self.data.keys():
139 yield self.data[k]
140
141
142 ImmDrawColors = {"Black":0,"Maroon":128,"Green":32768,"Olive":32896,"Navy":8388608,"Purple":8388736,"Teal":8421376,\
143 "Gray":8421504,"Silver":12632256,"Red":255,"Lime":65280,"Yellow":65535,"Blue":16711680,"Fuchsia":16711935,\
144 "Aqua":16776960,"LightGray":12632256,"DarkGray":8421504,"White":16777215,"MoneyGreen":12639424,\
145 "SkyBlue":15780518,"Cream":15793151,"MedGray":10789024,"red":255,"darkgreen":32768}
146
147
148
149
150
151
154 """ Initialize the Immunity Debugger API"""
155 self.threadid = 0
156 os = self.getOsInformation()
157 self.ossystem = os[ 0 ].lower()
158 self.osversion = os[ 1 ].lower()
159 self.osrelease = os[ 2 ].lower()
160 self.isWin7 = False
161
162
163 self.isVista = self.getOsRelease()[0] == '6'
164 if self.isVista:
165 tmprelease = self.getOsRelease()
166 if len(tmprelease) > 3:
167 if tmprelease[2] == '1':
168 self.isWin7 = True
169 self.isVista = False
170
171 self.Eventndx = { debugger.CREATE_PROCESS_DEBUG_EVENT : CreateProcessEvent,
172 debugger.CREATE_THREAD_DEBUG_EVENT : CreateThreadEvent,
173 debugger.EXCEPTION_DEBUG_EVENT : ExceptionEvent,
174 debugger.EXIT_PROCESS_DEBUG_EVENT : ExitProcessEvent,
175 debugger.EXIT_THREAD_DEBUG_EVENT : ExitThreadEvent,
176 debugger.LOAD_DLL_DEBUG_EVENT : LoadDLLEvent,
177 debugger.OUTPUT_DEBUG_STRING_EVENT : OutputDebugEvent,
178 debugger.UNLOAD_DLL_DEBUG_EVENT : UnloadDLLEvent,
179 debugger.RIP_EVENT : RIPEvent }
180
181 self.clearState()
182
184 self.Symbols = DictTypes()
185 self.Handles = DictTypes()
186 self.Threads = DictTypes()
187 self.MemoryPages = DictTypes()
188 self.Modules = DictTypes()
189 self.BackTrace = []
190 self.HeapsAddr = []
191 self.Heaps = {}
192
193
194
196 return self.error("%d" % (0x15 * 2))
197
198
199
200
201
203 """
204 This function add a python object to the knowledge database.
205
206 @type id: STRING
207 @param id: unique name tag of the object
208
209 @type object: Python object
210 @param object: Object to be saved in the knowledge database
211 """
212
213 pickled_object=pickle.dumps(object)
214 return debugger.add_knowledge(pickled_object,id, force_add)
215
217 """
218 Gets python object from the knowledge database.
219
220 @type id: STRING
221 @param id: unique name tag of the object
222
223 @rtype: PYTHON OBJECT
224 @return: Object retrieved from the knowledge database
225 """
226 pickled_object=debugger.get_knowledge(id)
227
228 if not pickled_object:
229 return None
230 return pickle.loads(pickled_object)
231
233 """
234 Gets the list of saved objects in the knowledge database.
235
236 @rtype: TUPLE
237 @return: List of String ids currently saved
238 """
239 return debugger.list_knowledge()
240
242 """
243 Find possible Packer/Cryptors/etc on a Module
244
245 @type name: STRING
246 @param name: Module name
247
248 @type OnMemory: (Optional, Def: True) BOOLEAN
249 @param OnMemory: Whether to look in memory or on a file.
250
251 @rtype: LIST of TUPLES in the form of (DWORD, LIST OF STRING)
252 @return: A list of the Packer founded (Offset, List of Packer found in that address)
253 """
254 if OnMemory:
255 mem = self.getMemoryPageByOwner(name)
256 if not mem:
257 raise Exception, "Coudln't find a Memory Page belonging to %s" % name
258 data = ""
259 for a in mem:
260 data+= a.getMemory()
261 else:
262 mod = self.getModule( name )
263 if not mod:
264 raise Exception, "Coudln't find the correct Module belonging to %s" % name
265 data = mod.getPath()
266
267 import pefile
268 import peutils
269 if OnMemory:
270 pe = pefile.PE( data = data )
271 else:
272 pe = pefile.PE( name = data )
273
274 sig_db = peutils.SignatureDatabase('Data/UserDB.TXT')
275 return sig_db.match( pe )
276
278 """
279 Remove python object from knowledge database.
280
281 @type id: STRING
282 @param id: unique name tag of the object
283 """
284 return debugger.forget_knowledge(id)
285
291
292
294 """
295 Add a hook to Immunity Debugger
296 """
297
298 import pickle
299 try:
300 rtype=object.type
301 except:
302 rtype=0
303 try:
304 label=object.label
305 except:
306 label="No Label specified for this hook"
307 pickled_object=pickle.dumps(object)
308 debugger.add_hook(pickled_object,label,rtype)
309
310
312 """
313 Clean ID memory from hook objects
314 """
315 for hk in self.listHooks():
316 debugger.remove_hook(hk)
317
318
319
321 """
322 Clean ID memory for every kind of object saved in it
323 """
324 self.cleanHooks()
325 self.cleanKnowledge()
326
327
329 """
330 Gets PEB.
331 @rtype: DWORD
332 @return: PEB address
333 """
334 return debugger.get_PEB()
335
336
337
338
339
341 """
342 Analyse module's code
343
344 @type Address: DWORD
345 @param Address: Address from module to be analysed
346 """
347 debugger.analyse_code(address)
348
350 """
351 Check if module is already analysed
352
353 @type Address: DWORD
354 @param Address: Address from module
355
356 @rtype: DWORD
357 @return: 1 if module already analysed
358 """
359 ret = debugger.is_analysed(address)
360
361 if ret == -1:
362 return 0
363 else:
364 return ret
365
367 """
368 Set Variable name to specified address.
369
370 @type Address: DWORD
371 @param Address: Address from assembly line
372
373 @type String: STRING
374 @param String: Variable name to be set
375
376 """
377 return debugger.set_variable(address,string)
378
380 """
381 Get Variable name from specified address
382
383 @type Address: DWORD
384 @param Address: Address from assembly line
385
386 @rtype: STRING
387 @return: Variable name for given address.
388
389 """
390 return debugger.get_variable(address)
391
392
394 """
395 It validates if a given address has the permissions provided in <perm>.
396 perm = RWXNC (N=No Access, C=Write Copy)
397 """
398
399 mem = self.getMemoryPageByAddress(address)
400 if not mem:
401 return False
402
403 access = mem.getAccess()
404 ret = True
405
406 if "X" in perm:
407 ret = ret and access >= 0x10
408 if "R" in perm:
409 ret = ret and (access >= 0x20 or (access >= 0x2 and access <= 0x8))
410 if "W" in perm:
411 ret = ret and (access >= 0x40 or (access >= 0x4 and access <= 0x8))
412 if "C" in perm:
413 ret = ret and (access == 0x80 or access == 0x8)
414 if "N" in perm:
415 ret = ret and access == 0x1
416
417 return ret
418
424
425
427 """
428 disasm address
429
430 @type Address: DWORD
431 @param Address: Address to disasm
432
433 @type Mode: (Optional, Def: DISASM_ALL)
434 @param Mode: disasm mode
435
436 @rtype: opCode Object (Check libanalyze.py)
437 @return: Disassmbled Opcode
438 """
439
440 op= opCode( self, address )
441 op._getfromtuple( debugger.disasm( address, mode) )
442 return op
443
444
445
447 """
448 Determine command size only
449
450 @type Address: DWORD
451 @param Address: Address to disasm
452
453 @rtype: opCode Object (Check libanalyze.py)
454 @return: Disassmbled Opcode
455 """
456 return self.disasm(address, DISASM_SIZE)
457
458
460 """
461 Determine size and analysis data
462
463 @type Address: DWORD
464 @param Address: Address to disasm
465
466 @rtype: opCode Object (Check libanalyze.py)
467 @return: Disassmbled Opcode
468 """
469 return self.disasm(address, DISASM_DATA)
470
472 """
473 Trace integer registers
474
475 @type Address: DWORD
476 @param Address: Address to disasm
477
478 @rtype: opCode Object (Check libanalyze.py)
479 @return: Disassmbled Opcode
480 """
481 return self.disasm(address, DISASM_TRACE)
482
483
485 """
486 Disassembly, no symbols/registers
487
488 @type Address: DWORD
489 @param Address: Address to disasm
490
491 @rtype: opCode Object (Check libanalyze.py)
492 @return: Disassmbled Opcode
493 """
494 return self.disasm(address, DISASM_FILE)
495
496
498 """
499 Disassembly, registers undefined
500
501 @type Address: DWORD
502 @param Address: Address to disasm
503
504 @rtype: opCode Object (Check libanalyze.py)
505 @return: Disassmbled Opcode
506 """
507 return self.disasm(address, DISASM_CODE)
508
510 """
511 Disassemble with run-trace registers
512
513 @type Address: DWORD
514 @param Address: Address to disasm
515
516 @rtype: opCode Object (Check libanalyze.py)
517 @return: Disassmbled Opcode
518 """
519 return self.disasm(address, DISASM_RTRACE)
520
521
523 """
524 disasm nlines forward of given address
525
526 @type Address: DWORD
527 @param Address: Address to disasm
528
529 @type nlines: DWORD
530 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
531
532 @type Mode: (Optional, Def: DISASM_ALL)
533 @param Mode: disasm mode
534
535 @rtype: opCode Object (Check libanalyze.py)
536 @return: Disassmbled Opcode
537 """
538 forward_address = debugger.disasm_forward( address, nlines )
539 op=opCode( self, forward_address )
540 op._getfromtuple( debugger.disasm( forward_address, mode ) )
541 return op
542
543
544
546 """
547 disasm nlines forward to the given address
548
549 @type Address: DWORD
550 @param Address: Address to disasm
551
552 @type nlines: DWORD
553 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
554
555 @type Mode: (Optional, Def: DISASM_ALL)
556 @param Mode: disasm mode
557
558 @rtype: DWORD
559 @return: Address of the opcode
560 """
561 return debugger.disasm_forward(address,nlines)
562
564 """
565 Determine command size only
566
567 @type Address: DWORD
568 @param Address: Address to disasm
569
570 @type nlines: DWORD
571 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
572
573 @rtype: opCode Object (Check libanalyze.py)
574 @return: Disassmbled Opcode
575 """
576 return self.disasmForward(address, nlines, DISASM_SIZE)
577
579 """
580 Determine size and analysis data
581
582 @type Address: DWORD
583 @param Address: Address to disasm
584
585 @type nlines: DWORD
586 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
587
588 @rtype: opCode Object (Check libanalyze.py)
589 @return: Disassmbled Opcode
590
591 """
592 return self.disasmForward(address, nlines, DISASM_DATA)
593
595 """
596 Trace integer registers
597
598 @type Address: DWORD
599 @param Address: Address to disasm
600
601 @type nlines: DWORD
602 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
603
604 @rtype: opCode Object (Check libanalyze.py)
605 @return: Disassmbled Opcode
606 """
607 return self.disasmForward(address, nlines, DISASM_TRACE)
608
610 """
611 Disassembly, no symbols/registers
612
613 @type Address: DWORD
614 @param Address: Address to disasm
615
616 @type nlines: DWORD
617 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
618
619 @rtype: opCode Object (Check libanalyze.py)
620 @return: Disassmbled Opcode
621 """
622 return self.disasmForward(address, nlines, DISASM_FILE)
623
625 """
626 Disassembly, registers undefined
627
628 @type Address: DWORD
629 @param Address: Address to disasm
630
631 @type nlines: DWORD
632 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
633
634 @rtype: opCode Object (Check libanalyze.py)
635 @return: Disassmbled Opcode
636 """
637 return self.disasmForward(address, DISASM_CODE)
638
640 """
641 Disassemble with run-trace registers
642
643 @type Address: DWORD
644 @param Address: Address to disasm
645
646 @type nlines: DWORD
647 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
648
649 @rtype: opCode Object (Check libanalyze.py)
650 @return: Disassmbled Opcode
651 """
652 return self.disasmForward(address, nlines, DISASM_RTRACE)
653
655 """
656 disasm nlines backward from the given address
657
658 @type Address: DWORD
659 @param Address: Address to disasm
660
661 @type nlines: DWORD
662 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
663
664 @rtype: opCode Object (Check libanalyze.py)
665 @return: Disassmbled Opcode
666 """
667 backward_address = debugger.disasm_backward( address, nlines )
668 op = opCode( self, backward_address )
669 op._getfromtuple( debugger.disasm( backward_address, mode ) )
670 return op
671
673 """
674 disasm nlines backward of given address
675
676 @type Address: DWORD
677 @param Address: Address to disasm
678
679 @type nlines: DWORD
680 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
681
682 @rtype: DWORD
683 @return: Address of the Opcode"""
684 return debugger.disasm_backward(address,nlines)
685
686
687
689 """
690 Determine command size only
691
692 @type Address: DWORD
693 @param Address: Address to disasm
694
695 @type nlines: DWORD
696 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
697
698 @rtype: opCode Object (Check libanalyze.py)
699 @return: Disassmbled Opcode
700 """
701 return self.disasmBackward(address, nlines, DISASM_SIZE)
702
704 """
705 Determine size and analysis data
706
707 @type Address: DWORD
708 @param Address: Address to disasm
709
710 @type nlines: DWORD
711 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
712
713 @rtype: opCode Object (Check libanalyze.py)
714 @return: Disassmbled Opcode
715 """
716 return self.disasmBackward(address, nlines, DISASM_DATA)
717
719 """
720 Trace integer registers
721
722 @type Address: DWORD
723 @param Address: Address to disasm
724
725 @type nlines: DWORD
726 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
727
728 @rtype: opCode Object (Check libanalyze.py)
729 @return: Disassmbled Opcode
730 """
731 return self.disasmBackward(address, nlines, DISASM_TRACE)
732
734 """
735 Disassembly, no symbols/registers
736
737 @type Address: DWORD
738 @param Address: Address to disasm
739
740 @type nlines: DWORD
741 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
742
743 @rtype: opCode Object (Check libanalyze.py)
744 @return: Disassmbled Opcode
745 """
746 return self.disasmBackward(address, nlines, DISASM_FILE)
747
749 """
750 Disassembly, registers undefined
751
752 @type Address: DWORD
753 @param Address: Address to disasm
754
755 @type nlines: DWORD
756 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
757
758 @rtype: opCode Object (Check libanalyze.py)
759 @return: Disassmbled Opcode
760 """
761 return self.disasmBackward(address, nlines, DISASM_CODE)
762
764 """
765 Disassemble with run-trace registers
766
767 @type Address: DWORD
768 @param Address: Address to disasm
769
770 @type nlines: DWORD
771 @param nlines: (Optional, Def: 1) Number of lines to disassemble forward
772
773 @rtype: opCode Object (Check libanalyze.py)
774 @return: Disassmbled Opcode
775 """
776 return self.disasmBackward(address, nlines, DISASM_RTRACE)
777
779 """
780 Get the internal decode information from an analysed module
781
782 @type Address: DWORD
783 @param Address: Address in the range of the module page
784
785 @rtype: Decode OBJECT
786 @return: Decode Object containing the analized information
787 """
788 return Decode( address )
789
790
792 """
793 Go to next procedure
794
795 @rtype: DWORD
796 @return: Address of next procedure
797 """
798 return debugger.go_next_procedure()
799
801 """
802 Go to previous procedure
803
804 @rtype: DWORD
805 @return: Address of previous procedure
806 """
807 return debugger.go_previous_procedure()
808
810 """
811 Get address's Opcode
812
813 @type Address: DWORD
814 @param Address: Address to disasm
815
816 @rtype: opCode Object (Check libanalyze.py)
817 @return: Disassmbled Opcode
818 """
819 op=opCode(self, address)
820 op._getfromtuple(debugger.disasm(address))
821 return op
822
824 """
825 assemble code.
826
827 @type code: STRING
828 @param code: Code to be assembled
829
830 @rtype: STRING
831 @return: Opcodes of the assembled code
832 """
833 opcode = []
834 for line in code.split("\n"):
835 line = line.strip()
836 if line:
837 opcode.append( debugger.assemble(line,address) )
838 return string.joinfields( opcode, "")
839
841 """
842 Decode given address
843
844 @rtype: STRING
845 @return: decoded value
846 """
847 return debugger.decode_address(address)
848
850 """
851 Undecorate given name
852
853 @type decorated: STRING
854 @param decorated: decorated name
855 @rtype: STRING
856 @return: undecorated name
857 """
858 return debugger.undecorate_name(decorated)
859
860 - def getTraceArgs(self, address, tracedarg, shownonusersupplied = False):
861 """
862 Trace Parameters of a function, return only when is user-supplied
863
864 @type Address: DWORD
865 @param Address: Address of the function call
866
867 @type Tracedarg: DWORD
868 @param Tracedarg: Parameter to trace
869
870 @type Shownonusersupplied: BOOLEAN
871 @param Shownonusersupplied: (Optional, Def: False) Flag whether or not show user supplied param
872
873 @rtype: TUPLES
874 @return: Returns a tuple of (Push Opcode, TABLE of OPCODES setting the PUSH)
875 """
876 t = TraceArgs( self, address, tracedarg, shownonusersupplied )
877 return t.get()
878
880 """
881 Gets all function of given module's address
882
883 @rtype: LIST
884 @return: Function start address
885 """
886 return debugger.get_all_functions(address)
887
889 """
890 Get the Function information
891
892 @type Address: DWORD
893 @param Address: Address of the function
894
895 @rtype: Function Object
896 @return: Function Object containing information of the requested function
897
898 """
899 return Function(self, address)
900
902 """
903 Find start address of funcion
904
905 @rtype: DWORD
906 @return: Start Address"""
907 return debugger.get_func_begin(address)
908
910 """
911 Get all the possible ends of a Function
912
913 @type function_address: DWORD
914 @param function_address: Address of the function
915
916 @rtype: LIST
917 @return: List of Address of all the possible ret address
918 """
919 if type(function_address) in (type(1), type(1L)):
920 func = self.getFunction( function_address )
921 return func.getFunctionEnd()
922 elif isinstance(function_address, Function):
923 return function_address.getFunctionEnd()
924 else:
925 raise Exception, "Function type not recognized"
926
927
928
929
930
931
932
933
934
935
937 """
938 Gets all basic blocks of given procedure (Deprecated, use Function)
939
940 @rtype: LIST
941 @return: (start,end) addresses of basic blocks
942 """
943 bblocks = debugger.get_all_basic_blocks(address)
944 basicblocks = []
945 if bblocks:
946 for block in bblocks:
947 basicblocks.append(basicBlock(self,block[0],block[1]))
948 return basicblocks
949
951 """
952 Find data references to given address
953
954 @rtype: LIST
955 @return: Table with found references
956 """
957 return debugger.find_data_ref(address)
958
960 """
961 Get X Reference from a given address
962
963 @type Address: DWORD
964 @param Address: Address
965
966 @rtype: LIST
967 @return: List of X reference from the given address
968 """
969 for mod in self.getAllModules():
970 xref = mod.getXrefFrom(address)
971
972 if xref: return xref
973 return []
974
976 """
977 Get X Reference to a given address
978
979 @type Address: DWORD
980 @param Address: Address
981
982 @rtype: LIST
983 @return: List of X reference to the given address
984 """
985 for mod in self.getAllModules():
986 xref = mod.getXrefTo(address)
987
988 if xref: return xref
989 return []
990
992 """
993 Get intermodular calls
994
995 @type Address: DWORD
996 @param Address: Address
997
998 @rtype: DICTIONARY
999 @return: Dict of intermodular calls to the given address
1000 """
1001 self.gotoDisasmWindow(address)
1002 return debugger.get_inter_calls(address)
1003
1004
1005
1006
1007
1009 """
1010 Get CPU Context values.
1011
1012 @rtype: DICTIONARY
1013 @return: x86 Registers
1014 """
1015 return debugger.get_regs()
1016
1018 """
1019 We have to do this to handle the Long integers, which XML-RPC cannot do
1020
1021 @rtype: DICTIONARY
1022 @return: x86 registers in string format (repr)
1023 """
1024 regs=self.getRegs()
1025
1026 for r in regs:
1027 regs[r]=repr(regs[r])
1028 return regs
1029
1031 """
1032 Set REG value
1033
1034 @type reg: STRING
1035 @param reg: Register name
1036
1037 @type value: DWORD
1038 @param vale: Value to set the register
1039 """
1040 return debugger.set_reg(Register[reg],value)
1041
1043 """
1044 Get the PEB information of the debugged process
1045
1046 @rtype: PEB OBJECT
1047 @return: PEB """
1048
1049 return PEB(self)
1050
1051
1052 - def getHeap(self, addr, restore = False):
1053 """
1054 Get Heap Information
1055
1056 @type addr: DWORD
1057 @param addr: Address of the heap
1058
1059 @type restore: BOOLEAN
1060 @param restore: (Optional, Def: False) Flag whether or not use a restore heap
1061
1062 @rtype: PHeap OBJECT
1063 @return: Heap
1064 """
1065 if self.Heaps.has_key(addr):
1066 return self.Heaps[addr]
1067
1068 if self.isVista or self.isWin7:
1069 pheap = libheap.VistaPHeap( self, addr, restore )
1070 else:
1071 pheap = libheap.PHeap( self, addr, restore )
1072
1073 if pheap:
1074 self.Heaps[addr] = pheap
1075 return pheap
1076
1078 """
1079 Get debugged name
1080
1081 @rtype: STRING
1082 @return: Name of the Process been debugged
1083 """
1084 return debugger.get_debugged_name()
1085
1087 """
1088 Get debugged pid
1089
1090 @rtype: DWORD
1091 @return: Process ID
1092 """
1093 return debugger.get_PID()
1094
1096 """
1097 Is debugger running as admin?
1098 @rtype: INTEGER
1099 @return: 1 if running as admin
1100 """
1101 return debugger.is_admin()
1102
1104 """
1105 Get information displayed on Info Panel
1106
1107 @rtype: TUPLE
1108 @return: Python Tuple with the 3 lines from InfoPanel
1109 """
1110 return debugger.get_info_panel()
1111
1113 """
1114 Get the current address been focus on the disasm window
1115
1116 @rtype: DWORD
1117 @return: Address
1118 """
1119 return debugger.get_current_address()
1120
1121
1123 """
1124 Get all loaded modules.
1125
1126 @rtype: DICTIONARY
1127 @return: Dict of Modules
1128 """
1129
1130 if self.Modules:
1131 return self.Modules
1132
1133 modulos = debugger.get_all_modules()
1134 symbol = 1
1135 for mod in modulos.keys():
1136 if not self.Modules.has_key(mod):
1137
1138 m = Module(mod, modulos[mod][0], modulos[mod][1], modulos[mod][2])
1139 mod_dict = self._getmoduleinfo(modulos[mod][0])
1140 m.setModuleExtension(mod_dict)
1141 if symbol:
1142 self.getAllSymbols()
1143 symbol = 0
1144
1145 try:
1146 m.setSymbols( self.Symbols[ mod.lower() ] )
1147 except KeyError:
1148 pass
1149 self.Modules[mod] = m
1150
1151
1152
1153 return self.Modules
1154
1156
1157 modulos = debugger.get_all_modules()
1158
1159 for name in modulos.keys():
1160 total_range = modulos[name][0] + modulos[name][1]
1161 if address > modulos[name][0] and address < total_range:
1162 if not self.Modules.has_key(name):
1163 m = Module(name, modulos[name][0], modulos[name][1], modulos[name][2])
1164 mod_dict = self._getmoduleinfo(modulos[name][0])
1165 m.setModuleExtension(mod_dict)
1166 self.Modules[name] = m
1167 return m
1168 else:
1169 return self.Modules[name]
1170
1172 """
1173 Get Module Information
1174
1175 @type name: STRING
1176 @param name: Name of the module
1177
1178 @rtype: Module OBJECT
1179 @return: A Module object
1180 """
1181
1182
1183
1184 modulos = debugger.get_all_modules()
1185 if modulos.has_key(name):
1186 if not self.Modules.has_key(name):
1187
1188 m = Module(name, modulos[name][0], modulos[name][1], modulos[name][2])
1189 mod_dict = self._getmoduleinfo(modulos[name][0])
1190 m.setModuleExtension(mod_dict)
1191
1192
1193
1194
1195
1196
1197
1198
1199 self.Modules[name] = m
1200 return m
1201 else:
1202 return self.Modules[name]
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213 return None
1214
1216 return debugger.get_mod_info(base_address)
1217
1219 """
1220 Get all referenced string from module
1221
1222 @type name: DWORD
1223 @param name: Code Base Address
1224 @rtype: LIST
1225 @return: A list of tuples with referenced strings (address, string, comment)
1226 """
1227 return debugger.get_referenced_strings(code_base)
1228
1230 """
1231 List all active processes.
1232
1233 @rtype: LIST
1234 @return: A list of tuples with process information (pid, name, path, services, tcp list, udp list)
1235 """
1236 return debugger.ps()
1237
1239 """
1240 Get the SEH chain.
1241
1242 @rtype: LIST
1243 @return: A list of tuples with SEH information (seh, handler)
1244 """
1245 return debugger.get_seh_chain()
1246
1248 """
1249 Get the current Event
1250
1251 @rtype: Event Object
1252 @return: Event
1253 """
1254 event = debugger.get_event()
1255 EventCode = event[0][0]
1256 try:
1257 return self.Eventndx[ EventCode ]( event )
1258 except KeyError:
1259 return None
1260
1261 - def getPage(self, addr):
1262 """
1263 Get a memory page.
1264
1265 @type addr: DWORD
1266 @param addr: Address of a beginning of the Page
1267
1268 @rtype: Page OBJECT
1269 @return: Memory Page
1270 """
1271 self.getMemoryPages()
1272 try:
1273 return self.MemoryPages[addr]
1274 except KeyError:
1275 return None
1276
1277 - def getMemoryPageByOwner(self, owner):
1278 """
1279 Get the Memory Pages belonging to the given dll.
1280
1281 @type owner: STRING
1282 @param owner: Name of the dll
1283
1284 @rtype: LIST
1285 @return: LIST of Memory Pages belonging to the given dll
1286 """
1287 self.getMemoryPages()
1288
1289 pages = []
1290 for a in self.MemoryPages.keys():
1291 mem = self.MemoryPages[a]
1292 if mem.getOwner().lower() == owner.lower():
1293 pages.append( mem )
1294
1295 return pages
1296
1297 - def getMemoryPageByOwnerAddress(self, owner_addr):
1298 """
1299 Get the Memory Pages belonging to the given dll by its base address.
1300
1301 @type owner: STRING
1302 @param owner: Name of the dll
1303
1304 @rtype: LIST
1305 @return: LIST of Memory Pages belonging to the given dll
1306 """
1307 self.getMemoryPages()
1308
1309 pages = []
1310 for a in self.MemoryPages.keys():
1311 mem = self.MemoryPages[a]
1312 if mem.owner == owner_addr:
1313 pages.append( mem )
1314
1315 return pages
1316
1317 - def getMemoryPageByAddress(self, address):
1318 """
1319 Get a memory page.
1320
1321 @type address: DWORD
1322 @param address: Address in the range of the Page
1323
1324 @rtype: Page OBJECT
1325 @return: Memory Page
1326 """
1327
1328 self.getMemoryPages()
1329 for a in self.MemoryPages.keys():
1330 mem = self.MemoryPages[a]
1331 if mem.baseaddress <= address and (mem.getBaseAddress() + mem.size) > address :
1332 return mem
1333 return None
1334
1335 - def getMemoryPages(self):
1336 """
1337 Get All memory pages.
1338
1339 @rtype: DICTIONARY
1340 @return: List of all memory pages
1341 """
1342 if self.MemoryPages:
1343 return self.MemoryPages
1344
1345 pages = debugger.get_memory_pages()
1346
1347 for addr in pages.keys():
1348 m = MemoryPage(addr, self)
1349 m._getfromtuple(pages[addr])
1350 self.MemoryPages[addr] = m
1351 return self.MemoryPages
1352
1354 """
1355 Query Memory Page
1356
1357 @type address: DWORD
1358 @param address: Base Address of memory page
1359
1360 @rtype: Python List
1361 @return: List with memory page structure
1362 """
1363 return debugger.vm_query(address)
1364
1365
1367 """
1368 Get all handles.
1369
1370 @rtype: DICTIONARY
1371 @return: All the process handles
1372 """
1373 if self.Handles:
1374 return self.Handles
1375
1376 handles = debugger.get_all_handles()
1377 for h in handles.keys():
1378 H = Handle( h )
1379 H._getfromtuple( handles[h] )
1380 self.Handles[ h ] = H
1381 return self.Handles
1382
1384 """
1385 Get all threads.
1386 @rtype: LIST
1387 @return: All process threads
1388 """
1389
1390 self.Threads = DictTypes()
1391 threads = debugger.get_all_threads()
1392 for thread in threads:
1393 T = Thread()
1394 T._getfromtuple(thread)
1395 self.Threads[T.getId()] = T
1396 return self.Threads
1397
1398
1399
1400
1402 """
1403 Get All Symbols.
1404
1405 @rtype: DICTIONARY
1406 @return: All the symbols of the process
1407 """
1408 if self.Symbols:
1409 return self.Symbols
1410
1411 names = debugger.get_all_names()
1412 current = self.getDebuggedName().rsplit(".", 1)[0]
1413
1414 for a in names.keys():
1415 s=Symbol(a)
1416 s._getfromtuple( names[a] )
1417 if current.lower() != s.getModule().lower():
1418 module = s.getModule() + ".dll"
1419 else:
1420 module = s.getModule() + ".exe"
1421
1422 if self.Symbols.has_key( module ):
1423 self.Symbols[ module ][ a ] = s
1424 else:
1425 self.Symbols[ module ] = { a : s }
1426
1427 return self.Symbols
1428
1430 """
1431 Get Symbols from module.
1432 @type Address: DWORD
1433 @param Address: Address from module.
1434
1435 @rtype: DICTIONARY
1436 @return: All the symbols of the module
1437 """
1438
1439 names = debugger.get_all_names(address)
1440 return names
1441
1442
1443
1445 """
1446 Get a Back Trace (Call stack).
1447
1448 @rtype: LIST of Stack OBJECT
1449 @return: list of all the stack trace
1450 """
1451 if self.BackTrace:
1452 return self.BackTrace
1453
1454 callstack = debugger.get_call_stack()
1455 for a in callstack:
1456 s = Stack()
1457 s._setfromtuple(a)
1458 self.BackTrace.append(s)
1459 return self.BackTrace
1460
1462 """
1463 Get the call tree of given address.
1464 @rtype: LIST of Call tuples
1465 @return: list of all the call tree
1466 ulong line; // Line number in column
1467 ulong dummy; // Must be 1
1468 ulong type; // Type, set of TY_xxx
1469 ulong entry; // Address of function
1470 ulong from; // Address of calling instruction
1471 ulong calls; // Address of called subfunction
1472 """
1473
1474 return debugger.get_call_tree(address)
1475
1476
1478 """
1479 Find which module an address belongs to.
1480
1481 @type address: DWORD
1482 @param address: Address
1483
1484 @rtype: LIST
1485 @return: Tuple of module information (name, base address)
1486
1487 """
1488 mod = debugger.find_module( address )
1489 if mod == -1:
1490 mod = ()
1491 return mod
1492
1494 """
1495 Find a module by name (case insensitive).
1496
1497 @type modname: STRING
1498 @param modname: Module Name
1499
1500 @rtype: OBJECT|BOOLEAN
1501 @return: a Module object matching the given name or False if it's not found or name is ambiguous
1502
1503 """
1504
1505 found=False
1506 for name,mod in self.getAllModules().iteritems():
1507 if modname.lower() in name.lower():
1508 if found != False:
1509 return False
1510 found=mod
1511
1512 return found
1513
1515 """
1516 Get a the process heaps
1517
1518 @rtype: LIST of DWORD
1519 @return: List of Heap Address
1520 """
1521 self.HeapsAddr = []
1522
1523 peb = self.getPEB()
1524 addr = peb.ProcessHeaps
1525 for ndx in range(0, peb.NumberOfHeaps):
1526 l = self.readLong( addr + ndx * 4 )
1527 if l:
1528 self.HeapsAddr.append( l )
1529
1530 return self.HeapsAddr
1531
1533 """
1534 Get the address from an expression as ntdll.RtlAllocateHeap
1535
1536 @type expression: STRING
1537 @param expression: Expression to translate into an address
1538
1539 @rtype: DWORD
1540 @return: Address of the Expression
1541 """
1542 return debugger.get_addr_from_exp(expression)
1543
1544
1546 """
1547 Get the address from an expression as ntdll.RtlAllocateHeap
1548
1549 @type expression: STRING
1550 @param expression: Expression to translate into an address
1551
1552 @rtype: DWORD
1553 @return: Address of the Expression
1554
1555 """
1556 return debugger.get_addr_from_exp(expression)
1557
1558
1559
1560
1562 """
1563 This function shows an Error dialog with a custom message.
1564
1565 @type msg: STRING
1566 @param msg: Message
1567 """
1568 return debugger.error( msg )
1569
1570 - def openTextFile(self,path=""):
1571 """
1572 Opens text file in MDI windows. ( if no path is specified browsefile dialog will pop up )
1573
1574 @type: STRING
1575 @param: (Optional, Def= "") Path to file
1576 """
1577 if (len(path) > 0):
1578 return debugger.open_text_file(path)
1579 else:
1580 return debugger.open_text_file()
1581
1583 """
1584 Sets the status bar message.
1585
1586 @type msg: STRING
1587 @param msg: Message
1588 """
1589 return debugger.info_line(msg)
1590
1592 """
1593 Removes the current status bar message.
1594 """
1595 return debugger.info_line()
1596
1597 - def logLines(self, data, address = 0, highlight = False, gray = False , focus = 0):
1598 """
1599 Adds multiple lines of ASCII text to the log window.
1600
1601 @type msg: LIST of STRING
1602 @param msg: List of Message to add (max size of msg is 255 bytes)
1603
1604 @type address: DWORD
1605 @param address: Address associated with the message
1606
1607 @type highlight: BOOLEAN
1608 @param highlight: Set highlight text
1609
1610 @type gray: BOOLEAN
1611 @param gray: Set gray text
1612 """
1613 return [ self.log(d, address, highlight, gray, focus) for d in data.split("\n") ]
1614
1615 - def log(self, msg, address = 0xbadf00d ,highlight = False, gray = False , focus = 0):
1616 """
1617 Adds a single line of ASCII text to the log window.
1618
1619 @type msg: STRING
1620 @param msg: Message (max size is 255 bytes)
1621
1622 @type address: DWORD
1623 @param address: Address associated with the message
1624
1625 @type highlight: BOOLEAN
1626 @param highlight: Set highlight text
1627
1628 @type gray: BOOLEAN
1629 @param gray: Set gray text
1630 """
1631 if gray and not highlight:
1632 highlight = -1
1633 return debugger.add_to_list( address, int(highlight), msg[:255],focus)
1634
1636 """
1637 Forces an immediate update of the log window.
1638 """
1639 debugger.update_list()
1640
1642 """
1643 Creates or restores the log window.
1644 """
1645 return debugger.create_list_window()
1646
1648 """
1649 Creates a custom window.
1650
1651 @type title: STRING
1652 @param title: Window title
1653
1654 @type col_titles: LIST OF STRING
1655 @param col_titles: Column titles list
1656
1657 @return HWND: Handler of created table
1658 """
1659 return self.createTable( title, col_titles )
1660
1662 """
1663 Creates a custom window.
1664
1665 @type title: STRING
1666 @param title: Window title
1667
1668 @type col_titles: LIST OF STRING
1669 @param col_titles: Column titles list
1670
1671 """
1672 return Table(self,title,col_titles)
1673
1675 """
1676 Set focus on window.
1677
1678 @type handler: ULONG
1679 @param handler: Windows Handler
1680
1681 @return phandler: Handle to the window that previously had the focus.
1682 """
1683 return debugger.set_focus(handler)
1684
1686 """
1687 Does a window still exist?
1688
1689 @type handler: ULONG
1690 @param handler: Windows to check handle
1691
1692 @return: INT : 1 Exists, 0 Doesnt exist
1693 """
1694 return debugger.is_valid_handle(handler)
1695
1697 """
1698 Sets and logs a status bar message.
1699
1700 @type addr: DWORD
1701 @param addr: Address related with the message
1702
1703 @type msg: STRING
1704 @param msg: Message
1705 """
1706 return debugger.message(addr, msg)
1707
1709 """
1710 Flashes a message at status bar.
1711
1712 @type msg: STRING
1713 @param msg: Message
1714 """
1715 return debugger.flash(msg)
1716
1718 """
1719 Displays a progress bar which can contain formatted text and a progress percentage.
1720 If the formatted text contains a dollar sign ('$') it will be replaced by the current progress percentage.
1721
1722 @type msg: STRING
1723 @param msg: Message
1724
1725 @type promille: DWORD
1726 @param promille: Progress. At 0 the progress bar is closed and the previous message restored.
1727 """
1728 return debugger.progress(promille, message)
1729
1731 """
1732 Close Progress Bar.
1733 """
1734 return debugger.progress(0, "")
1735
1765
1766
1767
1768
1769
1772
1775
1778
1781
1782
1794
1796 """
1797 Set a label.
1798
1799 @type adresss: DWORD
1800 @param address: Address to the new label
1801
1802 @type label: STRING
1803 @param label: Label to add
1804 """
1805 return debugger.set_label(address, label)
1806
1808 """
1809 Place a start mark for timming your script
1810 """
1811 self.timer=time.clock()
1812
1814 """
1815 Place an End mark for timming your script
1816
1817 @rtype time: DWORD
1818 @return time: time in seconds
1819 """
1820 if self.timer >0:
1821 return time.clock() - self.timer
1822 else:
1823 return 0
1824
1826 """
1827 Find exported function on the loaded dlls.
1828
1829 @type lookfor: TABLE of DWORD
1830 @param lookfor: Table of functions to search
1831
1832 @rtype: DICTIONARY
1833 @return: Dictionary
1834 """
1835
1836
1837
1838 symbol = self.getAllSymbols()
1839
1840 result = {}
1841 for modname in symbol.keys():
1842 modsym = symbol[modname]
1843 for modaddr in modsym.keys():
1844 mod = modsym[modaddr]
1845 if mod.name.lower() in lookfor:
1846 if mod.type == "Import":
1847 if result.has_key(modname):
1848 result[modname].append(mod)
1849 else:
1850 result[modname] = [mod]
1851 return result
1852
1853
1854
1856 """
1857 Check if debugger is running under a vmware machine
1858
1859 @rtype: DWORD
1860 @return: 1 if vmware machine exists
1861 """
1862 return debugger.check_vmware()
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1874 """
1875 Set a Manual Breakpoint.
1876
1877 @type address: DWORD
1878 @param address: Address of the breakpoint
1879
1880 @type key: DWORD
1881 @param key: VK_F2 (Conditional Breakpoint) or VK_F4 (Logging Breakpoint)
1882
1883 @type shiftkey: DWORD
1884 @param shiftkey: State of the shiftkey
1885
1886 @type font: STRING
1887 @param font: See ImmFonts
1888 """
1889 if not ImmFonts.has_key( font.lower() ):
1890 font = ImmFonts[ "fixed" ]
1891 else:
1892 font = ImmFonts[ font.lower() ]
1893
1894 return debugger.manual_breakpoint(address, key, int(shiftkey), font)
1895
1897 """
1898 Set an Unconditional Breakpoint.
1899
1900 @type address: DWORD
1901 @param address: Address for the breakpoint
1902
1903 @type font: STRING
1904 @param font: (Optional, Def: fixed) Font for the breakpoint
1905 """
1906 return self.manualBreakpoint(address, BpKeys["VK_F2"], False, font)
1907
1909 """
1910 Set a Conditional Breakpoint.
1911
1912 @type address: DWORD
1913 @param address: Address for the breakpoint
1914
1915 @type font: STRING
1916 @param font: (Optional, Def: fixed) Font for the breakpoint
1917 """
1918 return self.manualBreakpoint(address, BpKeys["VK_F2"], True, font)
1919
1921 """
1922 Set a Logging Breakpoint. (This breakpoint will not puase the execution, it will just act as a Watch point"
1923
1924 @type address: DWORD
1925 @param address: Address for the breakpoint
1926 """
1927 return debugger.set_logging_breakpoint(address)
1928
1930 """
1931 Set a watching Breakpoint.
1932
1933 @type address: DWORD
1934 @param address: Address for the watchpoint
1935 """
1936 return debugger.set_logging_breakpoint(address)
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1950 """
1951 Set a Temporary Breakpoint.
1952
1953 @type address: DWORD
1954 @param address: Address for the breakpoint
1955
1956 @type continue_execution: BOOLEAN
1957 @param continue_execution: Automatically removes temporary breakpoint when hit and continue execution
1958
1959 @type stoptrace: BOOLEAN
1960 @param stoptrace: Stop any kind of trace or animation when hit
1961 """
1962 if continue_execution:
1963 flags = BpFlags["TY_TEMP"] | BpFlags["TY_KEEPCOND"]
1964 else:
1965 flags = BpFlags["TY_ONESHOT"] | BpFlags["TY_KEEPCOND"]
1966 if stoptrace:
1967 flags |= BpFlags["TY_STOPAN"]
1968
1969 return debugger.temp_breakpoint(address, flags)
1970
1972 """
1973 Set a Breakpoint.
1974
1975 @type address: DWORD
1976 @param address: Address for the breakpoint
1977 """
1978 flags = BpFlags["TY_ACTIVE"]
1979 return debugger.set_breakpoint(address, flags, "")
1980
1982 """
1983 Set a Breakpoint.
1984
1985 @type Name: STRING
1986 @param Name: name of the function to bp
1987
1988 @rtype: DWORD
1989 @return: Address of name
1990 """
1991 return debugger.set_breakpoint_on_name(name)
1992
1994 """
1995 Disable Breakpoint.
1996
1997 @type address: DWORD
1998 @param address: Address for the breakpoint
1999 """
2000 flags = BpFlags["TY_DISABLED"]
2001 return debugger.set_breakpoint(address, flags, "")
2002
2004 """
2005 Delete Breakpoint.
2006
2007 @type address: DWORD
2008 @param address: Start range of addresses to delete breakpoints
2009 @type address2: DWORD
2010 @param Address: End range of addresses to delete breakpoints
2011 """
2012 return debugger.delete_breakpoints(address,address2)
2013
2014
2016 """
2017 Get the Breakpoint type.
2018
2019 @type address: DWORD
2020 @param address: Address for the breakpoint
2021
2022 @rtype: STRING
2023 @return: Breakpoint type
2024 """
2025
2026 type = debugger.get_breakpoint_type_count(address)
2027 for a in BpFlags.keys():
2028 if BpFlags[a] == type:
2029 return a
2030 return ""
2031
2033 """
2034 Modifies or removes a memory breakpoint.
2035
2036 @type address: DWORD
2037 @param address: Address for the breakpoint
2038
2039 @type type: DWORD
2040 @param type: Type of Memory Breakpoint (READ/WRITE/SFX)
2041
2042 @type size: DWORD
2043 @param size: (Optional, Def: 4) Size of Memory Breakpoint
2044 """
2045 ty = type.strip().split("|")
2046 flags = 0
2047 for a in ty:
2048 try:
2049 flags |= BpMemFlags[a]
2050 except KeyError:
2051 raise Exception("Bad Flags for setMembreakpoint: %s" % type)
2052
2053 return debugger.set_mem_breakpoint(flags, addr, size)
2054
2056 """
2057 Disable Memory Breakpoint.
2058 """
2059 return debugger.set_mem_breakpoint(0, addr,0)
2060
2061
2063 """
2064 Sets Hardware breakpoint
2065 """
2066 return debugger.set_hardware_breakpoint(type,addr,size)
2067
2068
2069
2070
2071
2073 """
2074 Write long to memory address.
2075
2076 @type address: DWORD
2077 @param address: Address
2078
2079 @type dword: DWORD
2080 @param dword: long to write
2081 """
2082 return debugger.write_memory( immutils.intel_order( dword ), address, 4, 0x2 )
2083
2085 """
2086 Write buffer to memory address.
2087
2088 @type address: DWORD
2089 @param address: Address
2090
2091 @type buf: BUFFER
2092 @param buf: Buffer
2093 """
2094 return debugger.write_memory(buf, address, len(buf), 0x2)
2095
2097 """
2098 Read block of memory.
2099
2100 @type address: DWORD
2101 @param address: Address
2102
2103 @type size: DWORD
2104 @param size: Size
2105
2106 @rtype: BUFFER
2107 @return: Process memory
2108 """
2109 return debugger.read_memory(address, size, 0x01|0x02)
2110
2112 """
2113 Read a Long from the debugged process
2114
2115 @type address: DWORD
2116 @param address: Address
2117
2118 @rtype: DWORD
2119 @return: Long
2120 """
2121 long = self.readMemory(address, 0x4)
2122 if len(long) == 4:
2123 try:
2124 return immutils.str2int32_swapped(long)
2125 except ValueError:
2126 raise Exception, "readLong failed to gather a long at 0x%08x" % address
2127 else:
2128 raise Exception, "readLong failed to gather a long at 0x%08x" % address
2129
2131 """
2132 Read a string from the remote process
2133
2134 @type address: DWORD
2135 @param address: Address of the string
2136
2137 @rtype: String
2138 @return: String
2139 """
2140 return self.readUntil(address, '\x00')
2141
2143 """
2144 Read a unicode string from the remote process
2145
2146 @type address: DWORD
2147 @param address: Address of the unicode string
2148
2149 @rtype: Unicode String
2150 @return: Unicode String
2151 """
2152 wstring = self.readUntil(address, "\x00\x00")
2153
2154 if not wstring.endswith("\x00"):
2155 wstring = wstring + "\x00"
2156
2157 return wstring
2158
2160 """
2161 Read string until ending starting at given address
2162
2163 @param Address: Start address
2164 @return Readed String
2165 """
2166 readed=[]
2167 while(1):
2168 read = self.readMemory( address, 16 )
2169 address += 16
2170 ndx = read.find(ending)
2171 if ndx != -1:
2172 readed.append( read[0:ndx] )
2173 break
2174 else:
2175 readed.append( read )
2176
2177 return string.joinfields(readed, "")
2178
2180 """
2181 Read a short integer from the remote process
2182
2183 @type address: DWORD
2184 @param address: Address of the short
2185
2186 @rtype: Short Integer
2187 @return: Short
2188 """
2189 short = self.readMemory(address, 0x2)
2190 return immutils.str2int16_swapped(short)
2191
2193 """
2194 Search a short integer on the remote process memory
2195
2196 @type short: SHORT
2197 @param short: Short integer to search for
2198
2199 @type flag: STRING
2200 @param flag: Memory Protection String Flag
2201
2202 @rtype: List
2203 @return: List of address of the short integer founded
2204 """
2205 return self.search(immutils.int2str16_swapped(short),flag)
2206
2208 """
2209 Search a short integer on the remote process memory
2210
2211 @type long: DWORD
2212 @param long: integer to search for
2213 @type flag: STRING
2214 @param flag: Memory Protection String Flag
2215
2216 @rtype: List
2217 @return: List of address of the integer founded
2218 """
2219 return self.search( immutils.int2str32_swapped(long),flag)
2220
2222 """
2223 Search string in executable memory.
2224
2225 @param buf: Buffer to search for
2226 @return: A list of address where the string was found on memory
2227 """
2228 if not buf:
2229 return []
2230 self.getMemoryPages()
2231 find = []
2232 buf_size = len(buf)
2233 for a in self.MemoryPages.keys():
2234 if (MemoryProtection["PAGE_EXECUTE"] == self.MemoryPages[a].access\
2235 or MemoryProtection["PAGE_EXECUTE_READ"] == self.MemoryPages[a].access\
2236 or MemoryProtection["PAGE_EXECUTE_READWRITE"] == self.MemoryPages[a].access\
2237 or MemoryProtection["PAGE_EXECUTE_WRITECOPY"] == self.MemoryPages[a].access):
2238 mem = self.MemoryPages[a].getMemory()
2239 if not mem:
2240 continue
2241 ndx = 0
2242 while 1:
2243 f = mem[ndx:].find( buf )
2244 if f == -1 : break
2245 find.append( ndx + f + a )
2246 ndx += f + buf_size
2247 return find
2248
2250 """
2251 Search string in writable memory.
2252
2253 @param buf: Buffer to search for
2254 @return: A list of address where the string was found on memory
2255 """
2256 if not buf:
2257 return []
2258 self.getMemoryPages()
2259 find = []
2260 buf_size = len(buf)
2261 for a in self.MemoryPages.keys():
2262 if (MemoryProtection["PAGE_READWRITE"] == self.MemoryPages[a].access\
2263 or MemoryProtection["PAGE_WRITECOPY"] == self.MemoryPages[a].access\
2264 or MemoryProtection["PAGE_EXECUTE_READWRITE"] == self.MemoryPages[a].access\
2265 or MemoryProtection["PAGE_EXECUTE_WRITECOPY"] == self.MemoryPages[a].access):
2266 mem = self.MemoryPages[a].getMemory()
2267 if not mem:
2268 continue
2269 ndx = 0
2270 while 1:
2271 f = mem[ndx:].find( buf )
2272 if f == -1 : break
2273 find.append( ndx + f + a )
2274 ndx += f + buf_size
2275 return find
2276
2278 """
2279 Search string in readable memory.
2280
2281 @param buf: Buffer to search for
2282 @return: A list of address where the string was found on memory
2283 """
2284 if not buf:
2285 return []
2286 self.getMemoryPages()
2287 find = []
2288 buf_size = len(buf)
2289 for a in self.MemoryPages.keys():
2290 if (MemoryProtection["PAGE_READONLY"] == self.MemoryPages[a].access\
2291 or MemoryProtection["PAGE_EXECUTE_READ"] == self.MemoryPages[a].access):
2292 mem = self.MemoryPages[a].getMemory()
2293 if not mem:
2294 continue
2295 ndx = 0
2296 while 1:
2297 f = mem[ndx:].find( buf )
2298 if f == -1 : break
2299 find.append( ndx + f + a )
2300 ndx += f + buf_size
2301 return find
2302
2303 - def search( self, buf, flag = None ):
2304 if not buf:
2305 return []
2306
2307 self.getMemoryPages()
2308 find = []
2309 buf_len = len(buf)
2310
2311 for a in self.MemoryPages.keys():
2312 if flag:
2313 if (MemoryProtection[flag] == self.MemoryPages[a].access):
2314 mem = self.MemoryPages[a].getMemory()
2315 if not mem:
2316 continue
2317
2318 mem_list = mem.split( buf )
2319 total_length = buf_len * -1
2320 recur_find = []
2321 for i in mem_list:
2322
2323 total_length = total_length + len(i) + buf_len
2324 recur_find.append( a + total_length )
2325
2326
2327
2328 del recur_find[ len(recur_find) - 1 ]
2329 find += recur_find
2330
2331 else:
2332 mem = self.MemoryPages[a].getMemory()
2333 if not mem:
2334 continue
2335 mem_list = mem.split( buf )
2336 total_length = buf_len * -1
2337 recur_find = []
2338 for i in mem_list:
2339
2340 total_length = total_length + len(i) + buf_len
2341 recur_find.append( a + total_length )
2342
2343
2344
2345 del recur_find[ len(recur_find) - 1 ]
2346 find += recur_find
2347
2348 return find
2349
2350
2352 """
2353 Search string in memory.
2354
2355 @param buf: Buffer to search for
2356 @param flag: Memory Protection String Flag
2357 @return: A list of address where the string was found on memory
2358
2359
2360 """
2361 if not buf:
2362 return []
2363
2364 self.getMemoryPages()
2365 find = []
2366 buf_size = len(buf)
2367 for a in self.MemoryPages.keys():
2368 if flag:
2369 if (MemoryProtection[flag] == self.MemoryPages[a].access):
2370 mem = self.MemoryPages[a].getMemory()
2371 if not mem:
2372 continue
2373 ndx = 0
2374 while 1:
2375 f = mem[ndx:].find( buf )
2376 if f == -1 : break
2377 find.append( ndx + f + a )
2378 ndx += f + buf_size
2379 else:
2380 mem = self.MemoryPages[a].getMemory()
2381 if not mem:
2382 continue
2383 ndx = 0
2384 while 1:
2385 f = mem[ndx:].find( buf )
2386 if f == -1 : break
2387 find.append( ndx + f + a )
2388 ndx += f + buf_size
2389 return find
2390
2392 """
2393 Search for a sequence of commands in all executable modules loaded.
2394 @type cmd: STRING
2395 @param cmd: Assembly code to search for (Search using regexp is available. See Documentation)
2396
2397 @rtype: List
2398 @return: List of address of the command found
2399
2400 NOTE: Since ImmunityDebugger 1.2 , the returning tuple[1] value is deprecated,
2401 if you need the opcode string of the resulted address, you'll have to do a immlib.disasm(tuple[0]).
2402
2403 """
2404 address=0
2405 return debugger.search_regexp(address,cmd)
2406
2408 """
2409 Search for a sequence of commands in given executable module.
2410 @type cmd: STRING
2411 @param cmd: Assembly code to search for (Search using regexp is available. See Documentation)
2412
2413 @rtype: List
2414 @return: List of address of the command found
2415
2416 NOTE: Since ImmunityDebugger 1.2 , the returning tuple[1] value is deprecated,
2417 if you need the opcode string of the resulted address, you'll have to do a immlib.disasm(tuple[0]).
2418
2419 """
2420 return debugger.search_regexp(address,cmd)
2421
2422
2423
2424
2425 - def run(self, address=0):
2426 """Run Process untill address.
2427 @param address: Address"""
2428 self.clearState()
2429 return debugger.run(address)
2430
2432 """Run Process till ret.
2433 """
2434 self.clearState()
2435 return debugger.run_until_ret()
2436
2437
2439 """Pause process"""
2440 return debugger.pause()
2441
2443 """
2444 Step-Over Process untill address.
2445
2446 @type address: DWORD
2447 @param address: (Optional, Def = 0) Address
2448 """
2449 self.clearState()
2450 return debugger.step_over(address)
2451
2452 - def stepIn(self, address=0):
2453 """
2454 Step-in Process untill address.
2455
2456 @type address: DWORD
2457 @param address: (Optional, Def = 0) Address
2458 """
2459 self.clearState()
2460 return debugger.step_in(address)
2461
2463 """
2464 Quits debugger
2465 """
2466 return debugger.exit_ID()
2467
2468
2470 """
2471 Ignore Single Step events
2472 @type flag: STRING
2473 @param flag: How to continue after a single event is catched
2474 flag = DISABLE : Disable ignoring
2475 flag = FORCE : Conventional Force continue method
2476 flag = CONTINUE : Transparent continue method
2477
2478 CAUTION: This method overrides GUI option 'single-step break'
2479 """
2480 return debugger.ignore_single_step(IgnoreSingleStep[flag])
2481
2482
2484 """
2485 Open process for debugging
2486 @type path: STRING
2487 @param path: Path to file to debug
2488 @type mode: INTEGER
2489 @param mode: How to start: -2 SILENT, 0 NORMAL
2490 """
2491 return debugger.open(path,mode)
2492
2494 """
2495 Restart debuggee
2496 @type mode: INTEGER
2497 @param mode: How to restart : -2 SILENT, -1 MSGBOX
2498
2499 """
2500 return debugger.open("",mode)
2501
2502
2504 """
2505 Attach to an active process
2506 @type pid: INTEGER
2507 @param pid: Process Id.
2508 """
2509 return debugger.attach(pid)
2510
2512 """
2513 Detach from active process
2514 """
2515
2516 return debugger.detach()
2517
2518
2520 """
2521 Prepare Debugger for fresh debugging session
2522 NOTE: be sure to know what you are doing when
2523 calling this method
2524 """
2525 return debugger.prepare_for_new_ps()
2526
2527
2528
2529
2531 """ Set/Unset silent debugging flag
2532 @type silent: INTEGER
2533 @param silent: 1 to set silent, 0 to unset
2534 """
2535 return debugger.go_silent(silent)
2536
2538 """
2539 Add a header to given row.
2540 @type address: DWORD
2541 @param address: Address to add the header into
2542 @type header: STRING
2543 @param header: Header string to add into row
2544 @type color: STRING
2545 @param color: Color of text
2546 """
2547 return debugger.add_header_to_row(address,header,ImmDrawColors[color])
2548
2550 """
2551 Removes header from row.
2552 @type address: DWORD
2553 @param address: Address to remove the header from
2554 """
2555 return debugger.remove_header_from_row(address)
2556
2558 """
2559 Removes header from row.
2560 @type address: DWORD
2561 @param address: Address to remove the header from
2562 """
2563 return debugger.remove_header_from_row(address)
2564
2566 """
2567 Get Header from row.
2568 @type address: DWORD
2569 @param address: Address to get the headers from
2570 @return PYLIST: List of strings
2571 """
2572 return debugger.get_header_from_row(address)
2573
2574 - def addLine(self,address,header,color="Black"):
2575 """
2576 Add a line to cpu window.
2577 @type address: DWORD
2578 @param address: Address to add line
2579 @type header: STRING
2580 @param header: Header string to add into row
2581 @type color: STRING
2582 @param color: Color of text
2583 """
2584 return debugger.add_header_to_row(address,header,ImmDrawColors[color])
2585
2587 """
2588 GoTo the Disassembler Window.
2589
2590 @type addr: DWORD
2591 @param addr: Address to show on the Disassembler Window
2592 """
2593 return debugger.set_cpu( self.threadid, addr, 0, 0, 0x8000L)
2594
2596 """
2597 GoTo Dump Window.
2598
2599 @type addr: DWORD
2600 @param addr: Address to show on the Dump Window
2601 """
2602 return debugger.set_cpu( self.threadid, 0, addr, 0, 0x8000L)
2603
2605 """
2606 GoTo the Stack Window.
2607 @type addr: DWORD
2608 @param addr: Address to show on the Stack Window
2609 """
2610 return debugger.set_cpu( self.threadid, 0, 0, addr, 0x8000L)
2611
2622
2624 """
2625 Creates Dialog with a combo_box.
2626
2627 @type title: STRING
2628 @param title: Title for the dialog
2629
2630 @type combolist: LIST
2631 @param combolist: List of items to add to combo dialog
2632
2633 @return: Selected item
2634 """
2635 return debugger.combo_box(title,combolist,len(combolist))
2636
2637
2638
2639
2641 """
2642 Get the status of the debugged process.
2643
2644 @return: Status of the debugged process
2645 """
2646 return debugger.get_status()
2647
2649 """
2650 Is the debugged process stopped?
2651
2652 @rtype: BOOL
2653 @return: Boolean (True/False)
2654 """
2655 return DebugerStatus["STOPPED"] == self.getStatus()
2656
2658 """
2659 Is the debugged process in an event state?
2660
2661 @rtype: BOOL
2662 @return: Boolean (True/False)
2663 """
2664 return DebugerStatus["EVENT"] == self.getStatus()
2665
2667 """
2668 Is the debugged process running?
2669
2670 @rtype: BOOL
2671 @return: Boolean (True/False)
2672 """
2673 return DebugerStatus["RUNNING"] == self.getStatus()
2674
2676 """
2677 Is the debugged process finished?
2678
2679 @rtype: BOOL
2680 @return: Boolean (True/False)
2681 """
2682 return DebugerStatus["FINISHED"] == self.getStatus()
2683
2685 """
2686 Is the debugged process closed?
2687
2688 @rtype: BOOL
2689 @return: Boolean (True/False)
2690 """
2691 return DebugerStatus["CLOSING"] == self.getStatus()
2692
2693
2694
2696 """
2697 List of active hooks
2698
2699 @rtype: LIST
2700 @return: List of active hooks
2701 """
2702 return debugger.list_hook()
2703
2705 """Unhook from memory
2706 """
2707 debugger.remove_hook(hook_str)
2708
2709 - def _getHookEntry(self, entry):
2710 tbl = []
2711
2712
2713 try:
2714 reg = HOOK_REG[ entry[0] ]
2715 tbl.append( "MOV EAX, %s" % reg )
2716 except KeyError:
2717 if entry[0] == 'ESP':
2718 tbl.append("LEA EAX, [ESP+0x14]")
2719 elif type( entry[0] ) == type(0):
2720 tbl.append("MOV EAX, [0x%08x]" % entry[0] )
2721 else:
2722 return []
2723
2724 if len(entry) == 2:
2725 tbl.append( "MOV EAX, [EAX + 0x%x]" % entry[1] )
2726 tbl.append( "STOSD" )
2727
2728 return tbl
2729
2730
2731
2732
2733 - def _createCodeforHook( self, memAddress, afterHookAddr, ndx, table, execute_prelude, alloc_size):
2734
2735
2736
2737 alloc_stub = [ "PUSHAD" ]
2738 alloc_stub += [ "MOV EBX, 0x%08x" % memAddress ]
2739 alloc_stub += [ "MOV EDI, [EBX]"]
2740 alloc_stub += [ "CMP DWORD DS:[EBX+4],1"]
2741
2742 alloc_stub += [ "MOV DWORD DS:[EBX+4],1"]
2743 alloc_stub += [ "MOV EAX, EDI"]
2744 alloc_stub += [ "SUB EAX, EBX"]
2745 alloc_stub += [ "ADD EAX, 0x%08x" % (len(table) * 4 + 4) ]
2746 alloc_stub += [ "CMP EAX, 0x%08x" % alloc_size]
2747
2748 alloc_stub_reg = [ "MOV EAX, 0x%x" % ndx]
2749 alloc_stub_reg += [ "STOSD"]
2750 for entry in table:
2751 alloc_stub_reg += self._getHookEntry( entry )
2752 alloc_stub_reg += [ "MOV [EBX], EDI"]
2753 alloc_stub_reg += [ "MOV DWORD DS:[EBX+4],0"]
2754
2755 alloc_stub_pos = [ "POPAD"]
2756
2757
2758 alloc_ret = "PUSH 0x%08x\nRET" % afterHookAddr
2759
2760
2761 code = self.assemble( "\n".join( alloc_stub ) )
2762 reg_code = self.assemble( "\n".join( alloc_stub_reg ) )
2763 code += "\x0f\x83" + struct.pack("L", len(reg_code) )
2764 code += reg_code
2765 code += self.assemble( "\n".join( alloc_stub_pos ) )
2766
2767 code += execute_prelude
2768 code += self.assemble( alloc_ret )
2769
2770 return code
2771
2772
2774 CODE_HOOK_START = 8
2775 flh = hook
2776
2777 table = flh.get()
2778
2779 memAddress = self.remoteVirtualAlloc( alloc_size )
2780 self.log( "Logging at 0x%08x" % memAddress )
2781
2782
2783
2784
2785
2786
2787
2788
2789 ptr = memAddress + CODE_HOOK_START
2790
2791 fn_restore = []
2792
2793 for fn_ndx in range( 0, len(table) ):
2794 hookAddress = table[ fn_ndx ][0]
2795 entry = table[ fn_ndx ][1]
2796
2797 idx = 0
2798
2799 patch_code = self.assemble( "JMP 0x%08x" % ptr, address = hookAddress)
2800
2801 while idx < len(patch_code):
2802 op = self.disasm( hookAddress + idx )
2803 if op.isCall() or op.isJmp():
2804 op = None
2805 break
2806
2807 idx += op.getOpSize()
2808 if not op:
2809 continue
2810
2811
2812 ex_prelude = self.readMemory( hookAddress, idx )
2813
2814 code = self._createCodeforHook( memAddress, hookAddress + idx,\
2815 fn_ndx + 1, entry, ex_prelude, alloc_size)
2816
2817 self.writeMemory( ptr , code )
2818 ptr+= len(code)
2819 self.writeMemory( hookAddress, patch_code )
2820
2821 fn_restore.append( ex_prelude )
2822
2823 if ptr % 4:
2824 ptr = 4 + ptr & ~(4-1)
2825 hook.setMem( ptr )
2826 self.writeLong( memAddress, ptr )
2827
2828 hook.setRestore( fn_restore )
2829
2830
2831
2832
2833
2834 - def rVirtualAlloc(self, lpAddress, dwSize, flAllocationType, flProtect):
2835 """
2836 Virtual Allocation on the Debugged Process
2837
2838 @type lpAddress: DWORD
2839 @param lpAddress: Desired starting Address
2840
2841 @type dwSize: DWORD
2842 @param dwSize: Size of the memory to be allocated (in bytes)
2843
2844 @type flAllocationType: DWORD
2845 @param flAllocationType: Type of Memory Allocation (MEM_COMMIT, MEM_RESERVED, MEM_RESET, etc)
2846
2847 @type flProtect: DWORD
2848 @param flProtect: Flag protection of the memory allocated
2849
2850 @rtype: DWORD
2851 @return: Address of the memory allocated
2852 """
2853 return debugger.pVirtualAllocEx( lpAddress, dwSize, flAllocationType, flProtect )
2854
2855
2856 - def rVirtualFree(self, lpAddress, dwSize = 0x0, dwFreeType = 0x8000):
2857 """
2858 Virtual Free of memory on the Debugged Process
2859
2860 @type size: DWORD
2861 @param size: (Optional, Def: 0) Size of the memory to free
2862
2863 @type dwFreeType: DWORD
2864 @param dwFreeType: (Optional, Def: MEM_RELEASE) Type of Free operation
2865
2866 @rtype: DWORD
2867 @return: On Successful, returns a non zero value
2868 """
2869 return debugger.pVirtualFreeEx( lpAddress, dwSize, dwFreeType )
2870
2872 """
2873 Virtual Allocation on the Debugged Process
2874
2875 @type size: DWORD
2876 @param size: (Optional, Def: 0x10000) Size of the memory to allocated, in bytes
2877
2878 @rtype: DWORD
2879 @return: Address of the memory allocated
2880 """
2881
2882 return self.rVirtualAlloc( 0x0, size, 0x1000, 0x40)
2883
2884
2886 return self.osversion
2887
2889 return self.osrelease
2890
2900
2902 """
2903 Return current debuggee thread id
2904
2905 @trype: LONG
2906 @return: Thread ID
2907 """
2908 return debugger.get_thread_id()
2909
2910
2911
2912
2914 """
2915 Look up into our dictionaries to find a function match.
2916
2917 @type name: STRING
2918 @param name: Name of the function to search
2919
2920 @type module: STRING
2921 @param module: name of a module to restrict the search
2922
2923 @type version: STRING
2924 @param version: restrict the search to the given version
2925
2926 @type heuristic: INTEGER
2927 @param heuristic: heuristic threasold to consider a real function match
2928
2929 @type data: STRING|LIST
2930 @param data: Name (or list of names) of the .dat file inside the Data folder, where're stored the function
2931 patterns. Use an empty string to use all the files in the Data folder.
2932
2933 @rtype: DWORD|None
2934 @return: the address of the function or None if we can't find it
2935 """
2936 recon = FunctionRecognition(self, data)
2937 return recon.searchFunctionByName(name, heuristic , module, version )
2938
2940 """
2941 Search memory to find a function that fullfit the options.
2942
2943 @type csvline: STRING
2944 @param csvline: A line of a Data CSV file. This's a simple support for copy 'n paste from a CSV file.
2945
2946 @type heuristic: INTEGER
2947 @param heuristic: heuristic threasold to consider a real function match
2948
2949 @type module: STRING
2950 @param module: name of a module to restrict the search
2951
2952 @type data: STRING|LIST
2953 @param data: Name (or list of names) of the .dat file inside the Data folder, where're stored the function
2954 patterns. Use an empty string to use all the files in the Data folder.
2955
2956 @rtype: DWORD|None
2957 @return: the address of the function or None if we can't find it
2958 """
2959
2960 recon = FunctionRecognition(self, data)
2961 return recon.searchFunctionByHeuristic(csvline, heuristic , module )
2962
2964 """
2965 Look up into our dictionaries to find a function match.
2966
2967 @type address: DWORD
2968 @param address: Address of the function to search
2969
2970 @type heuristic: INTEGER
2971 @param heuristic: heuristic threasold to consider a real function match
2972
2973 @type data: STRING|LIST
2974 @param data: Name (or list of names) of the .dat file inside the Data folder, where're stored the function
2975 patterns. Use an empty string to use all the files in the Data folder.
2976
2977 @rtype: STRING
2978 @return: a STRING with the function's real name or the given address if there's no match
2979 """
2980 recon = FunctionRecognition(self,data)
2981 return recon.resolvFunctionByAddress(address, heuristic,data)
2982
2984 """
2985 @type address: DWORD
2986 @param address: address of the function to hash
2987
2988 @type compressed: Boolean
2989 @param compressed: return a compressed base64 representation or the raw data
2990
2991 @type followCalls: Boolean
2992 @param followCalls: follow the first call in a single basic block function
2993
2994 @type data: STRING|LIST
2995 @param data: Name (or list of names) of the .dat file inside the Data folder, where're stored the function
2996 patterns. Use an empty string to use all the files in the Data folder.
2997
2998 @rtype: LIST
2999 @return: the first element is described below and the second is the result of this same function but over the first
3000 call of a single basic block function (if applies), each element is like this:
3001 a base64 representation of the compressed version of each bb hash:
3002 [4 bytes BB(i) start][4 bytes BB(i) 1st edge][4 bytes BB(i) 2nd edge]
3003 0 <= i < BB count
3004 or the same but like a LIST with raw data.
3005 """
3006 recon = FunctionRecognition(self, data)
3007 return FunctionRecognition.makeFunctionHashHeuristic(address, compressed, followCalls)
3008
3010 """
3011 Return a SHA-1 hash of the function, taking the raw bytes as data.
3012
3013 @type address: DWORD
3014 @param address: address of the function to hash
3015
3016 @type data: STRING|LIST
3017 @param data: Name (or list of names) of the .dat file inside the Data folder, where're stored the function
3018 patterns. Use an empty string to use all the files in the Data folder.
3019
3020 @rtype: STRING
3021 @return: SHA-1 hash of the function
3022 """
3023
3024 recon = FunctionRecognition(self,data)
3025 return recon.makeFunctionHashExact(address)
3026
3028 """
3029 Return a list with the best BB to use for a search and the heuristic hash
3030 of the function. This two components are the function hash.
3031
3032 @type address: DWORD
3033 @param address: address of the function to hash
3034
3035 @type compressed: Boolean
3036 @param compressed: return a compressed base64 representation or the raw data
3037
3038 @type data: STRING|LIST
3039 @param data: Name (or list of names) of the .dat file inside the Data folder, where're stored the function
3040 patterns. Use an empty string to use all the files in the Data folder.
3041
3042 @rtype: LIST
3043 @return: 1st element is the generalized instructions to use with searchCommand
3044 2nd element is the heuristic function hash (makeFunctionHashHeuristic)
3045 3rd element is an exact hash of the function (makeFunctionHashExact)
3046 """
3047 recon = FunctionRecognition(self,data)
3048 return recon.makeFunctionHash(address, compressed)
3049
3050
3051
3052
3054 """
3055 This function finds Natural Loops inside a function.
3056
3057 Each loop item has the following structure:
3058 [ start, end, nodes ]
3059 start: address of node receiving the back edge.
3060 end: address of node which has the back edge.
3061 node: list of node's addresses involved in this loop.
3062
3063 @type address: DWORD
3064 @param address: function start address
3065
3066 @rtype: LIST
3067 @return: A list of loops
3068 """
3069
3070 cfa = ControlFlowAnalysis(self, address)
3071 return cfa.findNaturalLoops()
3072
3074 """
3075 timeout is in seconds. this function will sleep 1 second at a time until timeout is reached
3076 or the debugger has stopped (probably due to AV)
3077 returns True if we were stopped before timeout happened
3078 """
3079 for i in xrange(timeout):
3080
3081 if self.isStopped():
3082 return True
3083 if self.isEvent():
3084 return True
3085
3086 time.sleep(1)
3087 return False
3088
3090 """
3091 This function loads a DLL into the debugged process.
3092
3093 @type dll_path: STRING
3094 @param dll_path: The full path to the DLL. ie C:\\WINDOWS\\system32\\kernel32.dll
3095
3096 @rtype: DWORD
3097 @return: The thread ID of the DLL loading thread.
3098 """
3099
3100 return debugger.inject_dll( dll_path )
3101
3103
3105 raise Exception(' '.join(['Only instantiate subclasses of this ',
3106 'class that define an __init__ function',
3107 'that hooks an output stream']))
3109 for line in out.split('\n'):
3110 if len(line) == 0:
3111 continue
3112
3113 self.imm.log(line)
3114 self.orig.write(line)
3115
3118
3120
3122 sys.stderr = self
3123 self.orig = sys.__stderr__
3124
3125 self.imm = Debugger()
3126
3128
3130 sys.stdout = self
3131 self.orig = sys.__stdout__
3132
3133 self.imm = Debugger()
3134