-
Notifications
You must be signed in to change notification settings - Fork 87
Description
I've written a Windows application using libesedb to extract data from the Windows Search databases. When extracting data from a few different columns (one of which is the System_Kind column), I'm getting what appears to be a tagged data type flag of 3 with unidentified byte values. Now, some other applications I've tested to confirm my issue seem to be either extracting the correct and expected bytes, or are extracting the same values I'm getting. Even the esedbexport application compiled seems to extract the correct bytes, but this issue only seems to be occurring with multi-value values in type 11 (long binary) columns.
I'm using version 20240420, and my function is below:
[DllImport("libesedb.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int libesedb_column_get_type(IntPtr column, out uint column_type, out IntPtr error);
[DllImport("libesedb.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int libesedb_record_get_utf8_value_size(IntPtr record, int value_entry, out UIntPtr utf8_value_size, out IntPtr error);
[DllImport("libesedb.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int libesedb_record_get_value_utf8_string_size(IntPtr record, int value_entry, out UIntPtr utf8_string_size, out IntPtr error);
[DllImport("libesedb.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int libesedb_record_get_value_utf8_string(IntPtr record, int value_entry, byte[] utf8_value, UIntPtr utf8_value_size, out IntPtr error);
[DllImport("libesedb.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int libesedb_record_get_value_data_size(IntPtr record, int value_entry, out UIntPtr value_data_size, out IntPtr error);
[DllImport("libesedb.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int libesedb_record_get_value_data(IntPtr record, int value_entry, byte[] value_data, UIntPtr value_data_size, out IntPtr error);
[DllImport("libesedb.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int libesedb_record_get_value_data_flags(IntPtr record, int value_entry, out byte value_data_flags, out IntPtr error);
[DllImport("libesedb.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int libesedb_record_get_value_32bit(IntPtr record, int value_entry, out uint value_32bit, out IntPtr error);
[DllImport("libesedb.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int libesedb_record_get_value_64bit(IntPtr record, int value_entry, out ulong value_64bit, out IntPtr error);
private static object? GetRecordValue(IntPtr recordHandle, int valueIndex)
{
int result = libesedb_record_get_column_type(recordHandle, valueIndex, out uint columnType, out nint error);
if (result != 1)
return null;
result = libesedb_record_get_value_utf8_string_size(recordHandle, valueIndex, out nuint valueSize, out error);
if (result == 1 && valueSize.ToUInt64() > 0)
{
byte[] valueBuffer = new byte[valueSize.ToUInt64()];
result = libesedb_record_get_value_utf8_string(recordHandle, valueIndex, valueBuffer, valueSize, out error);
if (result == 1)
{
return Encoding.UTF8.GetString(valueBuffer).TrimEnd('\0');
}
}
result = libesedb_record_get_value_32bit(recordHandle, valueIndex, out uint value32, out error);
if (result == 1)
{
return value32;
}
result = libesedb_record_get_value_64bit(recordHandle, valueIndex, out ulong value64, out error);
if (result == 1)
{
return value64;
}
result = libesedb_record_get_value_data_size(recordHandle, valueIndex, out valueSize, out error);
if (result == 1 && valueSize.ToUInt64() > 0)
{
byte[] dataBuffer = new byte[valueSize.ToUInt64()];
result = libesedb_record_get_value_data(recordHandle, valueIndex, dataBuffer, valueSize, out error);
if (result == 1)
{
return dataBuffer;
}
}
return null;
}
When the values are a tagged data type 01, I get the correct Unicode bytes back, either folder, link, etc. However, When they come back as type 03 I get 13ecb47b0d80cbdf6779b80d ( the type and value are 0313ecb47b0d80cbdf6779b80d, but I don't get the type with the returned bytes, this was parsed using another tool) or something similar (0314e6379b5c9603e6e5b07c8c36bfd9e4b21c) depending on what the content should be. Since this tagged data type isn't in the documentation, I'm unsure of the best way to handle it, if it can be handled with libesedb. The only reason I know this is a multi-value is when I use other tools to parse the same database, or when using esedbexport, I get either link program or 6c696e6b0070726f6772616d. But I'm not getting the expected data from libesedb_record_get_value_data.
Here's a screenshot of what I end up getting from both this function and esedbexport:
And yes, while I appreciate there is some decoding going on later to convert the bytes to readable text, the return values I get from dataBuffer are the bytes posted above. The incoherent text in the screenshot just serves to highlight the comparison points between the outputs.
If this is a "me" problem, and I've coded something incorrectly, I'll fully accept that. However, because the returns are inconsistent, I'm wondering if there might be something missing in the evaluation of the data, or a missing type?
I can provide sample databases and more source code as necessary via email or Google Drive or the like.