0

I am trying to retrieve a Date value from the registry. The value is encrypted with CryptProtectData.

The Bytes of interest are (little-endian):

[-16] and [-15] is a the year. [-14] and [-13] is a month and [-12] and [-11] is a day.

RegistryKey HKCR;
RegistryKey dateKey;
HKCR = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, RegistryView.Default);
dateKey = HKCR.OpenSubKey(subKeyPath);
byte[] registryValue = (byte[])dateKey.GetValue(null);
byte[] unprotectedRegistryValue = ProtectedData.Unprotect(registryValue, null, DataProtectionScope.LocalMachine);

The unprotectedRegistryValue is an byte Array: {byte[224]}. I have to further process the range [-16..-11] and pass the apropried values to BitConverter.ToInt16([-16..-15]) and then to Date functions to receive the information about the year for example.

Unfortunatelly I am stuck with the value from unprotectedRegistryValue, because there is no negative index. When I try to access the values for the year information.

var yearBytes = new byte[] {unprotectedRegistryValue[-16], unprotectedRegistryValue[-15]};

I receive an IndexOutOfRangeException because the indexes of the unprotectedRegistryValue are all positive.

I miss some understanding between the part of encrypt the data and pass the bytes of interest to further processing the values.

How could I manage to get the bytes of interest and pass them further?

carboneum
  • 21
  • 1
  • 6
  • Arrays don't have negative indexes. Where have you got the info that those bytes are the ones with the values you need? – Gusman Jun 14 '20 at 18:19
  • @Gusman thank you for your fast response. This is actually a written note from an former colleague. Unfortunately He doesn't work for our company anymore. He was working with C++ and I am trying to accomplish an idea in C#. Here is his Pseudocode: RegGetValue; CryptUnprotectData; Data.pbData[Data.cbData-16]. He has also mentioned the bytes of interest. – carboneum Jun 14 '20 at 18:26
  • Without more info you are going to have a hard time.. where would '0' be placed? Is '0' the last byte and it goes up to -223? Is 0 placed at the middle of the array? If you can't know that, there's nothing you can do but a brute force test to find where are these values stored. – Gusman Jun 14 '20 at 18:30
  • @Gusman Thank you, that means that the needed information could be somewhere there. Is it so much different in C++? I mean he mentioned this bytes of interest, there has to be an method how I could pass this indexes and receive the needed bytes. Could I maybe use some other type for holding the information, instead of an byte[]? – carboneum Jun 14 '20 at 18:34
  • C++ behaves exactly as C# when using arrays, you can't use negative indexes...Also, a negative index has no meaning unless you know where '0' is placed, when you have a positive index you assume that '0' is the first element in the array, but when you have a negative number there is no consensus (it's not even valid), so your colleague must have some reference to where '0' is, where he considers the data starts and ends. It's worth a try to consider '0' the last byte, if that's the case then '-16' would be `unprotectedRegistryValue.Length - 17` and '-15' `unprotectedRegistryValue.Length - 16` – Gusman Jun 14 '20 at 18:40
  • @Gusman I understand, thank you very much. I will try to receive the Date assuming 0 as the last byte, maybe I have luck and I receive a date from this year :). – carboneum Jun 14 '20 at 18:44
  • @Gusman You were right :) '0' was the last byte and it worked like a charm. Thank you very much, please post your comment as an answer so I can accept it. – carboneum Jun 14 '20 at 21:14
  • Glad it worked :) – Gusman Jun 14 '20 at 21:15

1 Answers1

0

A negative index has no meaning unless you know where '0' is placed, when you have a positive index you assume that '0' is the first element in the array, but when you have a negative number there is no consensus (it's not even valid), so your colleague must have some reference to where '0' is, where he considers the data starts and ends.

It's worth a try to consider '0' the last byte, if that's the case then '-16' would be unprotectedRegistryValue.Length - 17 and '-15' unprotectedRegistryValue.Length - 16

Gusman
  • 14,905
  • 2
  • 34
  • 50
  • 1
    Thank you very much, based on your answer, here is the solution that worked. int t = unprotectedRegistryValue.Length - 16; int b = unprotectedRegistryValue.Length - 10; byte[] bytes = unprotectedRegistryValue[t..b]; byte[] year = bytes[0..2]; byte[] month = bytes[2..4]; byte[] day = bytes[4..6]; var yearDate = BitConverter.ToInt16(year); var monthDate = BitConverter.ToInt16(month); var dayDate = BitConverter.ToInt16(day); – carboneum Jun 14 '20 at 21:18