#!/usr/bin/python
import sys, os
import math
import time
class SkypeDataset:
s = ""
dataset = {}
i = 0
print_unknown = False #True
verbose = False #True
filename = None
def unknown_endswith3(self, end):
i = self.i
s = self.s
if self.print_unknown:
print "unknown_endswith", end,":",
j = 0
while True:
nextn = ord(s[i]) * (256**2) + ord(s[i+1]) * (256) + ord(s[i+2])
if nextn in end:
break
if self.print_unknown:
print "%d(%X)" % (i, ord(s[i])),
i = i + 1
if self.print_unknown:
print
self.i = i+3
return end.index(nextn)
def unknown(self, count):
i = self.i
s = self.s
if self.print_unknown:
print "unknown: ",
for i in range(i,i+count):
d = s[i]
if self.print_unknown:
print "%d(%X)" % (i, ord(d)),
i = i + 1
if self.print_unknown:
print
self.i = i
def known_str_len(self, count, name):
i = self.i
s = self.s
self.dataset[name] = s[i:(i+count)]
if self.verbose:
print name, ":", self.dataset[name]
self.i = i+count
def known_str(self, name):
i = self.i
s = self.s
begin = i
while ord(s[i]) != 0:
i = i + 1
content = s[begin:i]
self.dataset[name] = content
if self.verbose:
print name, ":", self.dataset[name]
while i<len(s) and ord(s[i]) == 0:
i = i + 1
self.i = i
def known_hex(self, count, name):
i = self.i
s = self.s
# LSB first
number = 0
for j in range(count):
number = number + ord(s[j+i]) * (256**j)
self.dataset[name] = number
if self.verbose:
print name, ":", self.dataset[name]
self.i = i+count
def known_num(self, count, name):
i = self.i
s = self.s
# LSB first
number = 0
for j in range(count):
number = number + ord(s[j+i]) * (256**j)
self.dataset[name] = number
if self.verbose:
print name, ":", self.dataset[name]
self.i = i + count
def __init__(self, filename):
self.filename = filename
assert(filename[-4:] == '.dbb')
i = -4
while filename[i-1].isdigit():
i = i - 1
self.datasetlen = int(filename[i:-4])
assert(self.datasetlen != 0)
self.datasetlen = self.datasetlen + 8
self.file = file(filename, "r")
if os.path.getsize(filename) % self.datasetlen == 0:
self.count = os.path.getsize(filename) / self.datasetlen
else:
self.count = os.path.getsize(filename) / self.datasetlen + 1
def __len__(self):
return self.count
def __getitem__(self, i):
return self.read_dataset(i)
def to_array(self):
a = []
j = 0
while j < self.count:
a.append(self.read_dataset(j))
j = j + 1
return a
@staticmethod
def skype_homes():
homes = []
if os.environ.has_key("HOME"):
path = os.path.join(os.environ["HOME"], ".Skype")
for el in os.listdir(path):
el_full = os.path.join(path, el)
if os.path.isdir(el_full):
homes.append(el_full)
if os.environ.has_key("APPDATA"): # TODO: Test
path = os.path.join(os.environ["APPDATA"], ".Skype")
for el in os.listdir(path):
el_full = os.path.join(path, el)
if os.path.isdir(el_full):
homes.append(el_full)
return homes
class SkypeMsgDataset(SkypeDataset):
@staticmethod
def find_filenames():
files = []
for skype_home in SkypeDataset.skype_homes():
for el in os.listdir(skype_home):
if el.startswith("chatmsg") and el.endswith(".dbb"):
files.append(os.path.join(skype_home, el))
return files
def read_dataset(self, i):
self.file.seek(self.datasetlen*i)
self.s = self.file.read(self.datasetlen)
self.i = 0
if len(self.s) < 4:
return None
if(self.s[0:4] != "l33l"):
raise IndexError("Odd identifier")
self.dataset = {}
self.known_str_len(4, "Identifier")
self.known_num(2, "Record Lenght")
self.known_num(2, "NULL")
self.known_num(2, "Message number")
self.known_num(2, "NULL")
self.unknown_endswith3([0x03E003])
self.known_str("Chatname")
self.known_num(7, "Timestamp")
self.unknown_endswith3([0x03E803])
self.known_str("Sender-ID")
self.unknown_endswith3([0x03EC03])
self.known_str("Sender Name")
try:
self.unknown_endswith3([0x03FC03, 0x03F403])
except:
raise Exception("Error 42 on parsing Message %d from file %s" % (i, self.filename))
try:
self.known_str("Content")
type = self.unknown_endswith3([0x03D818, 0xf10303])
self.unknown_endswith3([0x0000])
#if type == 0:
# self.unknown(3)
#self.known_str("Chat members")
except:
raise Exception("Error 43 on parsing Message %d from file %s" % (i, self.filename))
return self.dataset
class SkypeCallDataset(SkypeDataset):
@staticmethod
def find_filenames():
files = []
for skype_home in SkypeDataset.skype_homes():
for el in os.listdir(skype_home):
if el.startswith("callmember") and el.endswith(".dbb"):
files.append(os.path.join(skype_home, el))
return files
def read_dataset(self, i):
self.file.seek(self.datasetlen*i)
self.s = self.file.read(self.datasetlen)
self.i = 0
if(self.s[0:4] != "l33l"):
raise IndexError("Odd identifier")
self.dataset = {}
self.known_str_len(4, "Identifier")
self.known_num(2, "Record Lenght")
self.known_num(2, "NULL")
self.known_num(2, "Message number")
self.known_num(2, "NULL")
self.unknown_endswith3([0x039807])
self.known_str("Caller-ID")
self.unknown_endswith3([0x039c07])
self.known_str("Caller Name")
self.unknown_endswith3([0x03b801])
self.unknown(2)
self.known_str("Timestamp")
self.dataset["Time"] = time.ctime(int(self.dataset["Timestamp"]))
return self.dataset