У меня каверзный вопрос, и я надеюсь, что смогу объяснить это хорошо,
Я хочу прочитать значение из реестра Windows, которое сохранено другой программой, источник которой у меня отсутствует, но я уже знаю тип этого значения, и оно выглядит следующим образом:
_MyData = record
byteType: Byte;
encData: PByte;
end;
byteType указывает тип этих данных в виде целого числа (1,2,3…), вы можете забыть об этом параметре, в то время как encData - это зашифрованные данные с использованием windows crypt32. функция dll (CryptProtectData)
Я использую следующий код для чтения значения из реестра:
procedure TForm1.Button2Click(Sender: TObject);
var
myData: _MyData;
reg: TRegistry;
valueSize: Integer;
begin
reg := TRegistry.Create;
try
if reg.OpenKey(KEY_PATH,false) then
Begin
valueSize := reg.GetDataSize(VALUE_NAME);
reg.ReadBinaryData(VALUE_NAME, myData, valueSize);
End;
finally
reg.Free;
end;
end;
// KEY_PATH, VALUE_NAME являются строковыми символами.
Итак, теперь у меня есть зашифрованные данные в myData.encData , и теперь я хочу расшифровать их, передав ей функцию CryptUnprotectData, которая имеет эту подпись:
function CryptUnprotectData(pDataIn: PDATA_BLOB; ppszDataDescr: PLPWSTR; pOptionalEntropy: PDATA_BLOB; pvReserved: Pointer; pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT; dwFlags: DWORD; pDataOut: PDATA_BLOB): BOOL; stdcall;
Сначала мне нужно поместить зашифрованные данные в переменную типа DATA_BLOB, которая имеет такую структуру:
_CRYPTOAPI_BLOB = record
cbData: DWORD;
pbData: PBYTE;
end;
DATA_BLOB = _CRYPTOAPI_BLOB;
PDATA_BLOB = ^DATA_BLOB;
pbData - указатель на зашифрованные данные (я читаю их из реестра), а cbData - размер зашифрованных данных, и вот моя проблема У меня есть указатель зашифрованные данные (я уже прочитал их из реестра) в myData.encData, который является PByte, но я не знаю, как получить размер этих данных? и если я не даю функции CryptUnprotectData правильный размер, он всегда дает ноль в выходной, Есть идеи, как это сделать?
Спасибо за вашу помощь.
Редактировать: решение, благодаря Кену Бурассе
_MyData = packed record
byteType: Byte;
encData: array of byte;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
myData: ^_MyData;
reg: TRegistry;
valueSize: Integer;
dataIn, dataOut: DATA_BLOB;
begin
reg := TRegistry.Create;
try
if reg.OpenKey(KEY_PATH,false) then
Begin
valueSize := reg.GetDataSize(VALUE_NAME);
GetMem(myData, ValueSize);
try
reg.ReadBinaryData(VALUE_NAME, myData^, valueSize);
dataOut.cbData := 0;
dataOut.pbData := nil;
dataIn.cbData := Valuesize - SizeOf(Byte);
dataIn.pbData := @myData.encData;
CryptUnprotectData(@dataIn,nil,nil,nil,nil,CRYPTPROTECT_UI_FORBIDDEN,@dataOut);
//yes, it works, Thank you very much Ken Bourassa
finally
FreeMem(myData);
End;
End;
finally
reg.Free;
end;
end;