Package rekall :: Module obj_test
[frames] | no frames]

Source Code for Module rekall.obj_test

  1  import logging 
  2  import unittest 
  3   
  4  from rekall import addrspace 
  5  from rekall import obj 
  6   
  7  # Import and register all the plugins. 
  8  from rekall import plugins # pylint: disable=unused-import 
  9  from rekall import session 
 10  from rekall import testlib 
 11   
 12   
13 -class ProfileTest(testlib.RekallBaseUnitTestCase):
14 """Test the profile implementation.""" 15
16 - def setUp(self):
17 self.session = session.Session() 18 # Create an address space from a buffer for testing 19 self.address_space = addrspace.BufferAddressSpace( 20 data="hello world" * 100, session=self.session)
21
22 - def testNativeTypes(self):
23 # We build a simple profile with just the native types here. 24 profile = obj.Profile.classes['Profile32Bits'](session=self.session) 25 26 # Check that simple types work 27 self.assertEqual( 28 profile.Object("long", offset=0, vm=self.address_space), 29 0x6c6c6568) 30 31 self.assertEqual( 32 profile.Object("long long", offset=0, vm=self.address_space), 33 0x6f77206f6c6c6568)
34
35 - def testBitField(self):
36 # We build a simple profile with just the native types here. 37 profile = obj.Profile.classes['Profile32Bits'](session=self.session) 38 profile.add_types({ 39 'Test': [0x10, { 40 'Field1': [0x00, ['BitField', dict(start_bit=0, end_bit=4)]], 41 'Field2': [0x00, ['BitField', dict(start_bit=4, end_bit=8)]], 42 }]}) 43 44 test = profile.Object("Test", offset=0, vm=self.address_space) 45 46 bf1 = test.Field1 47 bf2 = test.Field2 48 49 self.assertEqual(bf1, 8) 50 self.assertEqual(bf2, 6) 51 52 # Check for overloaded numeric methods. 53 self.assertEqual(bf1 + 1, 9) 54 self.assertEqual(bf1 - 1, 7) 55 self.assertEqual(bf1 + bf2, 8 + 6) 56 self.assertEqual(bf1 < bf2, 8 < 6) 57 self.assertEqual(bf1 > bf2, 8 > 6) 58 self.assertEqual(bf1 & bf2, 8 & 6) 59 self.assertEqual(bf1 ^ bf2, 8 ^ 6) 60 self.assertEqual(bf1 + 6, 8 + bf2) 61 self.assertEqual(bf1 < 6, 8 < bf2) 62 self.assertEqual(bf1 > 6, 8 > bf2) 63 self.assertEqual(bf1 & 6, 8 & bf2) 64 self.assertEqual(bf1 ^ 6, 8 ^ bf2)
65
66 - def testPointer(self):
67 # Create an address space from a buffer for testing 68 address_space = addrspace.BufferAddressSpace( 69 data="\x08\x00\x00\x00\x00\x00\x00\x00" 70 "\x66\x55\x44\x33\x00\x00\x00\x00" 71 "\x99\x88\x77\x66\x55\x44\x33\x22", session=self.session) 72 73 vtype = {'Test': [0x10, { 74 # Check simple type dereferencing 75 'ptr32': [0x00, ['Pointer', dict( 76 target='unsigned long' 77 )]], 78 'ptr64': [0x00, ['Pointer', dict( 79 target='long long' 80 )]], 81 82 # Check struct dereferencing 83 'next': [0x00, ['Pointer', dict( 84 target='Test' 85 )]], 86 87 # A pointer to an invalid location 88 'invalid': [0x08, ['Pointer', dict( 89 target='long' 90 )]], 91 92 # A void pointer 93 'void': [0x00, ['Pointer', dict( 94 target='Void' 95 )]], 96 }]} 97 98 # We build a simple profile with just the native types here. 99 profile = obj.Profile.classes['Profile32Bits'](session=self.session) 100 profile.add_types(vtype) 101 102 test = profile.Object("Test", offset=0, vm=address_space) 103 104 ptr = test.ptr32 105 106 # Can we check the offset of members? 107 self.assertEqual(profile.get_obj_offset("Test", "invalid"), 8) 108 109 # 32 bit pointers. 110 self.assertEqual(ptr.obj_size, 4) 111 112 # The pointer itself is at location 0. 113 self.assertEqual(ptr.obj_offset, 0) 114 115 # But is pointing to location 8. 116 self.assertEqual(ptr.v(), 8) 117 self.assertEqual(int(ptr), 8) 118 self.assertEqual(ptr, 8) 119 120 # The long is the next 8 bytes. 121 self.assertEqual(ptr.dereference(), 0x33445566) 122 123 # Pointer comparison 124 self.assertEqual(test.ptr32, test.ptr64) 125 126 # We could do pointer arithmetic. 127 ptr2 = ptr + 2 128 129 # The new pointer is at location 8 (its 32 bits). 130 self.assertEqual(ptr2.obj_offset, 8) 131 132 # The pointer to long long is moving twice as fast 133 self.assertEqual(test.ptr64 + 1, 0x33445566) 134 self.assertEqual(test.ptr32 + 1, 0) 135 136 # And its pointing to. 137 self.assertEqual(ptr2.v(), 0x33445566) 138 139 # The above makes the pointer invalid, so dereferencing it returns a 0. 140 # (This is because there is no good way to validate pages except at 141 # system runtime.) 142 self.assertEqual(ptr2.dereference(), 0) 143 144 # This is also invalid and will return a zero. 145 self.assertEqual(test.invalid.dereference(), 0) 146 147 # Test nonzero. 148 self.assert_(test.ptr32) 149 150 # Now dereference a struct. 151 ptr3 = test.next 152 153 # This struct starts at offset 8. 154 self.assertEqual(test.next.v(), 8) 155 156 next = ptr3.dereference() 157 158 # We get another struct from this. 159 self.assertEqual(next.obj_type, "Test") 160 161 # This new struct's ptr32 is pointing at this address now. 162 self.assertEqual(next.ptr32, 0x33445566) 163 164 # Now test 64 bit pointers. 165 profile = obj.Profile.classes['ProfileLLP64'](session=self.session) 166 profile.add_types(vtype) 167 168 test = profile.Object("Test", offset=0, vm=address_space) 169 170 ptr = test.ptr32 171 172 # 64 bit pointers. 173 self.assertEqual(ptr.obj_size, 8) 174 175 # The pointer itself is at location 0. 176 self.assertEqual(ptr.obj_offset, 0) 177 178 # But is pointing to location 8. 179 self.assertEqual(ptr.v(), 8) 180 181 # The long is the next 8 bytes. 182 self.assertEqual(ptr.dereference(), 0x33445566) 183 184 # We could do pointer arithmetic. 185 ptr2 = ptr + 2 186 187 # This will advance the pointer by 8 bytes (still pointer to long). 188 self.assertEqual(ptr2.obj_offset, 8) 189 self.assertEqual(ptr2, 0x33445566) 190 191 # NOTE: We assume that long is 32 bits wide in both 64 bits and 32 bits 192 # mode - which is the way windows does it. This is not the same as linux 193 # which has long being the bit size in both cases. 194 195 # Test the void pointer 196 self.assertEqual(test.void, 8) 197 198 # A Void object can not be compared to anything! 199 self.assertNotEqual(test.void.dereference(), 0x33445566)
200
201 - def testArray(self):
202 # Create an address space from a buffer for testing 203 address_space = addrspace.BufferAddressSpace( 204 data="abcdefghijklmnopqrstuvwxyz", session=self.session) 205 206 profile = obj.Profile.classes['Profile32Bits'](session=self.session) 207 test = profile.Object("Array", vm=address_space, offset=0, 208 target="int", count=0) 209 210 self.assertEqual(test[0], 0x64636261) 211 self.assertEqual(test[1], 0x68676665) 212 213 # Can read past the end of the array but this returns all zeros. 214 self.assertEqual(test[100], 0)
215 216 217 if __name__ == "__main__": 218 logging.basicConfig(level=logging.DEBUG) 219 unittest.main() 220