1

The Skype 8 has leveldb which is located inside the folder

C:\Users\machine-user-name\AppData\Roaming\Microsoft\Skype for Desktop\IndexedDB\file__0.indexeddb.leveldb

I am working on c# to read the contents of skype 8 leveldb. Here is my code to open and iterate over all key and value of leveldb.

void IteratorSkypeDb()
{
    var path = @"C:\Users\ptandukar\AppData\Roaming\Microsoft\Skype for Desktop\IndexedDB\file__0.indexeddb.leveldb";
    Options options = new Options();
    using (var db = new DB(options, path))
    {
        using (var iterator = db.CreateIterator(new ReadOptions()))
        {
            iterator.SeekToFirst();
            while (iterator.IsValid())
            {
                var key = iterator.KeyAsString();
                var value = iterator.ValueAsString();
                Console.WriteLine($"{key}-{value}");
                iterator.Next();
                }
            }
        }
    }
}

But, I got following exception while initializing the DB:

System.UnauthorizedAccessException: 'Invalid argument: idb_cmp1does not match existing comparator : leveldb.BytewiseComparator'

Could any one sheds some light on it?

FYI: I used the sample code from the https://github.com/Reactive-Extensions/LevelDB It has a native project which is not loaded in my VS2017 but I managed to download the leveldb.dll from some other link and copied it to bin\debug folder to run the program.

smn.tino
  • 2,272
  • 4
  • 32
  • 41
Prakash
  • 422
  • 1
  • 12
  • 31

2 Answers2

3

I have tried using https://github.com/tg123/IronLeveldb with some success. The only issue is that the encoding looks weird and that I cannot find a way using this library to read out the entire DB. I copied the entire LevelDb folder to a test folder and ran this code:

var db = IronLeveldbBuilder.BuildFromPath(@"C:\test\leveldb");
        IEnumerable<IByteArrayKeyValuePair> data = db.SeekFirst();
        foreach (IByteArrayKeyValuePair pair in data)
        {
            Console.BackgroundColor = ConsoleColor.Blue;
            Console.WriteLine($"****{Encoding.Default.GetString(pair.Key.ToArray(), 0, pair.Key.Length)}****");
            Console.ResetColor();
            Console.WriteLine(Encoding.Default.GetString(pair.Value.ToArray(), 0, pair.Value.Length));
        }

I just added the *** to make the keys stand out from the values. The result was quite interesting to see, I seems like there are messages that Skype blocks (spam) as well.

The first couple of values (of the key value pairs) seems to be the "column names"

c o n v i d c r e a t e d t i m e c o n v e r s a t i o n I d c r e a t e d T i m e c o n v i d c o u n t s c r e a t e d t i m e c o n v e r s a t i o n I d _ c o u n t s T y p e c r e a t e d T i m e c o n v i d m y m e s s a g e c r e a t e d t i m e c o n v e r s a t i o n I d _ i s M y M e s s a g e c r e a t e d T i m e a l e r t s C o n v i d m e s s a g e . c o n v e r s a t i o n I d a l e r t s R e a d T i m e s t a m p

and then further on some conversation data:

**** 0 1 9 : 1 3 4 1 9 5 1 e a a 3 8 4 7 e 5 a 3 8 4 a f 9 5 2 a a f 0 0 d 9 @ t h r e a d . s k y p e 1 7 4 3 5 8 1 1 3 8 5 3 9 3 0 3 4 0 9 3**** 1535543604069"composetime"2018-08-29T11:53:23.825Z"clientmessageid"17435811385393034093"conversationLink"zhttps://db5-client-s.gateway.messenger.live.com/v1/users/ME/conversations/19:1341951eaa3847e5a384af952aaf00d9@thread.skype"content"-I have done a DNS health check and there are still some things that is in warning or error state, probably due to propagation so will continue checking from my side as well."type"Message"conversationid"019:1341951eaa3847e5a384af952aaf00d9@thread.skype"from"Ohttps://db5-client-s.gateway.messenger.live.com/v1/users/ME/contacts/8:evn26041{$ "cuid"17435811385393034093"conversationId"019:1341951eaa3847e5a384af952aaf00d9@thread.skype"createdTimeN P6XXvB"creator" 8:evn26041"content"-I have done a DNS health check and there are still some things that is in warning or error state, probably due to propagation so will continue checking from my side as well."messagetypeRichText"contenttype_" properties_"_isEphemeralF"fileEncryptionKeys"_countsTypeI"_isMyMessageI {

Kaptein Babbalas
  • 1,058
  • 12
  • 15
2

You need to define a comparator named idb_cmp1. See the documentation on the github. Unclear if it is connected to the implementation of LevelDB/IndexDB used by google (see this so question/answer that references the same name, implementation of the comparator that is here but seems to be complex enough to be too much pain to reimplement)

If you only need to read data, and you want to read all the data, and it isn't a problem that the data is unordered, then it is possible that creating any comparator named idb_cmp1 will be ok. Untested code for a binary comparator:

// Simple binary comparer
var comparator = Comparator.Create("idb_cmp1", (x, y) =>
{
    NativeArray<byte> nx = (NativeArray<byte>)x;
    NativeArray<byte> ny = (NativeArray<byte>)y;

    long count = Math.Min((long)nx.count, (long)ny.count);

    for (int i = 0; i < count; i++)
    {
        int cmp = nx[i].CompareTo(ny[i]);

        if (cmp != 0)
        {
            return cmp;
        }
    }

    return 0;
});
xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Thank you xanatos for the detail answer. It would take a bit much effort for us to implement it in c#. – Prakash Jul 23 '18 at 17:20
  • Thank you @Xanatos for the updates. I tried this and this time, it does not give the error while initializing DB but throws following error at iterator.SeekToFirst(); System.Exception: 'IO error: D:\temp\24-a\file__0.indexeddb.leveldb\000028.sst: The system cannot find the file specified. In that leveldb folder, it does not have the file nameed 000028.sst. It has instead the file 000031.sst. Wondering why it was looking the file that does not exists in leveldb folder. – Prakash Jul 23 '18 at 19:42
  • Do you have a file named 000028.ldb? Had a similar issue and saw this where renaming to a .sst file worked for me: https://github.com/dain/leveldb/issues/73 – OJ7 Jul 22 '19 at 19:46