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