-
Notifications
You must be signed in to change notification settings - Fork 32
/
heaper.py
executable file
·4251 lines (3917 loc) · 266 KB
/
heaper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
'''
Created on Apr 24, 2012
@author: mr_me
@contact: [email protected]
@version: 0.02
'''
__VERSION__ = '0.02'
__IMM__ = '1.8'
DESC="""heaper - an advanced heap analysis plugin for Immunity Debugger."""
import immlib
from immlib import LogBpHook, FastLogHook
import immutils
import libdatatype
try:
import pydot
except:
pydot = False
import struct
import re
from hashlib import sha1
import urllib2
import inspect
from immlib import AccessViolationHook
import os
###########
# Globals #
###########
# for hooking function pointers
# =============================
INDEXER = 0xb4000000
INDEX_MASK = 0xFF000000
FNDX_MASK = 0x00FFFFFF
# window management
# =================
opennewwindow = False
windowtag = "display_box"
# The Heaper class
class Heaper:
"""
The main heaper class that handles generic heap analysis
"""
def __init__(self, imm, window):
self.imm = imm
self.window = window
self.opennewwindow = False
self.os = ""
self.heap = ""
self.pheap = ""
self.config_settings = []
self.block = 0x8
self.ptr_dict = {}
# all available commands '!heaper <command>'
self.available_commands = ["dumppeb", "dp", "dumpheaps", "dh", "analyseheap", "ah",
"dumpteb", "dt", "analysefrontend", "af", "analysebackend", "ab", "analysechunks", "ac",
"dumpfunctionpointers", "dfp", "help", "-h", "analysesegments", "as", "-f", "-m", "-p",
"freelistinuse", "fliu", "analyseheapcache", "ahc", "exploit", "exp", "u",
"update", "patch", "p", "config", "cnf", "hardhook", "hh", "softhook", "sh", "findwptrs",
"findwritablepointers"]
def run(self):
self.os = int(self.imm.getOsRelease().split('.')[0])
self.peb = self.imm.getPEBAddress()
self.peb_struct = self.imm.getPEB()
self.config_settings.append("workingdir")
self.set_config()
# operational methods
# ===================
def banner(self):
self.window.Log("----------------------------------------")
self.window.Log(" __ ")
self.window.Log(" / / ___ ___ ____ ___ ____ ")
self.window.Log(" / _ \/ -_) _ `/ _ \/ -_) __/ ")
self.window.Log(" /_//_/\__/\_,_/ .__/\__/_/ ")
self.window.Log(" /_/ ")
self.window.Log("----------------------------------------")
self.window.Log("by mr_me :: [email protected]")
def usage(self):
self.window.Log("")
self.window.Log("**** available commands ****")
self.window.Log("")
self.window.Log("dumppeb / dp : Dump the PEB pointers")
self.window.Log("dumpteb / dt : Dump the TEB pointers")
self.window.Log("dumpheaps / dh : Dump the heaps")
self.window.Log("dumpfunctionpointers / dfp : Dump all the processes function pointers")
self.window.Log("findwritablepointers / findwptrs : Dump all the called, writable function pointers")
self.window.Log("analyzeheap <heap> / ah <heap> : Analyze a particular heap")
self.window.Log("analyzefrontend <heap> / af <heap> : Analyze a particular heap's frontend data structure")
self.window.Log("analyzebackend <heap> / ab <heap> : Analyze a particular heap's backend data structure")
self.window.Log("analyzesegments <heap> / as <heap> : Analyze a particular heap's segments")
self.window.Log("analyzechunks <heap> / ac <heap> : Analyze a particular heap's chunks")
self.window.Log("analyzeheapcache <heap> / ahc <heap> : Analyze a particular heap's cache (FreeList[0])")
self.window.Log("freelistinuse <heap> / fliu <heap> : Analyze/patch the FreeListInUse structure")
self.window.Log("hardhook <heap> / hh <heap> -f <func> : Hook various functions that manipulate a heap by injecting assembly")
self.window.Log("softhook <heap> / sh <heap> -f <func> : Hook various functions that manipulate a heap by using software breakpoints ")
self.window.Log("patch <function/data structure> / p : Patch a function or datastructure")
self.window.Log("update / u : Update to the latest version")
self.window.Log("config <options> / cnf <options> : Display or set the current context configurations")
self.window.Log("exploit [<heap>/all] / exp [<heap>/all] : Perform heuristics against the FrontEnd and BackEnd allocators")
self.window.Log(" to determine exploitable conditions")
self.window.Log("")
self.window.Log("Want more info about a given command? Run !heaper help <command>")
self.window.Log("Detected the operating system to be windows %s, keep this in mind." % (self.imm.getOsVersion()))
self.window.Log("")
return "Example: !heaper analyzefrontend 00480000 -l"
def get_config(self):
config_settings = []
for knowledge in self.imm.listKnowledge():
if re.match("config", knowledge):
config_settings.append(knowledge)
return config_settings
# runtime detection of avaliable functions
def get_extended_usage(self):
extusage = {}
extusage["freelistinuse"] = "\nfreelistinuse <heap> / fliu <heap> : analyse/patch the FreeListInUse structure\n"
extusage["freelistinuse"] += "---------------------------------------------\n"
extusage["freelistinuse"] += "Use -p <byte entry> to patch the FreeListInUse entry and set its bit\n"
extusage["freelistinuse"] += "eg !heaper fliu 0x00a80000 -p 0x7c\n"
extusage["dumppeb"] = "\ndumppeb / dp : Return the PEB entry address\n"
extusage["dumppeb"] += "---------------------------------------------\n"
extusage["dumppeb"] += "Use -m to view the PEB management structure\n"
extusage["softhook"] = "\nsofthook <heap> / sh : Hook various functions that create/destroy/manipulate a heap\n"
extusage["softhook"] += "------------------------------------------------------------------------------\n"
extusage["softhook"] += "Use -f to hook available function(s).\n"
extusage["softhook"] += "Use -u to unhook previously hooked function(s).\n"
extusage["softhook"] += "Available functions to hook are: \n"
extusage["softhook"] += "- RtlAllocateHeap() [alloc]\n"
extusage["softhook"] += "- RtlFreeHeap() [free]\n"
extusage["softhook"] += "- Hook all functions! [all]\n"
extusage["softhook"] += "Examples:\n"
extusage["softhook"] += "~~~~~~~~~\n"
extusage["softhook"] += "Hard hook RtlAllocateHeap() on heap 0x00150000 '!heaper softhook 0x00150000 -h alloc'\n"
extusage["softhook"] += "Unhook all heap functions '!heaper softhook 0x00150000 -u all'\n"
extusage["softhook"] += "Hard hook RtlFreeHeap() '!heaper sh 0x00150000 -f free'\n"
extusage["hardhook"] = "\nhardhook <heap> / hh : Hook various functions that create/destroy/manipulate a heap\n"
extusage["hardhook"] += "------------------------------------------------------------------------------\n"
extusage["hardhook"] += "Use -h to hook RtlAllocateHeap and RtlFreeHeap.\n"
extusage["hardhook"] += "Use -u to unhook previously hooked functions.\n"
extusage["hardhook"] += "Use -s to show the hooked results.\n"
extusage["hardhook"] += "Available options to use: \n"
extusage["hardhook"] += "-a : filter by chunk address\n"
extusage["hardhook"] += "-h : enable the hook on\n"
extusage["hardhook"] += "-d : disable the hooks\n"
extusage["hardhook"] += "-c : clear the hooks\n"
extusage["hardhook"] += "-p : pause hook execution\n"
extusage["hardhook"] += "-d : to scan for double frees (requires -s)\n"
extusage["hardhook"] += "-C : Continue hook execution\n"
extusage["hardhook"] += "Examples:\n"
extusage["hardhook"] += "~~~~~~~~~\n"
extusage["hardhook"] += "'!heaper hardhook 0x00150000 -h'\n"
extusage["hardhook"] += "'!heaper hardhook 0x00150000 -u'\n"
extusage["hardhook"] += "'!heaper hh 0x00150000 -h -a 0x1503e848'\n"
extusage["dumpteb"] = "\ndumpteb / dt : List all of the TEB entry addresses\n"
extusage["dumpteb"] += "--------------------------------------------------------\n"
extusage["dumpheaps"] = "\ndumpheaps / dh : Dump all the heaps for a given process\n"
extusage["dumpheaps"] += "-------------------------------------------------------\n"
extusage["analyseheap"] = "\nanalyseheap <heap> / ah <heap> : Analyse a particular heap\n"
extusage["analyseheap"] += "----------------------------------------------------------\n"
extusage["analysesegments"] = "\nanalysesegments <heap> / as <heap> : Analyse a particular heap's segment stucture(s)\n"
extusage["analysesegments"] += "------------------------------------------------------------------------------------\n"
extusage["analysesegments"] += "Use -g to view a graphical representation of the heap structure\n"
extusage["analysefrontend"] = "\nanalysefrontend <heap> / af <heap> : Analyse a particular heap's frontend free structure\n"
extusage["analysefrontend"] += "----------------------------------------------------------------------------------------\n"
if self.os >= 6.0:
extusage["analysefrontend"] += "Use -u to dump the UserBlocks that are activated in the LFH\n"
extusage["analysefrontend"] += "Use -s to specify a sized bin to dump\n"
extusage["analysefrontend"] += "Use -c to dump the UserBlockCache structure\n"
extusage["analysefrontend"] += "Use -b to dump the buckets in the LFH\n"
extusage["analysefrontend"] += "Use -g to view a graphical representation of the UserBlocks in the LFH\n"
extusage["analysefrontend"] += "Use -o to specify a filename for the graph\n"
extusage["analysefrontend"] += "Examples:\n"
extusage["analysefrontend"] += "~~~~~~~~~\n"
extusage["analysefrontend"] += "Dump the UserBlocks '!heaper af 0x00260000 -u'\n"
extusage["analysefrontend"] += "Dump the UserBlocks for size 0x40 '!heaper af 0x00260000 -u -s 0x40'\n"
extusage["analysefrontend"] += "Dump the UserBlockCache '!heaper af 0x00260000 -c'\n"
extusage["analysefrontend"] += "Dump the buckets '!heaper af 0x00260000 -b'\n"
extusage["analysefrontend"] += "Dump the UserBlocks and graph it '!heaper af 0x00260000 -u -g -o UserBlocks-example'\n"
elif self.os < 6.0:
extusage["analysefrontend"] += "Use -l to dump the Lookaside Lists\n"
extusage["analysefrontend"] += "Use -v to verbosely dump the Lookaside Lists\n"
extusage["analysefrontend"] += "Use -g to view a graphical representation of the Lookaside Lists\n"
extusage["analysefrontend"] += "Use -o to specify a filename for the graph\n"
extusage["analysefrontend"] += "Examples:\n"
extusage["analysefrontend"] += "~~~~~~~~~\n"
extusage["analysefrontend"] += "Dump the Lookaside Lists '!heaper af 0x00260000 -l'\n"
extusage["analysefrontend"] += "Dump the Lookaside Lists and graph it '!heaper af 0x00260000 -l -g -o lookaside'\n"
extusage["analysebackend"] = "\nanalysebackend <heap> / ab <heap> : Analyse a particular heap's backend free structure\n"
extusage["analysebackend"] += "------------------------------------------------------------------------------------\n"
if self.os >= 6.0:
extusage["analysebackend"] += "Use -l to view the ListHints\n"
extusage["analysebackend"] += "Use -f to view the FreeList chunks\n"
extusage["analysebackend"] += "Use -g to view a graphical representation of the ListHint/FreeList\n"
extusage["analysebackend"] += "Use -o to specify a filename for the graph\n"
extusage["analysebackend"] += "Examples:\n"
extusage["analysebackend"] += "~~~~~~~~~\n"
extusage["analysebackend"] += "Analyse the ListHints '!heaper ab 00150000 -l'\n"
# verbose mode only supported in windows NT v5.x for now
elif self.os < 6.0:
extusage["analysebackend"] += "Use -h to dump the HeapCache (if its activated)\n"
extusage["analysebackend"] += "Use -f to dump the FreeList chunks\n"
extusage["analysebackend"] += "Use -v to verbosely dump the FreeList chunks\n"
extusage["analysebackend"] += "Use -g to view a graphical representation of the FreeLists\n"
extusage["analysebackend"] += "Use -o to specify a filename for the graph\n"
extusage["analysebackend"] += "Examples:\n"
extusage["analysebackend"] += "~~~~~~~~~\n"
extusage["analysebackend"] += "Analyse the FreeList '!heaper ab 00150000 -f'\n"
extusage["analysebackend"] += "Analyse the FreeList verbosly '!heaper ab 00150000 -f -v'\n"
extusage["analysebackend"] += "Analyse and graph the FreeList '!heaper ab 00150000 -f -g'\n"
extusage["analysebackend"] += "Analyse and graph the FreeList verbosly setting a filename '!heaper ab 00150000 -f -g -v -o ie8_freelist'\n"
extusage["analysesegments"] = "\nanalysesegment(s) <heap> / as <heap> : Analyse a particular heap's segment structure(s)\n"
extusage["analysesegments"] += "------------------------------------------------------------------------------------\n"
extusage["patch"] = "\npatch <function/data structures> / p <function/data structures> : patch memory for the heap\n"
extusage["patch"] += "-------------------------------------------------------------------------------------------\n"
extusage["patch"] += "Use 'PEB' to patch the following areas:\n"
extusage["patch"] += " - PEB.IsDebugged\n"
extusage["patch"] += " - PEB.ProcessHeap.Flag\n"
extusage["patch"] += " - PEB.NtGlobalFlag\n"
extusage["patch"] += " - PEB.LDR_DATA\n"
extusage["patch"] += "Example: '!heaper patch PEB'\n"
extusage["analyseheapcache"] = "\nanalyseheapcache <heap> / ahc <heap> : Analyse a particular heap's cache (FreeList[0])\n"
extusage["analyseheapcache"] += "------------------------------------------------------------------------------------\n"
extusage["analysechunks"] = "\nanalysechunks <heap> / ac <heap> : Analyse a particular heap's chunks\n"
extusage["analysechunks"] += "---------------------------------------------------------------------\n"
extusage["analysechunks"] += "Use -f to chunk_filter chunks by type (free/busy) eg: !heaper ac d20000 -f busy\n"
extusage["analysechunks"] += "Use -v to view the first 16 bytes of each chunk\n"
extusage["dumpfunctionpointers"] = "\ndumpfunctionpointers / dfp : Dump all the function pointers of the current process\n"
extusage["dumpfunctionpointers"] += "-----------------------------------------------------------------------------------\n"
extusage["dumpfunctionpointers"] += "Use -a <address> to specify where to start looking for function pointers\n"
extusage["dumpfunctionpointers"] += "Use -s <size> to specify the amount of data to search from the address\n"
extusage["dumpfunctionpointers"] += "Use -p <address/all> to patch a function pointer or all function pointers\n"
extusage["dumpfunctionpointers"] += "Use -r <address/all> to restore a function pointer or all function pointers\n"
extusage["dumpfunctionpointers"] += "Use -e <address,address,address> comma seperated list of addresses to exclude from patching/restoring\n"
extusage["dumpfunctionpointers"] += "Examples:\n"
extusage["dumpfunctionpointers"] += "~~~~~~~~~\n"
extusage["dumpfunctionpointers"] += "locate pointers - '!heaper dfp -s 3000 -a 0x00c55000'\n"
extusage["dumpfunctionpointers"] += "patch pointer - '!heaper dfp -p 0x00c56120'\n"
extusage["dumpfunctionpointers"] += "patch all pointers - '!heaper dfp -s 2000 -a 6ed86000 -p all -e 6ed86290,6ed86294'\n"
extusage["dumpfunctionpointers"] += "restore pointer - '!heaper dfp -r 0x00c56120'\n"
extusage["dumpfunctionpointers"] += "restore all pointers - '!heaper dfp -s 3000 -a 0x00c55000 -r all'\n"
extusage["config"] = "\nconfig / cnf : Display the current configuration settings or set them accordingly\n"
extusage["config"] += "---------------------------------------------------------------------------------\n"
extusage["config"] += "Use -d to display the current settings\n"
extusage["config"] += "Use -s to set any setting\n"
extusage["config"] += "Examples:\n"
extusage["config"] += "~~~~~~~~~\n"
extusage["config"] += "Display the settings '!heaper cnf -d'\n"
extusage["config"] += "Set the workingdir option '!heaper cnf -s workingdir c:\output'\n"
extusage["exploit"] = "\nexploit [<heap>/all] / exp [<heap>/all]: Perform heuristics against the FrontEnd and BackEnd allocators to determine exploitable conditions\n"
extusage["exploit"] += "-------------------------------------------------------------------------------------------------------------------------------------------\n"
extusage["exploit"] += "Use -f to analyse the FrontEnd allocator\n"
extusage["exploit"] += "Use -b to analyse the BackEnd allocator\n"
extusage["exploit"] += "Examples:\n"
extusage["exploit"] += "~~~~~~~~~\n"
extusage["exploit"] += "Validate all heaps for overwritten chunks in the frontend - '!heaper exploit all -f'\n"
extusage["exploit"] += "Validate the 0x00490000 heap's backend for overwritten chunks - '!heaper exploit 0x00490000 -b'\n"
extusage["findwritablepointers"] = "\nfindwritablepointers / findwptrs : finds and w+ function pointers for application data attacks\n"
extusage["findwritablepointers"] += "----------------------------------------------------------------------------------------------\n"
extusage["findwritablepointers"] += "Use -m to filter by module (use 'all' for all modules in the address space)\n"
extusage["findwritablepointers"] += "Use -p to patch all the found function pointers\n"
extusage["findwritablepointers"] += "Use -r to restore all the found function pointers\n"
extusage["findwritablepointers"] += "\n"
extusage["findwritablepointers"] += "!! Warning: using the 'all' option will take a long time. Go get a 0xc00ffee !!\n"
extusage["findwritablepointers"] += "\n"
extusage["findwritablepointers"] += "Examples:\n"
extusage["findwritablepointers"] += "~~~~~~~~~\n"
extusage["findwritablepointers"] += "find calls/jmps from ntdll.dll and save there pointers - '!heaper findwptrs -m ntdll.dll'\n"
extusage["findwritablepointers"] += "patch the saved pointers from ntdll.dll - '!heaper findwptrs -m ntdll.dll -p'\n"
extusage["findwritablepointers"] += "restore the saved pointers from ntdll.dll - '!heaper findwptrs -m ntdll.dll -r'\n"
extusage["findwritablepointers"] += "find calls/jmps in all modules - '!heaper findwptrs -m all'\n"
return extusage
# taken from mona.py, thanks peter
def get_modules_iat(self, module):
themod = module
syms = themod.getSymbols()
IAT = []
for sym in syms:
if syms[sym].getType().startswith("Import"):
theaddress = syms[sym].getAddress()
if not theaddress in IAT:
IAT.append(theaddress)
return IAT
def set_usage(self):
self.cmds = {}
self.cmds["dumppeb"] = Setcommand("dumppeb", "Dump the PEB pointers",self.get_extended_usage()["dumppeb"], "dp")
self.cmds["dp"] = Setcommand("dumppeb", "Dump the PEB pointers",self.get_extended_usage()["dumppeb"], "dp")
self.cmds["dumpteb"] = Setcommand("dumpteb", "Dump the TEB pointers",self.get_extended_usage()["dumpteb"], "dt")
self.cmds["dt"] = Setcommand("dumpteb", "Dump the TEB pointers",self.get_extended_usage()["dumpteb"], "dt")
self.cmds["dumpheaps"] = Setcommand("dumpheaps", "Dump all the heaps of a process",self.get_extended_usage()["dumpheaps"], "dh")
self.cmds["dh"] = Setcommand("dumpheaps", "Dump all the heaps of a process",self.get_extended_usage()["dumpheaps"], "dh")
self.cmds["dumpfunctionpointers"] = Setcommand("dumpfunctionpointers", "Dump all the function pointers of the current process",self.get_extended_usage()["dumpfunctionpointers"], "dfp")
self.cmds["dfp"] = Setcommand("dumpfunctionpointers", "Dump all the function pointers of the current process",self.get_extended_usage()["dumpfunctionpointers"], "dfp")
self.cmds["analyseheap"] = Setcommand("analyseheap", "analyse a particular heap",self.get_extended_usage()["analyseheap"], "ah")
self.cmds["ah"] = Setcommand("analyseheap", "analyse a particular heap",self.get_extended_usage()["analyseheap"], "ah")
self.cmds["analysefrontend"] = Setcommand("analysefrontend", "analyse a particular heap's frontend",self.get_extended_usage()["analysefrontend"], "af")
self.cmds["af"] = Setcommand("analyselal", "analyse a particular heap's lookaside list",self.get_extended_usage()["analysefrontend"], "af")
self.cmds["analysebackend"] = Setcommand("analysebackend", "analyse a particular heap's backend",self.get_extended_usage()["analysebackend"], "ab")
self.cmds["ab"] = Setcommand("analysefreelist", "analyse a particular heap's freelist",self.get_extended_usage()["analysebackend"], "ab")
self.cmds["analysechunks"] = Setcommand("analysechunks", "analyse a particular heap's list of chunks",self.get_extended_usage()["analysechunks"], "ac")
self.cmds["ac"] = Setcommand("analysechunks", "analyse a particular heap's list of chunks",self.get_extended_usage()["analysechunks"], "ac")
self.cmds["analysesegments"] = Setcommand("analysesegments", "analyse a particular heap's segment(s)",self.get_extended_usage()["analysesegments"], "as")
self.cmds["as"] = Setcommand("analysesegments", "analyse a particular heap's segment(s)",self.get_extended_usage()["analysesegments"], "as")
self.cmds["analyseheapcache"] = Setcommand("analyseheapcache", "analyse a particular heap's cache (FreeList[0])",self.get_extended_usage()["analyseheapcache"], "ahc")
self.cmds["ahc"] = Setcommand("analyseheapcache", "analyse a particular heap's cache (FreeList[0])",self.get_extended_usage()["analyseheapcache"], "ahc")
self.cmds["freelistinuse"] = Setcommand("freelistinuse", "analyse/patch the FreeListInUse structure",self.get_extended_usage()["freelistinuse"], "fliu")
self.cmds["fliu"] = Setcommand("freelistinuse", "analyse/patch the FreeListInUse structure",self.get_extended_usage()["freelistinuse"], "fliu")
self.cmds["hardhook"] = Setcommand("hook", "Hard hook various functions that manipulate a heap",self.get_extended_usage()["hardhook"], "hh")
self.cmds["hh"] = Setcommand("hook", "Hard hook various functions that manipulate a heap",self.get_extended_usage()["hardhook"], "hh")
self.cmds["softhook"] = Setcommand("hook", "Soft hook various functions that manipulate a heap",self.get_extended_usage()["softhook"], "sh")
self.cmds["sh"] = Setcommand("hook", "Soft hook various functions that manipulate a heap",self.get_extended_usage()["softhook"], "sh")
self.cmds["patch"] = Setcommand("patch", "Patch various data structures and functions",self.get_extended_usage()["patch"], "p")
self.cmds["p"] = Setcommand("patch", "Patch various data structures and functions",self.get_extended_usage()["patch"], "p")
self.cmds["exploit"] = Setcommand("exploit", "Perform heuristics against the FrontEnd and BackEnd allocators to determine exploitable conditions",self.get_extended_usage()["exploit"], "exp")
self.cmds["exp"] = Setcommand("exploit", "Perform heuristics against the FrontEnd and BackEnd allocators to determine exploitable conditions",self.get_extended_usage()["exploit"], "exp")
self.cmds["config"] = Setcommand("config", "Display or set the current configuration",self.get_extended_usage()["config"], "cnf")
self.cmds["cnf"] = Setcommand("config", "Display or set the current configuration",self.get_extended_usage()["config"], "cnf")
self.cmds["findwritablepointers"] = Setcommand("findwritablepointers", "List all the called, hardcoded, writable function pointers for a given module or modules",self.get_extended_usage()["findwritablepointers"], "findwptrs")
self.cmds["findwptrs"] = Setcommand("findwritablepointers", "List all the called, hardcoded, writable function pointers for a given module or modules",self.get_extended_usage()["findwritablepointers"], "findwptrs")
def set_config(self):
self.imm.addKnowledge("config_workingdir","C:\\Program Files\\Immunity Inc\\Immunity Debugger\\heaper")
# print methods
def print_heaps(self):
self.window.Log("-" * 24)
self.window.Log("Listing available heaps: ")
self.window.Log("")
for hndx in self.imm.getHeapsAddress():
self.window.Log("Heap: 0x%08x" % hndx, address = hndx, focus = 1)
self.window.Log("-" * 16)
return "(+) Dumped all heaps for the debugged process"
def print_peb_struct(self, dump_management=False):
"""
dump the PEB structure using mostly immunities API
arguments:
- obj imm
- obj window
- boolean dump_management flag
return:
- PEB structure if flag is set
- The PEB address if flag is NOT set
"""
self.window.Log("")
if dump_management:
# some PEB members are not in immlib API
AtlThunkSListPtr32 = self.imm.readMemory(self.peb+0x34, 4)
(AtlThunkSListPtr32) = struct.unpack("L", AtlThunkSListPtr32)[0]
# we only need them if we are running win7's PEB structure
if self.os >= 6.0:
AtlThunkSListPtr = self.imm.readMemory(self.peb+0x20, 4)
AtlThunkSListPtr = struct.unpack("L", AtlThunkSListPtr)[0]
IFEOKey = self.imm.readMemory(self.peb+0x24, 4)
IFEOKey = struct.unpack("L", IFEOKey)[0]
ApiSetMap = self.imm.readMemory(self.peb+0x38, 4)
ApiSetMap = struct.unpack("L", ApiSetMap)[0]
FlsBitmapBits = self.imm.readMemory(self.peb+0x21c, 8)
FlsBitmapBits = struct.unpack("d", FlsBitmapBits)[0]
FlsBitmapBits2 = self.imm.readMemory(self.peb+0x21c+0x8, 8)
FlsBitmapBits2 = struct.unpack("d", FlsBitmapBits2)[0]
FlsBitmap = self.imm.readMemory(self.peb+0x218, 4)
FlsBitmap = struct.unpack("L", FlsBitmap)[0]
FlsListHead = self.imm.readMemory(self.peb+0x210, 4)
FlsListHead = struct.unpack("L", FlsListHead)[0]
FlsCallback = self.imm.readMemory(self.peb+0x20c, 4)
FlsCallback = struct.unpack("L", FlsCallback)[0]
FlsHighIndex = self.imm.readMemory(self.peb+0x22c, 4)
FlsHighIndex = struct.unpack("L", FlsHighIndex)[0]
WerRegistrationData = self.imm.readMemory(self.peb+0x230, 4)
WerRegistrationData = struct.unpack("L", WerRegistrationData)[0]
WerShipAssertPtr = self.imm.readMemory(self.peb+0x234, 4)
WerShipAssertPtr = struct.unpack("L", WerShipAssertPtr)[0]
pContextData = self.imm.readMemory(self.peb+0x238, 4)
pContextData = struct.unpack("L", pContextData)[0]
pImageHeaderHash = self.imm.readMemory(self.peb+0x23c, 4)
pImageHeaderHash = struct.unpack("L", pImageHeaderHash)[0]
offset_three = self.imm.readMemory(self.peb+0x03, 1)
offset_three = struct.unpack("B", offset_three)[0]
# get the binary 0/1 representation
binary_three = bin(offset_three)[2:].rjust(8, '0')
CrossProcessFlags = self.imm.readMemory(self.peb+0x28, 4)
CrossProcessFlags = struct.unpack("L", CrossProcessFlags)[0]
# 4 bytes instead of 1 so we expand to 32 bits
binary_twenty_eight = bin(CrossProcessFlags)[2:].rjust(32, '0')
AppCompatFlags = self.imm.readMemory(self.peb+0x1d8, 8)
AppCompatFlags = struct.unpack("LL", AppCompatFlags)[0]
AppCompatFlagsUser = self.imm.readMemory(self.peb+0x1e0, 8)
AppCompatFlagsUser = struct.unpack("LL", AppCompatFlagsUser)[0]
pShimData = self.imm.readMemory(self.peb+0x1e8, 4)
pShimData = struct.unpack("L", pShimData)[0]
ActivationContextData = self.imm.readMemory(self.peb+0x1f8, 4)
ActivationContextData = struct.unpack("L", ActivationContextData)[0]
ProcessAssemblyStorageMap = self.imm.readMemory(self.peb+0x1fc, 4)
ProcessAssemblyStorageMap = struct.unpack("L", ProcessAssemblyStorageMap)[0]
SystemDefaultActivationContextData = self.imm.readMemory(self.peb+0x200, 4)
SystemDefaultActivationContextData = struct.unpack("L", SystemDefaultActivationContextData)[0]
SystemAssemblyStorageMap = self.imm.readMemory(self.peb+0x204, 4)
SystemAssemblyStorageMap = struct.unpack("L", SystemAssemblyStorageMap)[0]
MinimumStackCommit = self.imm.readMemory(self.peb+0x208, 4)
MinimumStackCommit = struct.unpack("L", MinimumStackCommit)[0]
self.window.Log("---------------------------------------------------------")
self.window.Log("PEB Management Structure @ 0x%08x" % self.peb,self.peb)
self.window.Log("---------------------------------------------------------")
self.window.Log("+0x000 InheritedAddressSpace : 0x%08x" % self.peb_struct.InheritedAddressSpace, self.peb_struct.InheritedAddressSpace)
self.window.Log("+0x001 ReadImageFileExecOptions : 0x%08x" % self.peb_struct.ReadImageFileExecOptions, self.peb_struct.ReadImageFileExecOptions)
self.window.Log("+0x002 BeingDebugged : 0x%08x" % self.peb_struct.BeingDebugged, self.peb_struct.BeingDebugged)
if self.os < 6.0:
self.window.Log("+0x003 SpareBool : 0x%08x" % self.peb_struct.SpareBool, self.peb_struct.SpareBool)
elif self.os >= 6.0:
# according the wingdbg symbols
self.window.Log("+0x003 BitField : 0x%x" % offset_three,offset_three)
self.window.Log("+0x003 ImageUsesLargePages : bit: %s" % binary_three[1])
self.window.Log("+0x003 IsProtectedProcess : bit: %s" % binary_three[2])
self.window.Log("+0x003 IsLegacyProcess : bit: %s" % binary_three[3])
self.window.Log("+0x003 IsImageDynamicallyRelocated : bit: %s" % binary_three[4])
self.window.Log("+0x003 SkipPatchingUser32Forwarders : bit: %s" % binary_three[5])
self.window.Log("+0x003 SpareBits : bits 6-8: %s" % binary_three[-3:len(binary_three)])
self.window.Log("+0x004 Mutant : 0x%08x" % self.peb_struct.Mutant, self.peb_struct.Mutant)
self.window.Log("+0x008 ImageBaseAddress : 0x%08x" % self.peb_struct.ImageBaseAddress, self.peb_struct.ImageBaseAddress)
self.window.Log("+0x00c Ldr : 0x%08x" % self.peb_struct.Ldr, self.peb_struct.Ldr)
self.window.Log("+0x010 ProcessParameters : 0x%08x" % self.peb_struct.ProcessParameters, self.peb_struct.ProcessParameters)
self.window.Log("+0x014 SubSystemData : 0x%08x" % self.peb_struct.SubSystemData, self.peb_struct.SubSystemData)
self.window.Log("+0x018 ProcessHeap : 0x%08x" % self.peb_struct.ProcessHeap, self.peb_struct.ProcessHeap)
self.window.Log("+0x01c FastPebLock : 0x%08x" % self.peb_struct.FastPebLock, self.peb_struct.FastPebLock)
if self.os < 6.0:
self.window.Log("+0x020 FastPebLockRoutine : 0x%08x" % self.peb_struct.FastPebLockRoutine, self.peb_struct.FastPebLockRoutine)
self.window.Log("+0x024 FastPebUnLockRoutine : 0x%08x" % self.peb_struct.FastPebUnlockRoutine, self.peb_struct.FastPebUnlockRoutine)
self.window.Log("+0x028 EnvironmentUpdateCount : 0x%08x" % self.peb_struct.EnviromentUpdateCount, self.peb_struct.EnviromentUpdateCount)
elif self.os >= 6.0:
self.window.Log("+0x020 AtlThunkSListPtr : 0x%08x" % AtlThunkSListPtr,AtlThunkSListPtr)
self.window.Log("+0x024 IFEOKey : 0x%08x" % IFEOKey, IFEOKey)
# according the wingdbg symbols
self.window.Log("+0x028 CrossProcessFlags : 0x%08x" % CrossProcessFlags,CrossProcessFlags)
self.window.Log("+0x028 ProcessInJob : bit: %s" % binary_twenty_eight[1])
self.window.Log("+0x028 ProcessInitializing : bit: %s" % binary_twenty_eight[2])
self.window.Log("+0x028 ProcessUsingVEH : bit: %s" % binary_twenty_eight[3])
self.window.Log("+0x028 ProcessUsingVCH : bit: %s" % binary_twenty_eight[4])
self.window.Log("+0x028 ProcessUsingFTH : bit: %s" % binary_twenty_eight[5])
self.window.Log("+0x028 ReservedBits0 : bits 6-32: %s" % binary_twenty_eight[-27:len(binary_twenty_eight)])
self.window.Log("+0x02c KernelCallbackTable : 0x%08x" % self.peb_struct.KernelCallbackTable, self.peb_struct.KernelCallbackTable)
if self.os >= 6.0:
self.window.Log("+0x02c UserSharedInfoPtr : 0x%08x" % self.peb_struct.KernelCallbackTable, self.peb_struct.KernelCallbackTable)
for sysResv in self.peb_struct.SystemReserved:
self.window.Log(" +0x030 SystemReserved : 0x%08x" % sysResv, sysResv)
self.window.Log("+0x034 AtlThunkSListPtr32 : 0x%08x" % AtlThunkSListPtr32, AtlThunkSListPtr32)
if self.os < 6.0:
self.window.Log("+0x038 FreeList : 0x%08x" % self.peb_struct.FreeList, self.peb_struct.FreeList)
elif self.os >= 6.0:
self.window.Log("+0x038 ApiSetMap : 0x%08x" % ApiSetMap, ApiSetMap)
self.window.Log("+0x03c TlsExpansionCounter : 0x%08x" % self.peb_struct.TlsExpansionCounter, self.peb_struct.TlsExpansionCounter)
self.window.Log("+0x040 TlsBitmap : 0x%08x" % self.peb_struct.TlsBitmap, self.peb_struct.TlsBitmap)
for bits in self.peb_struct.TlsBitmapBits:
self.window.Log(" +0x044 TlsBitmapBits : 0x%08x" % bits, bits)
self.window.Log("+0x04c ReadOnlySharedMemoryBase : 0x%08x" % self.peb_struct.ReadOnlySharedMemoryBase, self.peb_struct.ReadOnlySharedMemoryBase)
if self.os < 6.0:
self.window.Log("+0x050 ReadOnlySharedMemoryHeap : 0x%08x" % self.peb_struct.ReadOnlySharedMemoryheap, self.peb_struct.ReadOnlySharedMemoryheap)
elif self.os >= 6.0:
# ReadOnlySharedMemoryheap == HotpatchInformation
self.window.Log("+0x050 HotpatchInformation : 0x%08x" % self.peb_struct.ReadOnlySharedMemoryheap, self.peb_struct.ReadOnlySharedMemoryheap)
self.window.Log("+0x054 ReadOnlyStaticServerData : 0x%08x" % self.peb_struct.ReadOnlyStaticServerData, self.peb_struct.ReadOnlyStaticServerData)
self.window.Log("+0x058 AnsiCodePageData : 0x%08x" % self.peb_struct.AnsiCodePageData, self.peb_struct.AnsiCodePageData)
self.window.Log("+0x05c OemCodePageData : 0x%08x" % self.peb_struct.OemCodePageData, self.peb_struct.OemCodePageData)
self.window.Log("+0x060 UnicodeCaseTableData : 0x%08x" % self.peb_struct.UnicodeCaseTableData, self.peb_struct.UnicodeCaseTableData)
self.window.Log("+0x064 NumberOfProcessors : 0x%08x" % self.peb_struct.NumberOfProcessors, self.peb_struct.NumberOfProcessors)
self.window.Log("+0x068 NtGlobalFlag : 0x%08x" % self.peb_struct.NtGlobalFlag, self.peb_struct.NtGlobalFlag)
self.window.Log("+0x070 CriticalSectionTimeout (high) : 0x%08x" % self.peb_struct.CriticalSectionTimeout_HighPart, self.peb_struct.CriticalSectionTimeout_HighPart)
self.window.Log("+0x070 CriticalSectionTimeout (low) : 0x%08x" % self.peb_struct.CriticalSectionTimeout_LowPart, self.peb_struct.CriticalSectionTimeout_LowPart)
self.window.Log("+0x078 HeapSegmentReserve : 0x%08x" % self.peb_struct.HeapSegmentReserve, self.peb_struct.HeapSegmentReserve)
self.window.Log("+0x07c HeapSegmentCommit : 0x%08x" % self.peb_struct.HeapSegmentCommit, self.peb_struct.HeapSegmentCommit)
self.window.Log("+0x080 HeapDeCommitTotalFreeThreshold : 0x%08x" % self.peb_struct.HeapDeCommitTotalFreeThreshold, self.peb_struct.HeapDeCommitTotalFreeThreshold)
self.window.Log("+0x084 HeapDeCommitFreeBlockThreshold : 0x%08x" % self.peb_struct.HeapDeCommitFreeBlockThreshold, self.peb_struct.HeapDeCommitFreeBlockThreshold)
self.window.Log("+0x088 NumberOfHeaps : 0x%08x" % self.peb_struct.NumberOfHeaps, self.peb_struct.NumberOfHeaps)
self.window.Log("+0x08c MaximumNumberOfHeaps : 0x%08x" % self.peb_struct.MaximumNumberOfHeaps, self.peb_struct.MaximumNumberOfHeaps)
self.window.Log("+0x090 ProcessHeaps : 0x%08x" % self.peb_struct.ProcessHeaps, self.peb_struct.ProcessHeaps)
self.window.Log("+0x094 GdiSharedHandleTable : 0x%08x" % self.peb_struct.GdiSharedHandleTable, self.peb_struct.GdiSharedHandleTable)
self.window.Log("+0x098 ProcessStarterHelper : 0x%08x" % self.peb_struct.ProcessStarterHelper, self.peb_struct.ProcessStarterHelper)
self.window.Log("+0x09c GdiDCAttributeList : 0x%08x" % self.peb_struct.GdiDCAttributeList, self.peb_struct.GdiDCAttributeList)
self.window.Log("+0x0a0 LoaderLock : 0x%08x" % self.peb_struct.LoaderLock, self.peb_struct.LoaderLock)
self.window.Log("+0x0a4 osMajorVersion : 0x%08x" % self.peb_struct.OSMajorVersion, self.peb_struct.OSMajorVersion)
self.window.Log("+0x0a8 osMinorVersion : 0x%08x" % self.peb_struct.OSMinorVersion, self.peb_struct.OSMinorVersion)
self.window.Log("+0x0ac osBuildNumber : 0x%08x" % self.peb_struct.OSBuildNumber, self.peb_struct.OSBuildNumber)
self.window.Log("+0x0ae osCSDVersion : 0x%08x" % self.peb_struct.OSCSDVersion, self.peb_struct.OSCSDVersion)
self.window.Log("+0x0b0 osPlatformId : 0x%08x" % self.peb_struct.OSPlatformId, self.peb_struct.OSPlatformId)
self.window.Log("+0x0b4 ImageSubsystem : 0x%08x" % self.peb_struct.ImageSubsystem, self.peb_struct.ImageSubsystem)
self.window.Log("+0x0b8 ImageSubsystemMajorVersion : 0x%08x" % self.peb_struct.ImageSubsystemMajorVersion, self.peb_struct.ImageSubsystemMajorVersion)
self.window.Log("+0x0bc ImageSubsystemMinorVersion : 0x%08x" % self.peb_struct.ImageSubsystemMinorVersion, self.peb_struct.ImageSubsystemMinorVersion)
if self.os < 6.0:
# ImageProcessAffinityMask == ActiveProcessAffinityMask
self.window.Log("+0x0c0 ImageProcessAffinityMask : 0x%08x" % self.peb_struct.ImageProcessAffinityMask, self.peb_struct.ImageProcessAffinityMask)
elif self.os >= 6.0:
self.window.Log("+0x0c0 ActiveProcessAffinityMask : 0x%08x" % self.peb_struct.ImageProcessAffinityMask, self.peb_struct.ImageProcessAffinityMask)
for buff in self.peb_struct.GdiHandleBuffer:
self.window.Log(" +0x0c4 GdiHandleBuffer : 0x%08x" % buff, buff)
self.window.Log("+0x14c PostProcessInitRoutine : 0x%08x" % self.peb_struct.PostProcessInitRoutine, self.peb_struct.PostProcessInitRoutine)
self.window.Log("+0x150 TlsExpansionBitmap : 0x%08x" % self.peb_struct.TlsExpansionBitmap, self.peb_struct.TlsExpansionBitmap)
for bitmapbits in self.peb_struct.TlsExpansionBitmapBits:
self.window.Log(" +0x154 TlsExpansionBitmapBits : 0x%08x" % bitmapbits, bitmapbits)
self.window.Log("+0x1d4 SessionId : 0x%08x" % self.peb_struct.SessionId, self.peb_struct.SessionId)
self.window.Log("+0x1d8 AppCompatFlags : 0x%08x" % AppCompatFlags, AppCompatFlags)
self.window.Log("+0x1e0 AppCompatFlagsUser : 0x%08x" % AppCompatFlagsUser, AppCompatFlagsUser)
self.window.Log("+0x1e8 pShimData : 0x%08x" % pShimData, pShimData)
self.window.Log("+0x1ec AppCompatInfo : 0x%08x" % self.peb_struct.AppCompatInfo, self.peb_struct.AppCompatInfo)
self.window.Log("+0x1f0 CSDVersion : 0x%08x" % self.peb_struct.CSDVersion_Buffer, self.peb_struct.CSDVersion_Buffer)
self.window.Log("+0x1f8 ActivationContextData : 0x%08x" % ActivationContextData, ActivationContextData)
self.window.Log("+0x1fc ProcessAssemblyStorageMap : 0x%08x" % ProcessAssemblyStorageMap, ProcessAssemblyStorageMap)
self.window.Log("+0x200 SystemDefaultActivationContextData : 0x%08x" % SystemDefaultActivationContextData, SystemDefaultActivationContextData)
self.window.Log("+0x204 SystemAssemblyStorageMap : 0x%08x" % SystemAssemblyStorageMap, SystemAssemblyStorageMap)
self.window.Log("+0x208 MinimumStackCommit : 0x%08x" % MinimumStackCommit, MinimumStackCommit)
if self.os >= 6.0:
self.window.Log("+0x20c FlsCallback : 0x%08x" % FlsCallback,FlsCallback)
self.window.Log("+0x210 FlsListHead : 0x%08x" % FlsListHead,FlsListHead)
self.window.Log("+0x218 FlsBitmap : 0x%08x" % FlsBitmap,FlsBitmap)
self.window.Log("+0x21c FlsBitmapBits : 0x%08x%08x" % (FlsBitmapBits,FlsBitmapBits2))
self.window.Log("+0x22c FlsHighIndex : 0x%08x" % FlsHighIndex,FlsHighIndex)
self.window.Log("+0x230 WerRegistrationData : 0x%08x" % WerRegistrationData,WerRegistrationData)
self.window.Log("+0x234 WerShipAssertPtr : 0x%08x" % WerShipAssertPtr,WerShipAssertPtr)
self.window.Log("+0x238 pContextData : 0x%08x" % pContextData,pContextData)
self.window.Log("+0x23c pImageHeaderHash : 0x%08x" % pImageHeaderHash,pImageHeaderHash)
self.window.Log("---------------------------------------------------------")
self.window.Log("")
return "Dumped PEB successfully"
else:
self.window.Log("(+) The PEB is located at 0x%08x" % self.peb,self.peb)
peb_struct = self.imm.getPEB()
# check at least to locations where the PEB might be patched..
if peb_struct.BeingDebugged and peb_struct.NtGlobalFlag:
self.window.Log("(!) Beaware! the PEB is not patched and heap operations may detect a debugger!")
elif peb_struct.BeingDebugged == 0 and peb_struct.NtGlobalFlag == 0:
self.window.Log("(+) Excellent, the PEB appears to be patched")
return "(+) PEB is located at 0x%08x" % self.peb
def print_teb(self):
"""
dump Thread environment block - dumps the listed TEB's in the current process
(multi-threaded application)
arguments:
- obj imm
- obj window
return:
- printed TEB addresses
"""
currenttid = self.imm.getThreadId()
threads = self.imm.getAllThreads()
self.window.Log("")
try:
currentTEB = threads[currenttid].getTEB()
self.window.Log("(+) The current TEB id is: %s and is located at: 0x%08x" % (currenttid,currentTEB),currentTEB)
except:
self.window.Log("(-) The current TEB id is: %s and is located at an unknown address" % (currenttid))
tebArray = {}
for key in threads:
teb = key.getTEB()
tid = key.getId()
tebArray[teb] = tid
valuelist = tebArray.keys()
valuelist.sort()
valuelist.reverse()
if len(valuelist) == 1:
self.window.Log("(!) There is only 1 thread running (the current TEB)")
else:
self.window.Log("(+) There are %d number of threads in this process" % len(valuelist))
self.window.Log("(+) Other TEB's in this process:")
for key in valuelist:
self.window.Log("(+) ID: %s is located at: 0x%08x" % (tebArray[key],key), key)
self.window.Log("-" * 40)
return "(+) Dumped TEB successfully"
def print_heap_struct(self):
"""
allows you to dump the _heap structure
arguments:
- int heap
- obj imm
- obj window
return:
- string showing the heap is dumped
"""
if self.heap and ( self.heap in self.imm.getHeapsAddress() ):
i = 0
v = 0
self.window.Log("--------------------------------------------------")
self.window.Log("Heap structure @ 0x%08x" % self.heap)
self.window.Log("--------------------------------------------------")
self.window.Log("+0x000 Entry : 0x%08x" % self.heap, self.heap)
if self.os < 6.0:
self.window.Log("+0x008 Signature : 0x%08x" % self.pheap.Signature, self.pheap.Signature)
self.window.Log("+0x00c Flags : 0x%08x" % self.pheap.Flags, self.pheap.Flags)
self.window.Log("+0x010 Forceflags : 0x%08x" % self.pheap.ForceFlags, self.pheap.ForceFlags)
self.window.Log("+0x014 VirtualMemoryThreshold : 0x%08x" % self.pheap.VirtualMemoryThreshold, self.pheap.VirtualMemoryThreshold)
self.window.Log("+0x018 SegmentReserve : 0x%08x" % self.pheap.SegmentReserve, self.pheap.SegmentReserve)
self.window.Log("+0x01C SegmentCommit : 0x%08x" % self.pheap.SegmentCommit, self.pheap.SegmentCommit)
elif self.os >= 6.0:
self.window.Log("+0x008 SegmentSignature : 0x%08x" % self.pheap.Signature, self.pheap.Signature)
self.window.Log("+0x00c SegmentFlags : 0x%08x" % self.pheap.Flags, self.pheap.Flags)
SegmentListEntry = self.imm.readMemory(self.heap+0x14, 4)
SegmentListEntry = struct.unpack("L", SegmentListEntry)[0]
self.window.Log("+0x010 SegmentListEntry : 0x%08x" % SegmentListEntry, SegmentListEntry)
self.window.Log("+0x018 Heap : 0x%08x" % self.pheap.SegmentReserve, self.pheap.SegmentReserve)
self.window.Log("+0x01C BaseAddress : 0x%08x" % self.pheap.SegmentCommit, self.pheap.SegmentCommit)
if self.os < 6.0:
self.window.Log("+0x020 DeCommitFreeBlockThreshold : 0x%08x" % self.pheap.DeCommitFreeBlockThreshold, self.pheap.DeCommitFreeBlockThreshold)
self.window.Log("+0x024 DeCommitTotalBlockThreshold : 0x%08x" % self.pheap.DeCommitTotalBlockThreshold, self.pheap.DeCommitTotalBlockThreshold)
self.window.Log("+0x028 TotalFreeSize : 0x%08x" % self.pheap.TotalFreeSize, self.pheap.TotalFreeSize)
elif self.os >= 6.0:
self.window.Log("+0x020 NumberOfPages : 0x%08x" % self.pheap.NumberOfPages, self.pheap.NumberOfPages)
self.window.Log("+0x024 FirstEntry : 0x%08x" % self.pheap.FirstEntry, self.pheap.FirstEntry)
self.window.Log("+0x028 LastValidEntry : 0x%08x" % self.pheap.TotalFreeSize, self.pheap.TotalFreeSize)
if self.os < 6.0:
self.window.Log("+0x02c MaximumAllocationSize : 0x%08x" % self.pheap.MaximumAllocationSize, self.pheap.MaximumAllocationSize)
elif self.os >= 6.0:
NumberOfUnCommittedPages = self.imm.readMemory(self.heap+0x2c, 4)
NumberOfUnCommittedPages = struct.unpack("L", NumberOfUnCommittedPages)[0]
self.window.Log("+0x02c NumberOfUnCommittedPages : 0x%08x" % NumberOfUnCommittedPages, NumberOfUnCommittedPages)
# libheap does not have some members, so we are on our own
ProcessHeapsListIndex = self.imm.readMemory(self.heap+0x30, 2)
ProcessHeapsListIndex = struct.unpack("H", ProcessHeapsListIndex)[0]
if self.os < 6.0:
self.window.Log("+0x030 ProcessHeapsListIndex : 0x%08x" % ProcessHeapsListIndex, ProcessHeapsListIndex)
elif self.os >= 6.0:
self.window.Log("+0x030 NumberOfUnCommittedRanges : 0x%08x" % ProcessHeapsListIndex, ProcessHeapsListIndex)
# libheap does not have some members, so we are on our own
SegmentAllocatorBackTraceIndex = self.imm.readMemory(self.heap+0x34, 2)
SegmentAllocatorBackTraceIndex = struct.unpack("H", SegmentAllocatorBackTraceIndex)[0]
Reserved = self.imm.readMemory(self.heap+0x36, 2)
Reserved = struct.unpack("H", Reserved)[0]
UCRSegmentList = self.imm.readMemory(self.heap+0x38, 4)
UCRSegmentList = struct.unpack("L", UCRSegmentList)[0]
UCRSegmentList1 = self.imm.readMemory(self.heap+0x3c, 4)
UCRSegmentList1 = struct.unpack("L", UCRSegmentList1)[0]
self.window.Log("+0x034 SegmentAllocatorBackTraceIndex : 0x%08x" % SegmentAllocatorBackTraceIndex, SegmentAllocatorBackTraceIndex)
self.window.Log("+0x036 Reserved : 0x%08x" % Reserved, Reserved)
self.window.Log("+0x038 UCRSegmentList : 0x%08x%08x" % (UCRSegmentList,UCRSegmentList1))
# uncommited range segments
if self.os < 6.0:
self.window.Log("+0x032 HeaderValidateLength : 0x%08x" % self.pheap.HeaderValidateLength, self.pheap.HeaderValidateLength)
self.window.Log("+0x034 HeaderValidateCopy : 0x%08x" % self.pheap.HeaderValidateCopy, self.pheap.HeaderValidateCopy)
self.window.Log("+0x038 NextAvailableTagIndex : 0x%08x" % self.pheap.NextAvailableTagIndex, self.pheap.NextAvailableTagIndex)
self.window.Log("+0x03a MaximumTagIndex : 0x%08x" % self.pheap.MaximumTagIndex, self.pheap.MaximumTagIndex)
self.window.Log("+0x03c TagEntries : 0x%08x" % self.pheap.TagEntries, self.pheap.TagEntries)
self.window.Log("+0x040 UCRSegments : 0x%08x" % self.pheap.UCRSegments, self.pheap.UCRSegments)
self.window.Log("+0x044 UnusedUncommittedRanges : 0x%08x" % self.pheap.UnusedUnCommittedRanges, self.pheap.UnusedUnCommittedRanges)
self.window.Log("+0x048 AlignRound : 0x%08x" % self.pheap.AlignRound, self.pheap.AlignRound)
self.window.Log("+0x04c AlignMask : 0x%08x" % self.pheap.AlignMask, self.pheap.AlignMask)
elif self.os >= 6.0:
self.window.Log("+0x040 Flags : 0x%08x" % self.pheap.Flags, self.pheap.Flags)
self.window.Log("+0x044 ForceFlags : 0x%08x" % self.pheap.ForceFlags, self.pheap.ForceFlags)
self.window.Log("+0x048 CompatibilityFlags : 0x%08x" % self.pheap.AlignRound, self.pheap.AlignRound)
self.window.Log("+0x04c EncodeFlagMask : 0x%08x" % self.pheap.AlignMask, self.pheap.AlignMask)
# lots of blocks..
if self.os < 6.0:
self.window.Log("+0x050 VirtualAllocedBlocks ")
for block in self.pheap.VirtualAllocedBlock:
v += 1
self.window.Log(" VirtualAllocedBlock %d : 0x%08x" % (v,block), block)
self.window.Log("+0x058 Segments")
for segment in self.pheap.Segments:
i += 1
self.window.Log(" Segment %d : 0x%08x" % (i,segment.BaseAddress), segment.BaseAddress)
FreelistBitmap = self.imm.readMemory(self.heap+0x158, 4)
FreelistBitmap = struct.unpack("L", FreelistBitmap)[0]
self.window.Log("+0x158 FreelistBitmap : 0x%08x" % FreelistBitmap, FreelistBitmap)
self.window.Log("+0x16a AllocatorBackTraceIndex : 0x%08x" % self.pheap.AllocatorBackTraceIndex, self.pheap.AllocatorBackTraceIndex)
NonDedicatedListLength = self.imm.readMemory(self.heap+0x16c, 4)
NonDedicatedListLength = struct.unpack("L", NonDedicatedListLength)[0]
self.window.Log("+0x16c NonDedicatedListLength : 0x%08x" % NonDedicatedListLength, NonDedicatedListLength)
if self.os < 6.0:
self.window.Log("+0x170 LargeBlocksIndex : 0x%08x" % self.pheap.LargeBlocksIndex, self.pheap.LargeBlocksIndex)
self.window.Log("+0x174 PseudoTagEntries : 0x%08x" % self.pheap.PseudoTagEntries)
self.window.Log("+0x178 Freelist[0] : 0x%08x" % (self.heap+0x178), (self.heap+0x178))
self.window.Log("+0x578 LockVariable : 0x%08x" % self.pheap.LockVariable, self.pheap.LockVariable)
self.window.Log("+0x57c CommitRoutine : 0x%08x" % self.pheap.CommitRoutine, self.pheap.CommitRoutine)
FrontEndHeap = self.imm.readMemory(self.heap+0x580, 4)
FrontEndHeap = struct.unpack("L", FrontEndHeap)[0]
FrontHeapLockCount = self.imm.readMemory(self.heap+0x584, 2)
FrontHeapLockCount = struct.unpack("H", FrontHeapLockCount)[0]
FrontEndHeapType = self.imm.readMemory(self.heap+0x586, 1)
FrontEndHeapType = struct.unpack("B", FrontEndHeapType)[0]
LastSegmentIndex = self.imm.readMemory(self.heap+0x587, 1)
LastSegmentIndex = struct.unpack("B", LastSegmentIndex)[0]
self.window.Log("+0x580 FrontEndHeap : 0x%08x" % FrontEndHeap, FrontEndHeap)
self.window.Log("+0x584 FrontHeapLockCount : 0x%08x" % FrontHeapLockCount, FrontHeapLockCount)
self.window.Log("+0x586 FrontEndHeapType : 0x%08x" % FrontEndHeapType, FrontEndHeapType)
self.window.Log("+0x587 LastSegmentIndex : 0x%08x" % LastSegmentIndex, LastSegmentIndex)
elif self.os >= 6.0:
Encoding = self.imm.readMemory(self.heap+0x50, 4)
Encoding = struct.unpack("L", Encoding)[0]
self.window.Log("+0x050 Encoding : 0x%08x" % Encoding, Encoding)
self.window.Log("+0x058 PointerKey : 0x%08x" % self.pheap.PointerKey, self.pheap.PointerKey)
Interceptor = self.imm.readMemory(self.heap+0x5c, 4)
Interceptor = struct.unpack("L", Interceptor)[0]
self.window.Log("+0x05c Interceptor : 0x%08x" % Interceptor, Interceptor)
self.window.Log("+0x060 VirtualMemoryThreshold : 0x%08x" % self.pheap.VirtualMemoryThreshold, self.pheap.VirtualMemoryThreshold)
self.window.Log("+0x064 Signature : 0x%08x" % self.pheap.Signature, self.pheap.Signature)
self.window.Log("+0x068 SegmentReserve : 0x%08x" % self.pheap.SegmentReserve, self.pheap.SegmentReserve)
self.window.Log("+0x06c SegmentCommit : 0x%08x" % self.pheap.SegmentCommit, self.pheap.SegmentCommit)
DeCommitFreeBlockThreshold = self.imm.readMemory(self.heap+0x70, 4)
DeCommitFreeBlockThreshold = struct.unpack("L", DeCommitFreeBlockThreshold)[0]
DeCommitTotalFreeThreshold = self.imm.readMemory(self.heap+0x74, 4)
DeCommitTotalFreeThreshold = struct.unpack("L", DeCommitTotalFreeThreshold)[0]
self.window.Log("+0x070 DeCommitFreeBlockThreshold : 0x%08x" % DeCommitFreeBlockThreshold, DeCommitFreeBlockThreshold)
self.window.Log("+0x074 DeCommitTotalFreeThreshold : 0x%08x" % DeCommitTotalFreeThreshold, DeCommitTotalFreeThreshold)
self.window.Log("+0x078 TotalFreeSize : 0x%08x" % self.pheap.TotalFreeSize, self.pheap.TotalFreeSize)
MaximumAllocationSize = self.imm.readMemory(self.heap+0x7c, 4)
MaximumAllocationSize = struct.unpack("L", MaximumAllocationSize)[0]
self.window.Log("+0x07c MaximumAllocationSize : 0x%08x" % MaximumAllocationSize, MaximumAllocationSize)
self.window.Log("+0x080 ProcessHeapsListIndex : 0x%08x" % self.pheap.ProcessHeapsListIndex, self.pheap.ProcessHeapsListIndex)
self.window.Log("+0x082 HeaderValidateLength : 0x%08x" % self.pheap.HeaderValidateLength, self.pheap.HeaderValidateLength)
self.window.Log("+0x084 HeaderValidateCopy : 0x%08x" % self.pheap.HeaderValidateCopy, self.pheap.HeaderValidateCopy)
self.window.Log("+0x088 NextAvailableTagIndex : 0x%08x" % self.pheap.NextAvailableTagIndex, self.pheap.NextAvailableTagIndex)
self.window.Log("+0x08a MaximumTagIndex : 0x%08x" % self.pheap.MaximumTagIndex, self.pheap.MaximumTagIndex)
self.window.Log("+0x08c TagEntries : 0x%08x" % self.pheap.TagEntries, self.pheap.TagEntries)
UCRList1 = self.imm.readMemory(self.heap+0x90, 4)
UCRList1 = struct.unpack("L", UCRList1)[0]
UCRList2 = self.imm.readMemory(self.heap+0x94, 4)
UCRList2 = struct.unpack("L", UCRList2)[0]
self.window.Log("+0x090 UCRList : 0x%08x%08x" % (UCRList1, UCRList2))
self.window.Log("+0x098 AlignRound : 0x%08x" % self.pheap.AlignRound, self.pheap.AlignRound)
self.window.Log("+0x09c AlignMask : 0x%08x" % self.pheap.AlignMask, self.pheap.AlignMask)
VirtualAllocdBlocks1 = self.imm.readMemory(self.heap+0x0a0, 4)
VirtualAllocdBlocks1 = struct.unpack("L", VirtualAllocdBlocks1)[0]
VirtualAllocdBlocks2 = self.imm.readMemory(self.heap+0x0a4, 4)
VirtualAllocdBlocks2 = struct.unpack("L", VirtualAllocdBlocks2)[0]
self.window.Log("+0x0a0 VirtualAllocdBlocks : 0x%08x%08x" % (VirtualAllocdBlocks1, VirtualAllocdBlocks2))
SegmentList1 = self.imm.readMemory(self.heap+0x0a8, 4)
SegmentList1 = struct.unpack("L", SegmentList1)[0]
SegmentList2 = self.imm.readMemory(self.heap+0x0ac, 4)
SegmentList2 = struct.unpack("L", SegmentList2)[0]
self.window.Log("+0x0a8 SegmentList : 0x%08x%08x" % (SegmentList1, SegmentList2))
self.window.Log("+0x0b0 AllocatorBackTraceIndex : 0x%08x" % self.pheap.AllocatorBackTraceIndex, self.pheap.AllocatorBackTraceIndex)
NonDedicatedListLength = self.imm.readMemory(self.heap+0x0b4, 4)
NonDedicatedListLength = struct.unpack("L", NonDedicatedListLength)[0]
BlocksIndex = self.imm.readMemory(self.heap+0x0b8, 4)
BlocksIndex = struct.unpack("L", BlocksIndex)[0]
UCRIndex = self.imm.readMemory(self.heap+0x0bc, 4)
UCRIndex = struct.unpack("L", UCRIndex)[0]
FreeLists = self.imm.readMemory(self.heap+0x0c4, 4)
FreeLists = struct.unpack("L", FreeLists)[0]
self.window.Log("+0x0b4 NonDedicatedListLength : 0x%08x" % NonDedicatedListLength, NonDedicatedListLength)
self.window.Log("+0x0b8 BlocksIndex : 0x%08x" % BlocksIndex, BlocksIndex)
self.window.Log("+0x0bc UCRIndex : 0x%08x" % UCRIndex, UCRIndex)
self.window.Log("+0x0c0 PseudoTagEntries : 0x%08x" % self.pheap.PseudoTagEntries, self.pheap.PseudoTagEntries)
self.window.Log("+0x0c4 FreeLists : 0x%08x" % FreeLists, FreeLists)
self.window.Log("+0x0cc LockVariable : 0x%08x" % self.pheap.LockVariable, self.pheap.LockVariable)
self.window.Log("+0x0d0 CommitRoutine : 0x%08x" % self.pheap.CommitRoutine, self.pheap.CommitRoutine)
FrontEndHeap = self.imm.readMemory(self.heap+0x0d4, 4)
FrontEndHeap = struct.unpack("L", FrontEndHeap)[0]
FrontHeapLockCount = self.imm.readMemory(self.heap+0x0d8, 2)
FrontHeapLockCount = struct.unpack("H", FrontHeapLockCount)[0]
FrontEndHeapType = self.imm.readMemory(self.heap+0x0da, 2)
FrontEndHeapType = struct.unpack("H", FrontEndHeapType)[0]
Counters = self.imm.readMemory(self.heap+0x0dc, 4)
Counters = struct.unpack("L", Counters)[0]
TuningParameters = self.imm.readMemory(self.heap+0x0d8, 4)
TuningParameters = struct.unpack("L", TuningParameters)[0]
self.window.Log("+0x0d4 FrontEndHeap : 0x%08x" % FrontEndHeap, FrontEndHeap)
self.window.Log("+0x0d8 FrontHeapLockCount : 0x%04x" % FrontHeapLockCount, FrontHeapLockCount)
self.window.Log("+0x0da FrontEndHeapType : 0x%04x" % FrontEndHeapType, FrontEndHeapType)
self.window.Log("+0x0dc Counters : 0x%08x" % Counters, Counters)
self.window.Log("+0x130 TuningParameters : 0x%08x" % TuningParameters, TuningParameters)
return "(+) Dumped the heap structure 0x%08x" % self.heap
def print_segment_structure(self):
"""
allows the user to dump the segment structure(s) from a heap
arguments:
- obj heap
- obj window
- obj imm
- int heap
return:
- string showing the segment is dumped
"""
for segment in self.pheap.Segments:
self.window.Log("")
self.window.Log("-" * 19)
self.window.Log("Segment: 0x%08x" % segment.BaseAddress)
self.window.Log("-" * 19)
self.window.Log("")
entry_0 = self.imm.readMemory(segment.BaseAddress, 4)
entry_0 = struct.unpack("L", entry_0)[0]
entry_1 = self.imm.readMemory(segment.BaseAddress+0x4, 4)
entry_1 = struct.unpack("L", entry_1)[0]
signature = self.imm.readMemory(segment.BaseAddress+0x8, 4)
signature = struct.unpack("L", signature)[0]
flags = self.imm.readMemory(segment.BaseAddress+0xc, 4)
flags = struct.unpack("L", flags)[0]
heap_ = self.imm.readMemory(segment.BaseAddress+0x10, 4)
heap_ = struct.unpack("L", heap_)[0]
LargestUncommitedRange = self.imm.readMemory(segment.BaseAddress+0x14, 4)
LargestUncommitedRange = struct.unpack("L", LargestUncommitedRange)[0]
BaseAddress = self.imm.readMemory(segment.BaseAddress+0x18, 4)
BaseAddress = struct.unpack("L", BaseAddress)[0]
NumberOfPages = self.imm.readMemory(segment.BaseAddress+0x1c, 4)
NumberOfPages = struct.unpack("L", NumberOfPages)[0]
FirstEntry = self.imm.readMemory(segment.BaseAddress+0x20, 4)
FirstEntry = struct.unpack("L", FirstEntry)[0]
LastValidEntry = self.imm.readMemory(segment.BaseAddress+0x24, 4)
LastValidEntry = struct.unpack("L", LastValidEntry)[0]
NumberOfUncommitedPages = self.imm.readMemory(segment.BaseAddress+0x28, 4)
NumberOfUncommitedPages = struct.unpack("L", NumberOfUncommitedPages)[0]
NumberOfUncommitedRanges = self.imm.readMemory(segment.BaseAddress+0x2c, 4)
NumberOfUncommitedRanges = struct.unpack("L", NumberOfUncommitedRanges)[0]
UnCommitedRanges = self.imm.readMemory(segment.BaseAddress+0x30, 4)
UnCommitedRanges = struct.unpack("L", UnCommitedRanges)[0]
AllocatorBackTraceIndex = self.imm.readMemory(segment.BaseAddress+0x34, 2)
AllocatorBackTraceIndex = struct.unpack("H", AllocatorBackTraceIndex)[0]
Reserved = self.imm.readMemory(segment.BaseAddress+0x36, 2)
Reserved = struct.unpack("H", Reserved)[0]
LastEntryInSegment = self.imm.readMemory(segment.BaseAddress+0x38, 4)
LastEntryInSegment = struct.unpack("L", LastEntryInSegment)[0]
self.window.Log("+0x000 Entry (high) : 0x%08x" % entry_0,entry_0)
self.window.Log("+0x000 Entry (low) : 0x%08x" % entry_1,entry_1)
self.window.Log("+0x008 Signature : 0x%08x" % signature,signature)
self.window.Log("+0x00c Flags : 0x%08x" % flags,flags)
self.window.Log("+0x010 heap : 0x%08x" % heap_,heap_)
self.window.Log("+0x014 LargestUncommitedRange : 0x%08x" % LargestUncommitedRange,LargestUncommitedRange)
self.window.Log("+0x018 BaseAddress : 0x%08x" % BaseAddress,BaseAddress)
self.window.Log("+0x01c NumberOfPages : 0x%08x" % NumberOfPages,NumberOfPages)
self.window.Log("+0x020 FirstEntry : 0x%08x" % FirstEntry,FirstEntry)
self.window.Log("+0x024 LastValidEntry : 0x%08x" % LastValidEntry,LastValidEntry)
self.window.Log("+0x028 NumberOfUncommitedPages : 0x%08x" % NumberOfUncommitedPages,NumberOfUncommitedPages)
self.window.Log("+0x02c NumberOfUncommitedRanges : 0x%08x" % NumberOfUncommitedRanges,NumberOfUncommitedRanges)
self.window.Log("+0x030 UnCommitedRanges : 0x%08x" % UnCommitedRanges,UnCommitedRanges)
self.window.Log("+0x034 AllocatorBackTraceIndex : 0x%08x" % AllocatorBackTraceIndex,AllocatorBackTraceIndex)
self.window.Log("+0x036 Reserved : 0x%08x" % Reserved,Reserved)
self.window.Log("+0x038 LastEntryInSegment : 0x%08x" % LastEntryInSegment,LastEntryInSegment)
return "(+) Dumped all Heap Segmements in heap 0x%08x" % self.heap
# print all chunks, busy, free, frontend or backend
def print_all_chunks(self, chunk_filter, show_detail=False):
for chunk in self.pheap.chunks:
trigger = False
# chunks on the lookaside will "appear" busy
if chunk_filter == "busy":
if chunk.getflags(chunk.flags) == "B$":
trigger = True
self.window.Log("(+) Chunk on the Lookaside @ 0x%08x" % chunk.addr,chunk.addr)
self.window.Log(" -> Lookaside[0x%02x] entry" % chunk.size)
self.window.Log(" -> Flink: 0x%08x" % (chunk.addr+0x8))
elif chunk.getflags(chunk.flags) == "B":
trigger = True
self.window.Log("(+) BUSY chunk @ 0x%08x" % chunk.addr,chunk.addr)
elif chunk.getflags(chunk.flags) == "B|T" and chunk_filter == "busy":
trigger = True
self.window.Log("(+) Last BUSY chunk @ 0x%08x" % chunk.addr,chunk.addr)
elif chunk_filter == "free":
if chunk.getflags(chunk.flags) == "F$":
trigger = True
self.window.Log("(+) Chunk on the Lookaside @ 0x%08x" % chunk.addr,chunk.addr)
elif chunk.getflags(chunk.flags) == "F":
trigger = True
self.window.Log("(+) Chunk on the Freelist @ 0x%08x+0x08 (0x%08x)" % (chunk.addr,(chunk.addr+0x08)), chunk.addr)
self.window.Log(" -> Freelist[0x%02x] entry" % chunk.size)
self.window.Log(" -> Flink: 0x%08x" % chunk.nextchunk)
self.window.Log(" -> Blink: 0x%08x" % chunk.prevchunk)
if trigger:
self.window.Log("")
self.window.Log(" -> size: 0x%08x (8 * 0x%04x = 0x%04x, decimal: %d)" % (chunk.usize, chunk.size, chunk.usize, chunk.usize) )
self.window.Log(" -> prevsize: 0x%08x (%04x)" % (chunk.upsize, chunk.psize))
self.window.Log(" -> flags: 0x%04x (%s)" % (chunk.flags, chunk.getflags(chunk.flags)))
if not show_detail:
self.window.Log("-" * 62)
if show_detail:
dump = immutils.hexdump(chunk.sample)
for a in range(0, len(dump)):
if not a:
self.window.Log(" -> First 16 bytes of data:")
self.window.Log(" -> hex: \\x%s" % dump[a][0].rstrip().replace(" ", "\\x"))
self.window.Log(" -> ascii: %s" % (dump[a][1]))
self.window.Log("-" * 80)
def to_hexidecimal(self, n):
return "%08x" % n
def generate_githash(self, data):
s = sha1()
s.update("blob %u\0" % len(data))
s.update(data)
return s.hexdigest()
def meets_access_level(self, page, accessLevel):
"""
Checks if a given page meets a given access level
Arguments:
page - a page object
accesslevel - a string containing one of the following access levels :
R,W,X,RW,RX,WR,WX,RWX or *
Return:
a boolean
"""
if "*" in accessLevel:
return True
pageAccess = page.getAccess(human=True)
if "R" in accessLevel:
if not "READ" in pageAccess:
return False
if "W" in accessLevel:
if not "WRITE" in pageAccess:
return False
if "X" in accessLevel:
if not "EXECUTE" in pageAccess:
return False
return True
def patch_or_restore_ptrs(self, addr=False, patch=False, restore=False):
"""
This function saves, patches or restores pointers
"""
# we are storing the pointer and data
if addr and not patch and not restore:
ptr_data = self.imm.readMemory(addr.adrconst, 4)
ptr_data = struct.unpack("L", ptr_data)[0]
# only if the key is not in the dict do we add it.
# lets not change the data at the pointer...
if not self.ptr_dict.has_key(addr.adrconst):
self.ptr_dict[addr.adrconst] = [addr, ptr_data]
# save the knowledge
self.imm.addKnowledge("writablepointers", self.ptr_dict, force_add = 1)
# we are patching
elif patch and not restore and not addr:
for ptr, addr_data in self.ptr_dict.iteritems():
self.window.Log("0x%08x: %s | patching ptr: 0x%08x" % (addr_data[0].ip, addr_data[0].result, addr_data[0].adrconst), addr_data[0].adrconst)
# we just write 0x41414141 for now, this can be changed later
self.imm.writeLong( ptr, 0x41414141 )
# we are restoring
elif restore and not patch and not addr:
for ptr, addr_data in self.ptr_dict.iteritems():
self.window.Log("0x%08x: %s | restoring ptr: 0x%08x" % (addr_data[0].ip, addr_data[0].result, addr_data[0].adrconst), addr_data[0].adrconst)
self.imm.writeLong(ptr, addr_data[1])
self.imm.forgetKnowledge("writablepointers")
def find_hardcoded_pointers(self, usermodule=False, patch=False, restore=False):
"""
This function finds all static function pointers
either for a given module or all modules
"""
text_addresses = {}
if not usermodule:
confirmation = self.imm.comboBox("Time is of essence, so are you sure?",["yes","no"])
if confirmation == "yes":
for name in self.imm.getAllModules().iterkeys():
module = name.lower()
module_page = self.imm.getMemoryPageByOwner(module)
usermod_obj = self.imm.findModuleByName(module)
# tries to filter the IAT, but if it fails, no big deal
iat_table = self.get_modules_iat(usermod_obj)
for u in module_page:
# xp and windows 7 tested
if u.section == ".text" or u.section == "CODE":
mod = self.imm.findModule(u.owner)
modname = mod[0]
usermod_obj = self.imm.getModule(modname)
if not text_addresses.has_key(u.baseaddress):