Package Libs :: Module libdatatype
[hide private]
[frames] | no frames]

Source Code for Module Libs.libdatatype

  1  #!/usr/bin/env python
 
  2  """
 
  3  Immunity Discovery Data Type API for Immunity Debugger
 
  4  
 
  5  (c) Immunity, Inc. 2004-2007
 
  6  
 
  7  
 
  8  U{Immunity Inc.<http://www.immunityinc.com>} Discovery Data Type API for python
 
  9  
 
 10  
 
 11  
 
 12  """ 
 13  
 
 14  __VERSION__ = '1.1' 
 15  
 
 16  import immutils 
 17  import struct 
 18  
 
 19  MEM      = 1 
 20  DWORD    = 2 
 21  MEM_ADDR = 3 
 22  
 
 23  INT     = 0 
 24  STRING  = 1 
 25  UNICODE = 2 
 26  POINTER = 3 
 27  DOUBLEL = 4 
 28  
 
 29  PLAINASCII  = 0x01 
 30  DIACRITICAL = 0x02 
 31  RAREASCII   = 0x10 
 32  
 
 33  ctable = [ 
 
 34    # 0x00.. 0x0F (TAB, Line feed, Carriage Return)
 
 35    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
 36    0x00, 0x13, 0x13, 0x00, 0x00, 0x13, 0x00, 0x00,
 
 37    # 0x10.. 0x1F
 
 38    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
 39    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
 40    # 0x20.. 0x2F (space, punctuation, parentheses)
 
 41    0x03, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 
 42    0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 
 43    # 0x30.. 0x3F (digits, punctuation)
 
 44    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 
 45    0x03, 0x03, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
 
 46    # 0x40.. 0x4F (@, letters A..O)
 
 47    0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 
 48    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 
 49    # 0x50.. 0x5F (letters P..Z, brackets, delimiters)
 
 50    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 
 51    0x03, 0x03, 0x03, 0x13, 0x13, 0x13, 0x13, 0x13,
 
 52    # 0x60.. 0x6F (`, letters a..o)
 
 53    0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 
 54    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 
 55    # 0x70.. 0x7F (letters p..z, braces)
 
 56    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
 
 57    0x03, 0x03, 0x03, 0x13, 0x13, 0x13, 0x13, 0x00,
 
 58    # 0x80.. 0x8F
 
 59    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
 60    0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02,
 
 61    # 0x90.. 0x9F
 
 62    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
 63    0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02,
 
 64    # 0xA0.. 0xAF
 
 65    0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02,
 
 66    0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x03, 0x02,
 
 67    # 0xB0.. 0xBF
 
 68    0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00,
 
 69    0x00, 0x02, 0x02, 0x00, 0x02, 0x00, 0x02, 0x02,
 
 70    # 0xC0.. 0xCF (capital diacritical characters)
 
 71    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 
 72    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 
 73    # 0xD0.. 0xDF (capital diacritical characters)
 
 74    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
 
 75    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 
 76    # 0xE0.. 0xEF (small diacritical characters)
 
 77    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 
 78    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
 
 79    # 0xF0.. 0xFF (small diacritical characters)
 
 80    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
 
 81    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00 ] 
 82  
 
