Package Libs ::
Module libdatatype
|
|
1
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
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x13, 0x13, 0x00, 0x00, 0x13, 0x00, 0x00,
37
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40
41 0x03, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
42 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
43
44 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
45 0x03, 0x03, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
46
47 0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
48 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
49
50 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
51 0x03, 0x03, 0x03, 0x13, 0x13, 0x13, 0x13, 0x13,
52
53 0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
54 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
55
56 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
57 0x03, 0x03, 0x03, 0x13, 0x13, 0x13, 0x13, 0x00,
58
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02,
61
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02,
64
65 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02,
66 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x03, 0x02,
67
68 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00,
69 0x00, 0x02, 0x02, 0x00, 0x02, 0x00, 0x02, 0x02,
70
71 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
72 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
73
74 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
75 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
76
77 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
78 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
79
80 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00,
81 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00 ]
82
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 = ''
91 self.name = 'Data'
92
95
98
100 """
101 Return information on the object
102
103 @rtype: STRING
104 @return: Object information
105 """
106 return str(self.data)
107
109 """
110 Return object's size
111
112 @rtype: Integer
113 @return: Object's Size
114 """
115 return self.size
116
118 """
119 Return object's address
120
121 @rtype: Integer
122 @return: Object's address
123 """
124 return self.address
125
128 """ String Class """
129 Data.__init__(self, STRING, address, data, len(data) )
130 self.name = 'String'
131
133 if self.data[-1] == "\x00":
134 return self.data[0:-1]
135 else:
136 return "'%s'" % self.data
137
140 """ Unicode Class """
141 Data.__init__(self, UNICODE, address, data, len(data)*2 )
142 self.name = 'Unicode'
144 if self.data[-1] == "\x00":
145 return immutils.prettyhexprint( self.data[0:-1] )
146 else:
147 return "'%s'" % self.data
148
149
152 """ Double Linked list Class """
153 Data.__init__(self, DOUBLEL, address, data, 8)
154 self.name = 'Double Linked List'
155
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
166 """ Pointer Class """
167 Data.__init__(self, POINTER, address, data, 4 )
168 self.mem = None
169 self.name = 'Pointer'
170 self.ptype = PTR
171
174
176 return self.ptype == PTR
177
180
183
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
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
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
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()
299
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
334
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
353
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
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