Package rekall :: Package plugins :: Package windows :: Package malware :: Module timers
[frames] | no frames]

Source Code for Module rekall.plugins.windows.malware.timers

  1  # Rekall Memory Forensics 
  2  # Copyright (c) 2010, 2011, 2012 Michael Ligh <michael.ligh@mnin.org> 
  3  # Copyright 2013 Google Inc. All Rights Reserved. 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 2 of the License, or (at 
  8  # your option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, but 
 11  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 13  # General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with this program; if not, write to the Free Software 
 17  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 18  # 
 19  from rekall.plugins.windows import common 
 20  from rekall_lib import utils 
 21   
 22  # pylint: disable=protected-access 
 23   
 24  #References: 
 25  # http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/a-performance-issue-in-windows-timer-management/ 
 26   
 27   
28 -class Timers(common.WindowsCommandPlugin):
29 """Print kernel timers and associated module DPCs. 30 31 Ref: 32 http://computer.forensikblog.de/en/2011/10/timers-and-times.html 33 """ 34 35 __name = "timers" 36 37 table_header = [ 38 dict(name="Tbl", align="r", width=3), 39 dict(name="_KTIMER", style="address"), 40 dict(name="due", width=22), 41 dict(name="due_time", width=24), 42 dict(name="period", width=11, align="r"), 43 dict(name="sig", align="r", width=4), 44 dict(name="routine", style="address"), 45 dict(name="symbol") 46 ] 47 48
49 - def _timers(self):
50 if self.profile.get_constant("KiTimerTableListHead"): 51 # On XP x64, Windows 2003 SP1-SP2, and Vista SP0-SP2, 52 # KiTimerTableListHead is an array of 512 _KTIMER_TABLE_ENTRY 53 # structs. 54 if self.profile.has_type("_KTIMER_TABLE_ENTRY"): 55 lists = self.profile.get_constant_object( 56 "KiTimerTableListHead", 57 target="Array", 58 target_args=dict( 59 target='_KTIMER_TABLE_ENTRY', 60 count=512) 61 ) 62 63 for i, l in enumerate(lists): 64 for t in l.Entry.list_of_type("_KTIMER", "TimerListEntry"): 65 yield i, t 66 67 else: 68 # On XP SP0-SP3 x86 and Windows 2003 SP0, KiTimerTableListHead 69 # is an array of 256 _LIST_ENTRY for _KTIMERs. 70 lists = self.profile.get_constant_object( 71 "KiTimerTableListHead", 72 target="Array", 73 target_args=dict( 74 target='_LIST_ENTRY', 75 count=256) 76 ) 77 78 for i, l in enumerate(lists): 79 for t in l.list_of_type_fast("_KTIMER", "TimerListEntry"): 80 yield i, t 81 else: 82 # On Windows 7, there is no more KiTimerTableListHead. The list is 83 # at _KPCR.PrcbData.TimerTable.TimerEntries (credits to Matt Suiche 84 # for this one. See http://pastebin.com/FiRsGW3f). 85 kpcr = self.session.plugins.kpcr().kpcr() 86 for i, table in enumerate(kpcr.Prcb.TimerTable.TimerEntries): 87 self.session.report_progress("Table %r", table) 88 for t in table.Entry.list_of_type_fast( 89 "_KTIMER", "TimerListEntry"): 90 yield i, t
91
92 - def timers(self):
93 """A generator of timer objects.""" 94 # Sort the timers by address to make them easier to inspect. 95 for i, timer in self._timers(): 96 # This is the code from reactos which checks for this: 97 # #define ASSERT_TIMER(E) \ 98 # NT_ASSERT(((E)->Header.Type == TimerNotificationObject) || \ 99 # ((E)->Header.Type == TimerSynchronizationObject)) 100 if timer.Header.Type not in ["TimerNotificationObject", 101 "TimerNotificationObject"]: 102 continue 103 104 self.session.report_progress("Looking at %#x", timer) 105 106 # Ignore timers without DPCs 107 if (not timer.Dpc.is_valid() or 108 not timer.Dpc.DeferredRoutine.is_valid()): 109 continue 110 111 yield i, timer
112
113 - def collect(self):
114 # Print kuser_shared things. 115 kuser_shared = self.profile.get_constant_object( 116 "KI_USER_SHARED_DATA", "_KUSER_SHARED_DATA") 117 118 interrupt_time = ((kuser_shared.InterruptTime.High1Time << 32) + 119 kuser_shared.InterruptTime.LowPart) 120 now = kuser_shared.SystemTime.as_windows_timestamp() - interrupt_time 121 seen = set() 122 123 for i, timer in self.timers(): 124 if timer in seen: 125 continue 126 127 seen.add(timer) 128 129 if timer.Header.SignalState.v(): 130 signaled = "Yes" 131 else: 132 signaled = "-" 133 134 yield dict(Tbl=i, 135 _KTIMER=timer, 136 # Due time in InterruptTime (100ns). 137 due="0x%0.20x" % timer.DueTime.QuadPart, 138 due_time=self.profile.WinFileTime( 139 value=now+timer.DueTime.QuadPart, 140 is_utc=True), 141 period=timer.Period, 142 sig=signaled, 143 routine=timer.Dpc.DeferredRoutine, 144 symbol=utils.FormattedAddress( 145 self.session.address_resolver, 146 timer.Dpc.DeferredRoutine) 147 )
148