<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4375640005424015695</id><updated>2011-08-02T13:44:09.335-07:00</updated><category term='pyflag'/><title type='text'>Scudette in Wonderland</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://scudette.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://scudette.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Scudette</name><uri>http://www.blogger.com/profile/00290957716409467236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4375640005424015695.post-4021944386241737906</id><published>2010-02-28T17:26:00.001-08:00</published><updated>2010-02-28T17:33:29.030-08:00</updated><title type='text'>googledoc2latex</title><content type='html'>So I have just finished my DFRWS paper submission - what a rush!!!&lt;br /&gt;&lt;br /&gt;This year we decided to use google docs for collaborating between the authors. Google docs is a great collaborative tool because it allows everyone to edit the document at the same time. There is also a perfectly adequate but simple diagram drawing tool.&lt;br /&gt;&lt;br /&gt;Unfortunately the formatting capabilities of google doc do not compare to latex (no word processor can really). What we wanted is a quick way to convert to latex for final proofing but for the document to be as intuitive as possible.&lt;br /&gt;&lt;br /&gt;So I wipped together a quick script to convert the google doc into latex. Simple formatting available on google doc will be converted to some simple latex formatting but you can write any latex commands within the google doc for fine level control.&lt;br /&gt;&lt;br /&gt;I thought this was such a useful thing that I quickly put it up on google code for others to share - no guarantee of how good this is.&lt;br /&gt;&lt;br /&gt;http://code.google.com/p/googledoc2latex/wiki/Usage&lt;br /&gt;&lt;br /&gt;Hopefully this can be refined further - but i think the idea is great. Edit a somewhat WYSIWYG collaborative document like google doc, and still produce publication quality product.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375640005424015695-4021944386241737906?l=scudette.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scudette.blogspot.com/feeds/4021944386241737906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375640005424015695&amp;postID=4021944386241737906' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/4021944386241737906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/4021944386241737906'/><link rel='alternate' type='text/html' href='http://scudette.blogspot.com/2010/02/googledoc2latex.html' title='googledoc2latex'/><author><name>Scudette</name><uri>http://www.blogger.com/profile/00290957716409467236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4375640005424015695.post-6003001105205762440</id><published>2010-02-18T01:50:00.000-08:00</published><updated>2010-02-18T02:43:03.097-08:00</updated><title type='text'>Treaps - Best data structure since sliced bread</title><content type='html'>I will be the first to admit that data structures are not my strong point. The wonderful thing about data structures is that once someone shows you how one works - its easy to understand, but trying to do something with the wrong data structure is a performance killer.&lt;br /&gt;&lt;br /&gt;While updating the AFF4 map implementation I had a requirement for a unique data structure. First a quick recap of the AFF4 map implementation. AFF4 maps are a list of points which specify a linear transormation between the map stream and one or more backing streams (which may be maps or images or whatever). For example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;map stream offset, target offset, target URL&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;0,100,file:///file1.dd&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;500,1000,file:///file2.dd&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;800,2123,file:///file3.dd&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This means that data in the map stream from offset 0 to 500 will be take from offset 100 to 600 in file://file1.dd. From byte 500 to 800, the data will be taken from offset 1000 to 1300 in file2.dd etc.&lt;br /&gt;&lt;br /&gt;In order to satisfy a read request at a specific offset we need to quickly search the map for the two elements immediately before and after the offset. For example if I want to read 100 bytes from offset 450 in the map stream, I need to find row 1 and row 2 above:&lt;br /&gt;&lt;br /&gt;Before:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;0,100,file:///file1.dd&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;500,1000,file:///file2.dd&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I then extrapolate the target offset and realise that I only have 50 bytes available from offset 100 + 450 = 550 in file1.dd.&lt;br /&gt;&lt;br /&gt;When the map is huge the speed of this search is very important. The interesting thing is that I will rarely need an exact match - I really need a range.&lt;br /&gt;&lt;br /&gt;My initial implementation used a sorted list for the map, sorted by the stream offset. I then did a binary search for the stream offset and retreived the index before and after the final point. Binary searching is O(lg N) and storage efficiency is excellent - no overhead is requires as the array can simply be allocated at once.&lt;br /&gt;&lt;br /&gt;The biggest problem with this approach is that it is not possible to add points to the map at the same time as reading them. This is because the array needs to be sorted before you can binary search it. If we just add all the elements in batch and then sort we can get away with O(1) on adding and then O(n) for the sort. There are a number of applications, however, where we need to be able to read the map while we are writing it. In particular whenever we need to know if a point is already present in the map, before adding a new one we need to sort it first. Sorting upon each insertion will result in O(n lg n) for insertion which is very poor.&lt;br /&gt;&lt;br /&gt;So I needed a data structure which:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;At least O(lg N) on retrieval&lt;/li&gt;&lt;li&gt;Better than O(n log n) on insertion.&lt;/li&gt;&lt;li&gt;Reasonably efficient for sorting.&lt;/li&gt;&lt;li&gt;Most importantly it has to be a data structure which can retrieve the nearest match rather than an exact match. We need to be able to identify the highest offset below the query point, and the lowest offset above the query point.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;A treap http://en.wikipedia.org/wiki/Treap is the perfect solution:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It has O(lg n) on insertion and retrieval&lt;/li&gt;&lt;li&gt;Its possible to do a previous search and next search to retrieve the elements which are before and after the query point. This gives us direct ranging.&lt;/li&gt;&lt;li&gt;The treap is already sorted - to dump a sorted list, just traverse the treap in forward order.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Reading the wikipedia page above made my head spin. Implementing one would be tricky. Luckily I found this http://www.canonware.com/trp/ - Awesome.&lt;br /&gt;&lt;br /&gt;How to actually use it?&lt;br /&gt;&lt;br /&gt;The .h file defines a bunch of macros (huge macros I might add) which implement the basic functions required for a treap implementation. I guess this is kind of like c++ templates - the idea is to have the macros define the algorithm and fit it to any struct you need.&lt;br /&gt;&lt;br /&gt;So there are two major structures a tree_t struct (the names are settable as args to the macro), and a node_t struct. The node carries whatever information you want to store in each node, while the tree just stores the head of the treap (and is used in all operations on the treap).&lt;br /&gt;&lt;br /&gt;You start off by defining the node:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;typedef struct map_point_node_s map_point_node_t;&lt;br /&gt;struct map_point_node_s {&lt;br /&gt;     uint64_t image_offset;&lt;br /&gt;     uint64_t target_offset;&lt;br /&gt;     // This is a pointer into the target list (i.e. its not unique to&lt;br /&gt;     // this node).&lt;br /&gt;    RDFURN target;&lt;br /&gt;&lt;br /&gt;     // The link is what makes this node part of the tree.&lt;br /&gt;     trp_node(map_point_node_t) link;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// This just defines the tree type.&lt;br /&gt;typedef trp(map_point_node_t) map_point_tree_t;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Inside our C file we now just generate all the functions we need to manipulate the tree. We need to define a comparison function so the implementation can order elements in the tree. The comparison function is called on two nodes to decide if they are the same or one is bigger than the other. In our case we only care about the stream offsets:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;static int map_point_cmp(map_point_node_t *a, map_point_node_t *b) {&lt;br /&gt;        int rVal = (a-&gt;image_offset &gt; b-&gt;image_offset) -  \&lt;br /&gt;                      (a-&gt;image_offset &lt;&gt;image_offset);&lt;br /&gt;&lt;br /&gt;       return rVal;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* This huge macro generates all the tree tranversal and searching&lt;br /&gt;  functions.&lt;br /&gt;*/&lt;br /&gt;trp_gen(static, tree_, map_point_tree_t, map_point_node_t, \&lt;br /&gt;       link, map_point_cmp, 1297, 1301);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In other words it will make static functions like tree_insert(), tree_remove(), tree_search() etc. Note that the macros do not manage memory at all, they just maintain the pointers to each node. This means you still need to worry about allocating and deleting individual nodes - you might want to allocate a slab for a bunch of nodes or allocate each node separately.&lt;br /&gt;&lt;br /&gt;Now to use the functions:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Statically allocate a tree&lt;br /&gt;map_point_tree_t tree;&lt;br /&gt;&lt;br /&gt;// Initialise it&lt;br /&gt;tree_new(&amp;amp;tree, 42);&lt;br /&gt;&lt;br /&gt;// Make a new node&lt;br /&gt;map_point_node_t *node = calloc(sizeof(map_point_node_t));&lt;br /&gt;&lt;br /&gt;//set the key:&lt;br /&gt;node-&gt;stream_offset = 5;&lt;br /&gt;&lt;br /&gt;// add it&lt;br /&gt;tree_add(&amp;amp;tree, node);&lt;br /&gt;&lt;br /&gt;// retrieve it - we make a static node, fill it with the key and then search for the node in the tree which matches it:&lt;br /&gt;{&lt;br /&gt;   map_point_node_t query;&lt;br /&gt;&lt;br /&gt;   query.stream_offset = 5;&lt;br /&gt;    // This will be NULL if the query is not in the tree&lt;br /&gt;   node = tree_search(&amp;amp;tree, &amp;amp;query);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can also do tree_nsearch() and tree_psearch() to retrieve the nodes before and after this one.&lt;br /&gt;&lt;br /&gt;To dump the tree in sorted order we define an iterator function callback and run it on all the tree:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;static map_point_node_t *inline_map_iterate_cb(map_point_tree_t *tree, map_point_node_t *node, void *data) {&lt;br /&gt;     printf("%llu\n",node-&gt;stream_offset);&lt;br /&gt;     return NULL;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;then (data is a pointer passed to the callback):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;tree_iter(&amp;amp;tree, NULL, inline_map_iterate_cb, (void *)data);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Thats it.&lt;br /&gt;&lt;br /&gt;This can be used very easily to build a fast data tree as well - making it an awesome substitute for a hash table or a dictionary. Even when we just want to store a bunch of items by a key.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375640005424015695-6003001105205762440?l=scudette.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scudette.blogspot.com/feeds/6003001105205762440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375640005424015695&amp;postID=6003001105205762440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/6003001105205762440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/6003001105205762440'/><link rel='alternate' type='text/html' href='http://scudette.blogspot.com/2010/02/treaps-best-data-structure-since-sliced.html' title='Treaps - Best data structure since sliced bread'/><author><name>Scudette</name><uri>http://www.blogger.com/profile/00290957716409467236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4375640005424015695.post-5588835016464295071</id><published>2009-07-21T19:35:00.001-07:00</published><updated>2009-07-21T19:38:06.239-07:00</updated><title type='text'>screenrc file</title><content type='html'>I have been using the awesome screen program for a long time. I recently remembered that someone once gave me the following ~/.screenrc file:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# Screen configuration &lt;br /&gt; &lt;br /&gt;# Statusbar &lt;br /&gt;hardstatus off &lt;br /&gt;hardstatus alwayslastline &lt;br /&gt;hardstatus string "%{.bW}%-w%{.rW}%n %t%{-}%+w %=%{..G} %H %{..Y} %d/%m %C%a" &lt;br /&gt; &lt;br /&gt;# Scrolling in xterms &lt;br /&gt;termcapinfo xterm|xterms|xs|rxvt ti@:te@ &lt;br /&gt; &lt;br /&gt;# Miscellaneous &lt;br /&gt;startup_message off &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This file enables a small status bar at the bottom of the screen with the hostname and color. I you need to manage lots of different servers this is great as you can make each status bar a different color - never get hosts confused again!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375640005424015695-5588835016464295071?l=scudette.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scudette.blogspot.com/feeds/5588835016464295071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375640005424015695&amp;postID=5588835016464295071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/5588835016464295071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/5588835016464295071'/><link rel='alternate' type='text/html' href='http://scudette.blogspot.com/2009/07/screenrc-file.html' title='screenrc file'/><author><name>Scudette</name><uri>http://www.blogger.com/profile/00290957716409467236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4375640005424015695.post-3192497668517974383</id><published>2009-07-21T19:28:00.000-07:00</published><updated>2009-07-21T19:35:07.707-07:00</updated><title type='text'>Python Debugger</title><content type='html'>I thought I will document this somewhere in case its useful to anyone.&lt;br /&gt;&lt;br /&gt;I recently had to do some work with the python debugger which is cool, but does not support any command line completion or even a history. I googled and apparently you can use ipython as a debugger but I could not get it to work properly.&lt;br /&gt;&lt;br /&gt;I found some code on the net to do completion and I added a bit of history. To do this you need to add the following files:&lt;br /&gt;&lt;br /&gt;~/.pdbrc.py:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import readline, os.path, os &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;HISTORY = os.path.join(os.environ["HOME"], ".pdbhist") &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;try: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    readline.read_history_file(HISTORY) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;except IOError: pass &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import atexit &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;atexit.register(readline.write_history_file,HISTORY) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;# save this in .pdbrc.py in your home directory &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;def complete(self, text, state): &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    """return the next possible completion for text, using the current frame's &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;       local namespace &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;       This is called successively with state == 0, 1, 2, ... until it &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;       returns None.  The completion should begin with 'text'. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    """ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    try: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        # keep a completer class, and make sure that it uses the current local scope  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        if not hasattr(self, 'completer'): &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;            self.completer = rlcompleter.Completer(self.curframe.f_locals) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        else: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;            self.completer.namespace = self.curframe.f_locals &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        return self.completer.complete(text, state) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    except Exception,e: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;        print e &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and ~/.pdbrc&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;# save this in .pdbrc in your home directory &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import os &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import sys &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;# import rlcompleter early, as it contains side effects &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;import rlcompleter &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;# refresh the terminal &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;os.system("stty sane") &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;# this rc file takes single lines, so define our complete function here &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;execfile(os.path.expanduser("~/.pdbrc.py")) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;# replace the Pdb class's complete method with ours &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;sys._getframe(1).f_globals['Pdb'].complete = complete &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;# set use_rawinput to 1 as tab completion relies on rawinput being used &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;sys._getframe(1).f_locals['self'].use_rawinput = 1 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375640005424015695-3192497668517974383?l=scudette.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scudette.blogspot.com/feeds/3192497668517974383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375640005424015695&amp;postID=3192497668517974383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/3192497668517974383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/3192497668517974383'/><link rel='alternate' type='text/html' href='http://scudette.blogspot.com/2009/07/python-debugger.html' title='Python Debugger'/><author><name>Scudette</name><uri>http://www.blogger.com/profile/00290957716409467236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4375640005424015695.post-608327365491028997</id><published>2008-10-02T15:24:00.001-07:00</published><updated>2008-10-03T04:41:41.747-07:00</updated><title type='text'>pstree - a volatility plugin</title><content type='html'>I have been lurking on the volatility irc channel (#volatility @ irc.freenode.net) and I overheard a challenge to make a &lt;a href="http://www.pyflag.net/volatility/pstree.py"&gt;pstree&lt;/a&gt; like plugin. I thought this would be a great way to learn more of the code base.&lt;br /&gt;&lt;br /&gt;The volatility code base is very nice and well written. It can be improved however, and this plugin demonstrates what I propose to make the code more reusable. As can be seen producing the data and rendering it are separated into 2 methods. The calculate() method just produces a data structure, and the render method output the data to the screen. This architecture is better because other tools can then just over ride the render method to output the data in any format they see fit - e.g. XML, HTML etc.&lt;br /&gt;&lt;br /&gt;Ed: After posting the initial version I had lots of discussions from the IRC channel. The next challenge was to recover the path and name of the binary for each task. There are lots of ways to do this and I was offered 3:&lt;br /&gt;&lt;br /&gt;First off we can get the CommandLine from the PEB. This is what volatility already does in dlllist for example&lt;br /&gt;&lt;br /&gt;Second we can get the ImagePathName from the PEB (as moyix and msuiche point out - thanks guys for the help). Note that for those two options we need to switch to process address space first.&lt;br /&gt;&lt;br /&gt;Lastly aschuster pointer out that same information is also stored in the auditing subsystem SeAuditProcessCreationInfo (thanks aschuster).&lt;br /&gt;&lt;br /&gt;So there are many ways to skin this cat. Here is a&lt;a href="http://www.pyflag.net/volatility/pstree.output"&gt; sample output&lt;/a&gt;. Hopefully all these agree with each other.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375640005424015695-608327365491028997?l=scudette.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scudette.blogspot.com/feeds/608327365491028997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375640005424015695&amp;postID=608327365491028997' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/608327365491028997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/608327365491028997'/><link rel='alternate' type='text/html' href='http://scudette.blogspot.com/2008/10/pstree-volatility-plugin.html' title='pstree - a volatility plugin'/><author><name>Scudette</name><uri>http://www.blogger.com/profile/00290957716409467236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4375640005424015695.post-1723926591678777459</id><published>2008-07-16T17:47:00.000-07:00</published><updated>2008-07-16T18:15:58.578-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pyflag'/><title type='text'>Digital Forensics Research Workshop Challenge</title><content type='html'>Every year the &lt;a href="http://www.dfrws.org/"&gt;DFRWS&lt;/a&gt; guys put on a great forensic challenge and this year was no different. While last years challenge was very hard and not that realistic, this years challenge was designed to reflect what many people would experience in their work. The challenge was a simulated incident which involved network traffic, some file forensics and Linux memory forensics.&lt;br /&gt;&lt;br /&gt;On the positive side it is quite easy to get something from the challenge. Pretty much anyone can have a go with this challenge and get something (You can probably even solve it using commercial tools !!). Thats a very good aspect of this years challenge - I'm sure it will be used for training for many years to come.&lt;br /&gt;&lt;br /&gt;The negative side is that it becomes difficult to do something extra ordinary in order to win the challenge. Just getting the right answer is not going to cut it because many others can get the right answer. We needed to get the right answer&lt;span style="font-style: italic;"&gt; in style&lt;/span&gt;... Our tools need to be better and look nicer and also be easier to use. Unless, of course, we missed something blatantly obvious....&lt;br /&gt;&lt;br /&gt;This year I was lucky enough to be involved with the great team of David Collett and Aaron Walters. These guys are brilliant and each brings their own unique skills to the table. I believe this made our submission well rounded and certainly better than what each of us could have done on our own. Regardless of whether we are lucky enough to place first, I think we did great and certainly developed &lt;a href="http://www.pyflag.org/"&gt;pyflag&lt;/a&gt; in new directions and added some very cool features - so it was well worth it.&lt;br /&gt;&lt;br /&gt;We actually took guidance from the perp (now i sound like a real CSI) and decided to use google docs for collaborative editing. Thats a great product and works very well considering that we tried to collaborate on a 50 page document with many screen shots and images.  As a bonus you can publish the document when you are finished:&lt;br /&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/Doc?id=ddmm9hjf_16hbkgjh4m&amp;amp;hl=en"&gt;https://docs.google.com/Doc?id=ddmm9hjf_16hbkgjh4m&amp;amp;hl=en&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Getting the paper in on time was a tremendous effort and well done to the team for foregoing sleep and time with their loved ones to make it happen....&lt;br /&gt;&lt;br /&gt;It turned out to be a really cool document with a pyflag walkthrough of a realistic scenario. Hopefully people can read it and get a better idea of how to use pyflag from it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375640005424015695-1723926591678777459?l=scudette.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scudette.blogspot.com/feeds/1723926591678777459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375640005424015695&amp;postID=1723926591678777459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/1723926591678777459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/1723926591678777459'/><link rel='alternate' type='text/html' href='http://scudette.blogspot.com/2008/07/digital-forensics-research-workshop.html' title='Digital Forensics Research Workshop Challenge'/><author><name>Scudette</name><uri>http://www.blogger.com/profile/00290957716409467236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4375640005424015695.post-8550848415393297474</id><published>2008-07-12T20:30:00.000-07:00</published><updated>2008-07-12T21:52:21.670-07:00</updated><title type='text'>Magic Flute</title><content type='html'>So we went to see the &lt;a href="http://www.operaqld.org.au/the%20magic%20flute/index.html"&gt;magic flute &lt;/a&gt;last night... The performance was excellent, taking the liberty of changing the original story to occur in a circus. This variation really turned out well with colorful characters and an interesting set. The clown costumes were engaging, and the set was beautifully constructed.&lt;br /&gt;&lt;br /&gt;Jason Barri Smith (Papageno) was excellent - not only was his singing superb, his acting was engaging, and so effortlessly combined with the music. &lt;span class="Show2bioheadbold"&gt;Judit Lorincz, (Queen of the night) was superb, performing the vocal scales in Der Hoelle Rache superbly (This is a really hard to sing aria).&lt;br /&gt;&lt;br /&gt;My most memorable aria of all was the Papageno/Papagna duet at the end was terrific - thats my favorite aria.&lt;br /&gt;&lt;br /&gt;Well done opera Queensland.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375640005424015695-8550848415393297474?l=scudette.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://scudette.blogspot.com/feeds/8550848415393297474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375640005424015695&amp;postID=8550848415393297474' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/8550848415393297474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375640005424015695/posts/default/8550848415393297474'/><link rel='alternate' type='text/html' href='http://scudette.blogspot.com/2008/07/magic-flute.html' title='Magic Flute'/><author><name>Scudette</name><uri>http://www.blogger.com/profile/00290957716409467236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