83 -class Data:
84 - def __init__(self, type, address, data = None, size = 0):
85 """ Base Data Class """ 86 self.type = type 87 self.size = size 88 self.data = data 89 self.address = address 90 self.comment = '' # for the future 91 self.name = 'Data'
92
93 - def setComment(self, comment):
94 self.comment = comment
95
96 - def setData(self, data):
97 self.data = data
98
99 - def Print(self):
100 """ 101 Return information on the object 102 103 @rtype: STRING 104 @return: Object information 105 """ 106 return str(self.data)
107
108 - def getSize(self):
109 """ 110 Return object's size 111 112 @rtype: Integer 113 @return: Object's Size 114 """ 115 return self.size
116
117 - def getAddress(self):
118 """ 119 Return object's address 120 121 @rtype: Integer 122 @return: Object's address 123 """ 124 return self.address
125
126 -class String(Data):
127 - def __init__(self, address, data):
128 """ String Class """ 129 Data.__init__(self, STRING, address, data, len(data) ) 130 self.name = 'String'
131
132 - def Print(self):
133 if self.data[-1] == "\x00": 134 return self.data[0:-1] 135 else: 136 return "'%s'" % self.data
137
138 -class Unicode(Data):
139 - def __init__(self, address, data):
140 """ Unicode Class """ 141 Data.__init__(self, UNICODE, address, data, len(data)*2 ) 142 self.name = 'Unicode'
143 - def Print(self):
144 if self.data[-1] == "\x00": 145 return immutils.prettyhexprint( self.data[0:-1] ) 146 else: 147 return "'%s'" % self.data
148 149
150 -class DoubleLinkedList(Data):
151 - def __init__(self, address, data):
152 """ Double Linked list Class """ 153 Data.__init__(self, DOUBLEL, address, data, 8) 154 self.name = 'Double Linked List'
155
156 - def Print(self):
157 return "( 0x%08x, 0x%08x )" % ( self.data[0], self.data[1] )
158 159 PTR = 0 160 FUNCTION_PTR = 1 161 DATA_PTR = 2 162 STACK_PTR = 3 163
164 -class Pointer(Data):
165 - def __init__(self, address, data):
166 """ Pointer Class """ 167 Data.__init__(self, POINTER, address, data, 4 ) 168 self.mem = None 169 self.name = 'Pointer' 170 self.ptype = PTR
171
172 - def isFunctionPointer(self):
173 return self.ptype == FUNCTION_PTR
174
175 - def isCommonPointer(self):
176 return self.ptype == PTR
177
178 - def isDataPointer(self):
179 return self.ptype == DATA_PTR
180
181 - def isStackPointer(self):
182 return self.ptype == STACK_PTR
183
184 - def Print(self):
185 mem = self.mem 186 187 if self.mem: 188 return "0x%08x in %s|%s " % (self.data, self.mem.getOwner(), self.mem.section) 189 return "0x%08x" % self.data
190
191 - def setMemPage(self, mem):
192 self.mem = mem 193 194 if self.mem: 195 196 if self.mem.section == ".text": 197 self.ptype = FUNCTION_PTR 198 self.name = 'Function Pointer:' 199 200 elif self.mem.section == ".data": 201 self.ptype = DATA_PTR 202 self.name = 'Data Pointer:'
203 204
205 -class DataTypes:
206 - def __init__(self, imm):
207 """ 208 Data Discovery Class 209 210 @type imm: Debugger Object 211 @param imm: Initialized debugged object 212 """ 213 214 self.MemPages = imm.getMemoryPages() 215 self.imm = imm 216 217 self.AllFunctions = [(self.isDoubleLinkedList, MEM), (self.isString, MEM),\ 218 (self.isUnicode, MEM), (self.isPointer, DWORD) ] 219 self.DiscoverWhat = {'all': self.AllFunctions,\ 220 'pointers': [ (self.isPointer, DWORD) ],\ 221 'strings': [(self.isString, MEM), (self.isUnicode, MEM)],\ 222 'asciistrings': [ (self.isString, MEM)],\ 223 'unicodestrings': [ (self.isUnicode, MEM) ],\ 224 'doublelinkedlists': [ (self.isDoubleLinkedList, MEM) ],\ 225 'exploitable': [ (self.isPointer, DWORD), (self.isDoubleLinkedList, MEM) ] 226 }
227
228 - def Get(self, address, size, iterate = 4, what = 'all'):
229 """ 230 Discover types on Memory Space 231 232 @type address: DWORD 233 @param address: RVA of the memory to analize 234 235 @type size: DWORD 236 @param size: Size of memory to analize 237 238 @type iterate: Integer 239 @param iterate: (Optional, Def: 4) Iterate through given bytes 240 241 @type what: STRING 242 @param what: (Optional, Def: ALL) What to search for: all, pointers, strings, asciistrings, unicodestrings, doublelinkedlists, exploitable 243 244 @rtype: List of Discovered Object 245 @return: A list of Discovered Objects 246 """ 247 248 mem = self.imm.readMemory( address, size ) 249 if not mem: 250 return [] 251 return self.Discover( mem, address, iterate, what )
252
253 - def Discover(self, mem, address, iterate = 4, what = 'all'):
254 """ 255 Discover types on Memory Space 256 257 @type mem: Buffer 258 @param mem: Memory to discover 259 260 @type address: DWORD 261 @param address: RVA of the memory 262 263 @type iterate: Integer 264 @param iterate: (Optional, Def: 4) Iterate through given bytes 265 266 @type what: STRING 267 @param what: (Optional, Def: ALL) What to search for: all, pointers, strings, asciistrings, unicodestrings, doublelinkedlists, exploitable 268 269 @rtype: List of Discovered Object 270 @return: A list of Discovered Objects 271 """ 272 # Discover types on memory space 273 ndx = 0 274 discovered = [] 275 276 try: 277 Functions = self.DiscoverWhat[ what.lower() ] 278 except KeyError: 279 return [] 280 281 while ndx < len(mem): 282 obj = None 283 #self.imm.log("Discovering... 0x%02x" % ndx, address = address + ndx) 284 for discover_func, tipo in Functions: 285 286 if tipo == MEM: 287 obj = discover_func(address + ndx, mem[ndx: ] ) 288 289 elif tipo == DWORD: 290 if len( mem[ndx:ndx+4] ) >= 4: 291 dword = struct.unpack("L", mem[ ndx : ndx+4 ] )[0] 292 obj = discover_func(address + ndx, dword ) 293 294 if obj: 295 break 296 if obj: 297 discovered.append( obj ) 298 ndx += obj.getSize() # align this address by iterate 299 # round by iterate 300 if ndx % iterate: 301 ndx = iterate + ndx & ~(iterate-1) 302 303 else: 304 ndx += iterate 305 306 return discovered
307
308 - def isUnicode(self, address, mem, max_size = 4*2):
309 ret = [] 310 for a in range(0, len(mem), 2): 311 ndx = struct.unpack("H", mem[ a: a + 2 ] )[0] 312 if ndx & 0xFF00: 313 return False 314 315 if not (ctable[ ndx & 0x00FF ] & PLAINASCII): 316 break 317 ret.append( chr( ndx & 0x00FF ) ) 318 319 if a < max_size: 320 return None 321 322 if ndx == 0x0000: 323 ret.append(" ") 324 325 return Unicode(address, "".join(ret) )
326
327 - def isString(self, address, mem, max_size = 4):
328 329 for a in range(0, len(mem)): 330 ndx = ord( mem[ a ] ) 331 if not (ctable[ ndx ] & PLAINASCII): 332 break 333 #if ( ndx < 0x20 or ndx > 0x7e) and ndx not in (0x9, 0xa, 0xd): 334 # break 335 336 if a < max_size: 337 return None 338 if ndx == 0x0: 339 a+=1 340 return String(address, mem[0 : a] )
341 342
343 - def isPointer(self, address, dword):
344 try: 345 ret = self.imm.readLong(dword) 346 except Exception: 347 return None 348 p = Pointer( address, dword ) 349 mem = self.imm.getMemoryPageByAddress(dword) 350 if mem: 351 p.setMemPage( mem ) 352 return p
353
354 - def isDoubleLinkedList(self, address, mem):
355 if len(mem) < 8: 356 return False 357 ptr1 = immutils.str2littleendian( mem[0 : 4] ) 358 ptr2 = immutils.str2littleendian( mem[4 : 8] ) 359 try: 360 ptr1_dword = self.imm.readLong( ptr1 ) 361 ptr1_dword2 = self.imm.readLong( ptr1 + 4 ) 362 ptr2_dword = self.imm.readLong( ptr2 ) 363 ptr2_dword2 = self.imm.readLong( ptr2 + 4 ) 364 except Exception: 365 return False 366 367 if (address == ptr1_dword or address == ptr1_dword2) and\ 368 (address == ptr2_dword or address == ptr2_dword2): 369 dl = DoubleLinkedList ( address, (ptr1, ptr2) ) 370 return dl 371 372 return False
373
374 - def isFormatString(self):
375 pass
376 377 378 379 if __name__ == '__main__': 380 d = DataTypes() 381 assert(d.isString("ho\nA\x01") == True) 382 assert(d.isString("\x01COCA") == False) 383