| Home | Trees | Indices | Help |
|
|---|
|
|
1 '''
2 PeachValidator GUI
3
4 @author: Michael Eddington
5 @version: $Id$
6 '''
7
8 #
9 # Copyright (c) 2008 Michael Eddington
10 #
11 # Permission is hereby granted, free of charge, to any person obtaining a copy
12 # of this software and associated documentation files (the "Software"), to deal
13 # in the Software without restriction, including without limitation the rights
14 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 # copies of the Software, and to permit persons to whom the Software is
16 # furnished to do so, subject to the following conditions:
17 #
18 # The above copyright notice and this permission notice shall be included in
19 # all copies or substantial portions of the Software.
20 #
21 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 # SOFTWARE.
28 #
29
30 # Authors:
31 # Michael Eddington (mike@phed.org)
32
33 # $Id$
34
35 import sys, os
36 sys.path.append("../..")
37 sys.path.append(os.getcwd() + "\\..\\..\\")
38
39 try:
40 import Ft.Xml.Domlette
41 from Ft.Xml.Domlette import *
42 from Ft.Xml.Catalog import GetDefaultCatalog
43 from Ft.Xml.InputSource import InputSourceFactory
44 from Ft.Lib.Resolvers import SchemeRegistryResolver
45 from Ft.Lib import Uri
46
47 except:
48 print "\nError loading 4Suite XML library. This library"
49 print "can be installed from the dependencies folder or"
50 print "downloaded from http://4suite.org/.\n\n"
51 raise
52
53 import gui
54 import wx
55 import wx.propgrid as wxpg
56 import re, pickle
57
58 from Peach.Engine import parser, engine, incoming, dom
59 from Peach.Engine.dom import *
60 import Peach
61 #import Peach.Gui
62
64
66 self.title = "Peach Validation - %s"
67 gui.PeachValidation.__init__(self, None, -1, "")
68
69 self._lastXmlFile = ""
70 self._lastBinFile = ""
71 self._lastPath = "/"
72
73 self.LoadState()
74
75 # Set values
76 self.textFilename.SetValue(self._lastBinFile)
77 self.textPeachXmlFilename.SetValue(self._lastXmlFile)
78
79 self.mutateObj = None
80
81 wx.EVT_CLOSE(self, self.OnClose)
82
83 # Disable controls that shouldn't be used yet
84
85 self.buttonGenerate.Disable()
86 self.comboMutator.Disable()
87 self.textFilename.Disable()
88 self.buttonBrowse.Disable()
89 self.buttonLoad.Disable()
90
91 # Create Tree image list
92 self.treeImages = wx.ImageList(16,16)
93 self.treeImages.NodeTemplate= self.treeImages.Add(wx.Bitmap("icons\\node-template.png", wx.BITMAP_TYPE_ANY))
94 self.treeImages.NodeBlock = self.treeImages.Add(wx.Bitmap("icons\\node-block.png", wx.BITMAP_TYPE_ANY))
95 self.treeImages.NodeChoice = self.treeImages.Add(wx.Bitmap("icons\\node-choice.png", wx.BITMAP_TYPE_ANY))
96 self.treeImages.NodeFlags = self.treeImages.Add(wx.Bitmap("icons\\node-flags.png", wx.BITMAP_TYPE_ANY))
97 self.treeImages.NodeNumber = self.treeImages.Add(wx.Bitmap("icons\\node-number.png", wx.BITMAP_TYPE_ANY))
98 self.treeImages.NodeString = self.treeImages.Add(wx.Bitmap("icons\\node-string.png", wx.BITMAP_TYPE_ANY))
99 self.treeImages.NodeUnknown = self.treeImages.Add(wx.Bitmap("icons\\node-unknown.png", wx.BITMAP_TYPE_ANY))
100 self.treeImages.NodeBlob = self.treeImages.Add(wx.Bitmap("icons\\node-blob.png", wx.BITMAP_TYPE_ANY))
101 self.treeImages.NodeError = self.treeImages.Add(wx.Bitmap("icons\\node-error.png", wx.BITMAP_TYPE_ANY))
102
103 self.ImageLookup = {'block':self.treeImages.NodeBlock,
104 'choice':self.treeImages.NodeChoice,
105 'flags':self.treeImages.NodeFlags,
106 'flag':self.treeImages.NodeFlags,
107 'number':self.treeImages.NodeNumber,
108 'string':self.treeImages.NodeString,
109 'blob':self.treeImages.NodeBlob,
110 'template':self.treeImages.NodeTemplate,
111 }
112
113 self.root = self.treeDataTree.AddRoot("Peach")
114 self.treeDataTree.SetImageList(self.treeImages)
115 self.treeDataTree.SetItemImage(self.root, self.treeImages.NodeTemplate)
116
117 # Adjust size of tree
118 self.SetSize(wx.Size(600, 600))
119 width, height = self.GetSizeTuple()
120 self.splitterTopBottom.SetSashPosition(height * 0.25, True)
121 self.splitterRightLeft.SetSashPosition(width * 0.35, True)
122
123 self.treeDataTree.SelectItem(self.root, True)
124 self.treeDataTree.Expand(self.root)
125
129
131 '''
132 Save out our state
133 '''
134
135 state = [self._lastXmlFile, self._lastBinFile, self._lastPath]
136
137 fd = open(os.path.join(Peach.Gui.__path__[0], "peachvalidator.state"), "wb+")
138 fd.write(pickle.dumps(state))
139 fd.close()
140
142 '''
143 Load our state if it exists
144 '''
145
146 try:
147 fd = open(os.path.join(Peach.Gui.__path__[0], "peachvalidator.state"), "rb")
148 state = pickle.loads(fd.read())
149 fd.close()
150
151 self._lastXmlFile = state[0]
152 self._lastBinFile = state[1]
153 self._lastPath = state[2]
154 except:
155 pass
156
157
159 #print "Event handler `OnButtonBrowse' not implemented!"
160 event.Skip()
161
162 dlg = wx.FileDialog(self, 'Choose a file to open', self._lastPath, self._lastBinFile, '*.*', wx.OPEN)
163 if dlg.ShowModal() != wx.ID_OK:
164 dlg.Destroy()
165 return
166
167 fileName = dlg.GetPath()
168 self._lastBinFile = fileName
169 self._lastPath = fileName[:fileName.rfind(os.path.pathsep)]
170 dlg.Destroy()
171 self.textFilename.SetValue(fileName)
172
174 event.Skip()
175
176 self.treeDataTree.DeleteChildren(self.root)
177 self.treeDataTree.SetItemImage(self.root, self.treeImages.NodeTemplate)
178
179 self.p = parser.ParseTemplate()
180 self.peach = self.p.parse("file:"+ self.textPeachXmlFilename.GetValue())
181
182 # Locate all templates and toss into combo
183 self.comboDataModel.Clear()
184 self.mutators = {}
185 for n in self.peach:
186 if n.elementType == 'template':
187 self.comboDataModel.Append(n.name)
188 self.comboDataModel.SetValue(n.name)
189
190 elif n.elementType == 'test':
191 for m in n.mutators:
192 if m.name not in self.mutators.keys():
193 self.mutators[m.name] = m
194
195 # Populate Mutator drop-down
196
197 self.comboMutator.Clear()
198 for m in self.mutators.keys():
199 self.comboMutator.Append(m)
200 self.comboMutator.SetValue(m)
201
202 # Enable controls that shouldn't be used yet
203
204 self.buttonGenerate.Disable()
205 self.comboMutator.Disable()
206 self.textFilename.Enable()
207 self.buttonBrowse.Enable()
208 self.buttonLoad.Enable()
209
211 #print "Event handler `OnComboDataModel' not implemented!"
212 event.Skip()
213
215 event.Skip()
216
217 self.treeDataTree.DeleteChildren(self.root)
218 self.treeDataTree.SetItemImage(self.root, self.treeImages.NodeTemplate)
219
220 fd = open(self.textFilename.GetValue(), "rb")
221 data = fd.read()
222 fd.close()
223
224 # Locate a template to use
225 self.template = None
226 for n in self.peach:
227 if n.elementType == 'template' and n.name == self.comboDataModel.GetValue():
228 self.template = n
229 break
230
231 if self.template == None:
232 raise Exception("Couldn't locate template, suck!")
233
234 try:
235 cracker = incoming.DataCracker(self.peach)
236 cracker.haveAllData = True
237 self.template = self.template.copy(None)
238 (rating, pos) = cracker.crackData(self.template, data)
239 if pos < len(data)-1:
240 # not everything was parsed!
241 self.treeDataTree.SetItemImage(self.root, self.treeImages.NodeError)
242
243 # TODO: Display error dialog
244 except:
245 self.treeDataTree.SetItemImage(self.root, self.treeImages.NodeError)
246
247 # Build tree
248 self.BuildTree(self.template)
249
250 self.buttonGenerate.Enable()
251 self.comboMutator.Enable()
252
254 self.treeDataTree.Freeze()
255
256 self.treeDataTree.SetPyData(self.root, template)
257 for child in template:
258 self.AddNodeToTree(self.root, child)
259
260 self.treeDataTree.Thaw()
261 self.treeDataTree.Expand(self.root)
262 self.treeDataTree.SelectItem(self.root, True)
263
265 event.Skip()
266
267 # Look at our junk and output some cool stuff
268 # to the text box.
269 itemId = event.GetItem()
270 node = self.treeDataTree.GetPyData(itemId)
271
272 if node == None:
273 return
274
275 value = "%s is a %s element type\n" % (node.name, node.elementType)
276 value += "="*(len(value)-1)
277 value += "\n\n"
278
279 if hasattr(node, 'pos') and hasattr(node, 'rating') and node.pos != None:
280 value += "DataElement.pos = %d\n" % node.pos
281 value += "DataElement.rating = %d\n" % node.rating
282
283 else:
284 value += "Warning: We did not reach, or crack this element!!\n\n"
285
286 if node.elementType == 'string':
287 if node.length != None:
288 value += "String.length: %d\n" % node.length
289 else:
290 value += "String.length: Unknown\n"
291
292 value += "String.nullTerminated: %s\n" % str(node.nullTerminated)
293 value += "String.type: %s\n" % node.type
294 value += "String.padCharacter: %s\n" % repr(node.padCharacter)
295
296 if node.defaultValue != None:
297 value += "String.defaultValue: %s\n" % repr(node.defaultValue)
298 else:
299 value += "String.defaultValue: None\n"
300 value += "\n"
301
302 elif node.elementType == 'number':
303 value += "Number.size: %d\n" % node.size
304 value += "Number.endian: %s\n" % node.endian
305 value += "Number.signed: %s\n" % str(node.signed)
306
307 if node.defaultValue != None:
308 value += "Number.defaultValue: %d\n" % int(node.defaultValue)
309 else:
310 value += "Number.defaultValue: None\n"
311 value += "\n"
312
313 elif node.elementType == 'flags':
314 value += "Flags.size: %d\n" % node.length
315 value += "Flags.endian: %s\n" % node.endian
316 value += "\n"
317
318 elif node.elementType == 'flag':
319 value += "Flag.size: %d\n" % node.length
320 value += "Flag.position: %d\n" % node.position
321
322 if node.defaultValue != None:
323 value += "Flag.defaultValue: %d\n" % int(node.defaultValue)
324 else:
325 value += "Flag.defaultValue: None\n"
326 value += "\n"
327
328 elif node.elementType == 'block':
329 pass
330
331 elif node.elementType == 'blob':
332 if node.length != None:
333 value += "Blob.length: %d\n" % node.length
334 else:
335 value += "Blob.length: Unknown\n"
336
337 if node.defaultValue != None:
338 value += "Blob.defaultValue: %s\n" % repr(node.defaultValue)
339 else:
340 value += "Blob.defaultValue: None\n"
341 value += "\n"
342
343 nodeInternal = None
344 nodeValue = None
345
346 try:
347 if node.currentValue != None:
348 nodeInternal = node.currentValue
349 nodeValue = node.getValue()
350 else:
351 nodeInternal = None
352 nodeValue = node.getValue()
353
354 except:
355 pass
356
357 if nodeInternal != None:
358 value += "Internal value: (%d bytes)\n%s\n\n\n" % (len(nodeInternal), repr(nodeInternal))
359 else:
360 value += "Internal value: None\n\n"
361
362 if nodeValue != None:
363 value += "Output value: (%d bytes)\n%s\n\n\n" % (len(nodeValue), repr(nodeValue))
364
365 length = len(nodeValue)
366 if length >= 100:
367 length = 50
368 spaces = '3'
369 elif length >= 10:
370 spaces = '2'
371 else:
372 spaces = ''
373
374 for i in range(length):
375 value += ("[%" + spaces + "d]: %s: %s\n") % (i, hex(ord(nodeValue[i])), repr(nodeValue[i]))
376
377 if length < len(nodeValue):
378 value += ".\n.\n.\n"
379
380 for i in range(len(nodeValue)-10, len(nodeValue)):
381 value += ("[%" + spaces + "d]: %s: %s\n") % (i, hex(ord(nodeValue[i])), repr(nodeValue[i]))
382 else:
383 value += "Output value: None\n\n"
384
385 self.textOutput.SetValue(value)
386
388 '''
389 Add a node to the tree. Adds the children of this node as well!
390
391 NOTE: This only builds the tree and links the tree item to the
392 node object.
393 '''
394
395 if not isinstance(node, DataElement):
396 return
397
398 id = self.treeDataTree.AppendItem(parentId, node.name)
399 self.treeDataTree.SetPyData(id, node)
400
401 try:
402 self.treeDataTree.SetItemImage(id, self.ImageLookup[node.elementType])
403
404 except:
405 raise Exception("Unknown element type: ", node.elementType)
406
407 try:
408 value = node.getValue()
409
410 except:
411 self.treeDataTree.SetItemImage(id, self.treeImages.NodeError)
412
413 if not hasattr(node, 'pos') or not hasattr(node, 'rating'):
414 self.treeDataTree.SetItemImage(id, self.treeImages.NodeError)
415
416 for child in node._children:
417 self.AddNodeToTree(id, child)
418
419 return id
420
422 #print "Event handler `OnButtonPeachFileBrowse' not implemented!"
423 event.Skip()
424
425 dlg = wx.FileDialog(self, 'Choose a Peach XML file to open', self._lastPath, self._lastXmlFile, '*.xml', wx.OPEN)
426 if dlg.ShowModal() != wx.ID_OK:
427 dlg.Destroy()
428 return
429
430 fileName = dlg.GetPath()
431 self._lastXmlFile = fileName
432 self._lastPath = fileName[:fileName.rfind(os.path.pathsep)]
433
434 dlg.Destroy()
435 self.textPeachXmlFilename.SetValue(fileName)
436
438 #print "Event handler `OnButtonGenerate' not implemented!"
439 event.Skip()
440
441 if self.mutateObj == None:
442 self.mutateObj = dom.Action('Mutation', None)
443 self.mutateObj.origionalTemplate = self.template
444
445 # Mutate
446
447 self.mutateObj.template = self.mutateObj.origionalTemplate.copy(self.mutateObj)
448 self.mutators[self.comboMutator.GetValue()].mutator.getActionValue(self.mutateObj)
449 try:
450 self.mutators[self.comboMutator.GetValue()].mutator.next()
451
452 # Build tree
453 self.treeDataTree.DeleteChildren(self.root)
454 self.treeDataTree.SetItemImage(self.root, self.treeImages.NodeTemplate)
455 self.BuildTree(self.mutateObj.template)
456 except:
457 wx.MessageBox('Mutator Completed', 'Info')
458
460 app = wx.PySimpleApp(0)
461 wx.InitAllImageHandlers()
462 peachMain = PeachValidatorGui()
463 app.SetTopWindow(peachMain)
464 peachMain.Show()
465 app.MainLoop()
466
467 if __name__ == "__main__":
468 RunPeachValidator()
469
470 # end
471
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Aug 16 12:17:18 2008 | http://epydoc.sourceforge.net |