@@ -18,7 +18,7 @@ class Malfind(interfaces.plugins.PluginInterface):
1818 """Lists process memory ranges that potentially contain injected code."""
1919
2020 _required_framework_version = (2 , 0 , 0 )
21- _version = (1 , 0 , 3 )
21+ _version = (1 , 0 , 4 )
2222
2323 @classmethod
2424 def get_requirements (cls ) -> List [interfaces .configuration .RequirementInterface ]:
@@ -37,6 +37,18 @@ def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]
3737 element_type = int ,
3838 optional = True ,
3939 ),
40+ requirements .IntRequirement (
41+ name = "dump-size" ,
42+ description = "Amount of bytes to dump for each dirty region/page found - Default 64 bytes" ,
43+ optional = True ,
44+ default = 64 ,
45+ ),
46+ requirements .BooleanRequirement (
47+ name = "dump-page" ,
48+ description = "Dump each dirty page and content - Default off" ,
49+ optional = True ,
50+ default = False ,
51+ ),
4052 ]
4153
4254 def _list_injections (
@@ -51,14 +63,36 @@ def _list_injections(
5163
5264 proc_layer = self .context .layers [proc_layer_name ]
5365
66+ dump_size = self .config ["dump-size" ]
67+
68+ # Dumping page defaults to off, as in case a whole r-xp region is dirty
69+ # this would likely dump 1000's of pages which might not always be wise nor necessary
70+
71+ dump_page = self .config ["dump-page" ]
72+
5473 for vma in task .mm .get_vma_iter ():
5574 vma_name = vma .get_name (self .context , task )
5675 vollog .debug (
5776 f"Injections : processing PID { task .pid } : VMA { vma_name } : { hex (vma .vm_start )} -{ hex (vma .vm_end )} "
5877 )
78+
79+ # If is_suspicious returns true, this means at least one page
80+ # in the region is dirty. If dump_page is true, then we dump
81+ # all dirty pages
82+
5983 if vma .is_suspicious (proc_layer ) and vma_name != "[vdso]" :
60- data = proc_layer .read (vma .vm_start , 64 , pad = True )
61- yield vma , vma_name , data
84+ malicious_pages = vma .get_malicious_pages (proc_layer )
85+ offset = 0
86+ if dump_page :
87+ # Dumping each dirty page
88+ for page_addr in malicious_pages :
89+ offset = page_addr - vma .vm_start
90+ data = proc_layer .read (page_addr , dump_size , pad = True )
91+ yield vma , f"{ vma_name } , page address: { page_addr :#x} , offset: { offset :#x} " , data , offset
92+ else :
93+ # Original behaviour - Dump the start of the region (not necessarily matching the dirty page)
94+ data = proc_layer .read (vma .vm_start , dump_size , pad = True )
95+ yield vma , vma_name , data , offset
6296
6397 def _generator (self , tasks ):
6498 # determine if we're on a 32 or 64 bit kernel
@@ -70,13 +104,15 @@ def _generator(self, tasks):
70104 for task in tasks :
71105 process_name = utility .array_to_string (task .comm )
72106
73- for vma , vma_name , data in self ._list_injections (task ):
107+ for vma , vma_name , data , offset in self ._list_injections (task ):
74108 if is_32bit_arch :
75109 architecture = "intel"
76110 else :
77111 architecture = "intel64"
78112
79- disasm = renderers .Disassembly (data , vma .vm_start , architecture )
113+ disasm = renderers .Disassembly (
114+ data , vma .vm_start + offset , architecture
115+ )
80116
81117 yield (
82118 0 ,
0 commit comments