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?
You should use JetGetDatabaseFileInfo() to get the required page size to use with SetSetSystemParameter()
Here is an example in C# (hey... that's close enough, right?)
For my case I had to manually go into the bin/Debug folder and delete the contents manually each time I switched databases before debugging it again. I hope this helps someone who is facing this issue.
If you notice, in one case it's
JetAttachDatabase
that fails with the exception, andJetInit
in the other.You are indeed correct that you need to set DatabasePageSize.
JetInit
is actually a poor name. It should be called something likeJetInitAndReplayLogFiles
. 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
withJET_param.LogFilePath
, or the wrapper classInstanceParameters.LogFileDirectory
). Oh, you'll also need to setInstanceParameters.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 setInstanceParameters.Recovery
tofalse
to avoid creating new transacation log files accidentally. And I see you're already attaching withAttacheDatabaseGrbit.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