1

In a Delphi XE8 VCL Form Aplication, with TEmbeddedWB I get the cookies with this method:

CookieStr := EmbeddedWB1.Cookie;
CodeSite.Send('CookieStr', CookieStr);

This is the result (for example):

name1=value1; name2=value2; name3=value3

However, as you can see, this gets only the name and value of the cookies.

So how can I get the other cookie fields such as path, expiration date, etc.?

user1580348
  • 5,721
  • 4
  • 43
  • 105
  • This applies to the `TWebBrowser` control as well. The string you got is from the [`IHTMLDocument2::cookie`](https://msdn.microsoft.com/en-us/library/aa752641(v=vs.85).aspx) property. EWB does no extra processing and this property does not return more than it has set. So the answer is that it should return those fields, but they are likely not set. – TLama Aug 18 '15 at 19:51
  • I have checked in `C:\Users\\AppData\Roaming\Microsoft\Windows\Cookies`: For example, the `c.bing.com/` web page has set this `ANONCHK` cookie: http://i.imgur.com/StfkAz1.png. You can see that it has all the fields. However, `EmbeddedWB1.Cookie` only gets me 'ANONCHK=1;'. Also, when I set a cookie from my website which explicitly sets an expiration date, I don't get this date with `EmbeddedWB1.Cookie`. – user1580348 Aug 18 '15 at 20:07
  • I'm afraid there's not much you can do here. The [`cookie`](https://msdn.microsoft.com/en-us/library/ms533693%28v=vs.85%29.aspx) property should give you all what is described there (which should include also the additional details). Maybe there are some security restrictions. – TLama Aug 18 '15 at 20:14
  • Will try to get the cookie details with a JavaScript. But how could I get the JavaScript result in Delphi? – user1580348 Aug 18 '15 at 20:18
  • 1
    That's a simple question with not simple answer. I have succeded with `TWebBrowser` following [this tutorial](http://www.delphidabbler.com/articles?article=22&part=1) (I think you will need to do the same as I don't think that EWB could make your life anyhow easier for this task). – TLama Aug 18 '15 at 20:31
  • 1
    Thanks, this looks very interesting. Will investigate this. – user1580348 Aug 18 '15 at 21:09
  • I've made it work with `TEmbeddedWB` and injected my own JavaScript with `TEmbeddedWB.ExecScript` to get the cookies with JavaScript `var c = document.cookie;`. However, with this JavaScript I get the same cookies string as with `TEmbeddedWB.Cookie`. So I wonder WHERE Internet Explorer stores the expiration date of a specific cookie and how it can be decoded? – user1580348 Aug 19 '15 at 10:01
  • So we have narrowed this issue down to IE and JavaScript (as in JavaScript you got the same string as returned by the `Cookie` property). I don't know much about cookies, but when thinking about it, the browser must parse those additional details to know when the cookie expires, and where can be applied. And I think you don't get these details because you just obtain a cookie that is not expired and that belongs to the given path in your domain (see e.g. [How to get cookie expiration date from JavaScript](http://stackoverflow.com/q/3274875/960757)). – TLama Aug 19 '15 at 10:36
  • There is a Nirsoft utility for this: http://www.nirsoft.net/utils/iecookies.html Unfortunately no source code. – user1580348 Aug 19 '15 at 11:42
  • I bet they are using the cookie files (which are [not difficult to decode](http://weitips.blogspot.jp/2006/04/cookie-file-format-of-internet.html)). – TLama Aug 19 '15 at 11:50
  • I have found a sample Delphi program with source: Cookie Detective v.1.0 – user1580348 Aug 21 '15 at 20:38
  • Exceeded the 5 minutes ... I have found a sample Delphi program with source: Cookie Detective v.1.0 http://www.torry.net/apps/internet/utilities/jccd.zip This reads all IE cookies by using `TInternetCacheEntryInfo` from `WinInet`. However those records have no reference to the cookie name and cookie value which I get from `TEmbeddedWB.Cookie`. So I have to use a cumbersome trick to associate the cookie from `TEmbeddedWB` with the respective records from `TInternetCacheEntryInfo`. Could somebody get me a hint on how to retrieve the name and value directly from `TInternetCacheEntryInfo`? – user1580348 Aug 21 '15 at 20:44
  • Also, in `Cookie Detective` I can only READ the cookie records. Does somebody know how to WRITE them? – user1580348 Aug 21 '15 at 20:48
  • You can use `GetUrlCacheEntryInfo` function to get `INTERNET_CACHE_ENTRY_INFO` entry for the given URL (you just have to sanitize the URL by yourself as the function doesn't perform URL parsing). With the `SetUrlCacheEntryInfo` function you can create a persistent cookie. – TLama Aug 21 '15 at 20:56
  • @TLama Could you show me a source code example? Thank you! – user1580348 Aug 22 '15 at 00:52
  • This is a working example for the usage of `GetUrlCacheEntryInfo`: http://i.imgur.com/phSnfvJ.png or http://pastebin.com/Ztc3bEHR In this case it gives back the local file name of a visited web page from the IE cache. How could this be related to cookies? – user1580348 Aug 22 '15 at 11:34

1 Answers1

0

Here is the solution:

First, we need to make us familiar with the Winapi FILETIME structure.

Then get the IE cookie files from here:

C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Cookies\

Now look for the cookie files with the identical name=value pairs you got from TEmbeddedWB.Cookie.

Here is an example of the content of a IE cookie file, where we take our data from:

enter image description here

(Similarities with people alive or other authorities are purely accidental and not intended!)

We can see the meaning of the various numbers from the red colored comments.

And here is the source code to decipher those numbers:

uses Winapi.Windows;

function ConvertWinapiFileTimeLoHiValuesToDateTimeStr(const AFTLoValue, AFTHiValue: Cardinal): string;
const
  InvalidDate = '01/01/80 12:00:00 AM';
var
  lCookieFileTime: TFileTime;
  lDosDT: Integer;
  lLocalFileTime: TFileTime;
begin
  lCookieFileTime.dwLowDateTime  := AFTLoValue;
  lCookieFileTime.dwHighDateTime := AFTHiValue;

  FileTimeToLocalFiletime(lCookieFileTime, lLocalFileTime);
  if FileTimeToDosDateTime(lLocalFileTime, Longrec(lDosDT).Hi, Longrec(lDosDT).Lo) then
  begin
    try
      Result := DateTimeToStr(FiledateToDatetime(lDosDT));
    except
      Result := InvalidDate;
    end;
  end
  else
    Result := InvalidDate;
end;

Now we can use this function with the numbers from the above cookie file, as an example:

CodeSite.Send('Expiration Date', ConvertWinapiFileTimeLoHiValuesToDateTimeStr(2496134912, 30471078));
CodeSite.Send('Modified Date', ConvertWinapiFileTimeLoHiValuesToDateTimeStr(2624224682, 30465043));

Which will give us this result:

enter image description here

user1580348
  • 5,721
  • 4
  • 43
  • 105