Search code examples
.netpowershellinternet-exploreresent

ESENT Always throws EsentPageSizeMismatchException when trying to open IE 10/11 WebCache.dat


I am trying to create a powershell script to read the IE 10/11 internet history, which is stored in AppData\Local\Microsoft\Windows\WebCache\WebCache.dat.

I am using Managed Esent+- to interface with the Win32 Jet api in .NET.

My issue is that I can never actually open the database, as EsentPageSizeMismatchException is thrown when I call JetAttachDatabase. After doing some research on this error, I found that the IE WebCache has a page size of 32K. When I attempted to correct for this, by setting the DatabasePageSize system parameter to 0x8000, JetInit started to throw the same exception.

Here is the code I have

#stop the things locking the database
stop-process -name taskhost
stop-process -name dllhost
#give powershell access to the interop dlls
add-type -path "$PSScriptRoot\ManagedEsent 1.6\Esent.Interop.dll"
$instance = [Microsoft.Isam.Esent.Interop.JET_INSTANCE]::Nil
#set page size
[Microsoft.Isam.Esent.Interop.api]::JetSetSystemParameter(
    $instance,
    [Microsoft.Isam.Esent.Interop.JET_SESID]::Nil,
    [Microsoft.Isam.Esent.Interop.JET_param]::DatabasePageSize,
    0x8000,
    $null
)
[Microsoft.Isam.Esent.Interop.Api]::JetCreateInstance([ref]$instance,"testing")
# init the instance, throws EsentPageSizeMismatchException if the page size is not default
[Microsoft.Isam.Esent.Interop.Api]::JetInit([ref]$instance) 
$sesid = [Microsoft.Isam.Esent.Interop.JET_SESID]::Nil
[Microsoft.Isam.Esent.Interop.Api]::JetBeginSession($instance,[ref]$sesid,$null,$null)
# throws EsentPageSizeMismatchException if page size is default
[Microsoft.Isam.Esent.Interop.api]::JetAttachDatabase(
   $sesid,
   "C:\Users\Administrator\AppData\Local\Microsoft\Windows\WebCache\WebCacheV01.dat",
   [Microsoft.Isam.Esent.Interop.AttachDatabaseGrbit]::ReadOnly
)
...

It seems like the ESENT engine does not like having the non-default page size, but I've scoured the internet and there doesn't seem to be a way to change the engine page size. What is causing this error?


Solution

  • If you notice, in one case it's JetAttachDatabase that fails with the exception, and JetInit in the other.

    You are indeed correct that you need to set DatabasePageSize. JetInit is actually a poor name. It should be called something like JetInitAndReplayLogFiles. It will look at the transaction log files (default name of edb*.log) in the log directory (default: "."), and replay the operations within the transaction log files.

    You are probably now picking up other transaction log files created with a different page size. Theory: you're picking up the edb*.log files you unintentionally created during your first attempt.

    Some potential solutions:

    -cd in to the directory that contains the log files first.

    -Change the LogFileDirectory (You can either use JetSetSystemParameter with JET_param.LogFilePath, or the wrapper class InstanceParameters.LogFileDirectory). Oh, you'll also need to set InstanceParameters.BaseName to "v01", since that's what the webcache01.dat file seems to use (Affects the names of "edb.log" versus "v01.log").

    -Use esentutl.exe -r v01 to bring the database to a 'clean shutdown' state, and then set InstanceParameters.Recovery to false to avoid creating new transacation log files accidentally. And I see you're already attaching with AttacheDatabaseGrbit.ReadOnly.

    Finally, I hope this is just for curiosity. The people who worked on the inetcache can change the implementation details at any time. If it's for forensic purposes, Microsoft does assist forensic efforts by law enforcement agencies.

    -martin