Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» CryptoAPI- проверить подпись драйвера

Автор: ofchar
Дата сообщения: 13.12.2008 08:27
Пишу программку, стоит задача проверить подпись приличного количества фалов, работая в PE. SignTool verify работает, но медленно. Если парсить ее вывод, будет еще дольше. Хотел попробовать через API, да вот не могу разобраться с механизмом.
Пытаюсь делать так:

procedure TForm1.Button1Click(Sender: TObject);
var
Prov: HCRYPTPROV;
sKey: HCRYPTKEY;
Stream: TMemoryStream;
Hash: HCRYPTHASH;
F: TMemoryStream;//TFileStream;
Rez: boolean;
Sign: string;
Size: DWORD;
BufLen: DWORD;
b: boolean;
err: DWORD;
begin
Sign:='';
F:=TMemoryStream.Create;
F.LoadFromFile('c:\windows\system32\drivers\acpi.sys');
Size:=F.Size;
b:=CryptAcquireContext(@Prov,nil,nil,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT); //true
b:=CryptCreateHash(Prov,CALG_MD5,0,0,@Hash); // true
b:=CryptHashData(Hash,PByte(F.Memory),Size,0); // true
// Получили хэш файла, вроде бы. Дальше нужно получить подпись хэша,
// используя какой-то ключ, и сверить с подписью, которая где-то хранится.
// Где брать ключ - не пойму, где хранится подпись - тоже.
SetLastError(0);
BufLen:=0;
b:=CryptSignHash(Hash,AT_SIGNATURE,nil,0,nil,@BufLen); // false
if b then Memo1.Lines.Add('YES') ;
err:= GetLastError; // 0x80090016
// Логично, ключ не выбран
if BufLen>0 then begin
SetLength(Sign,BufLen);
CryptSignHash(Hash,AT_SIGNATURE,nil,0,PByte(Sign),@BufLen);
end;
Rez:=CryptVerifySignature(Hash,PByte(Sign),Length(Sign),sKey,nil,0);
if Rez then Memo1.Lines.Add('YES') else Memo1.Lines.Add('NO');

F.Free;
CryptDestroyHash(Hash);
CryptReleaseContext(Prov,0);
end;

Вот такая ботва.
Автор: dmka
Дата сообщения: 13.12.2008 18:42
WinVerifyTrust Function
http://msdn.microsoft.com/en-us/library/aa388208.aspx

Еxample C Program: Verifying the Signature of a PE File.
http://msdn.microsoft.com/en-us/library/aa382384(VS.85).aspx
Автор: ofchar
Дата сообщения: 15.12.2008 10:50
dmka
Спасибо огромное. Не стой стороны я MSDN рыл.

Добавлено:
Задаю DRIVER_ACTION_VERIFY({F750E6C3-38EE-11d1-85E5-00C04FC295EE}), получаю 800B0001 (TRUST_E_PROVIDER_UNKNOWN).
Заменил на WINTRUST_ACTION_GENERIC_VERIFY ( TGUID = '{189A3842-3041-11D1-85E1-00C04FC295EE}') тоже пытался, для интереса. Подсунул explorer.exe, с тем же результатом.
Автор: dmka
Дата сообщения: 15.12.2008 15:44
ofchar
попробуй еще WINTRUST_ACTION_GENERIC_VERIFY_V2...

Вообще в explorer.exe и других системных файлах подпись не в самом файле (как в примере), а в отдельном каталоге. Там нужно делать примерно так:

//получаешь хэш файла
CryptCATAdminCalcHashFromFileHandle

// ищешь каталог
CryptCATAdminEnumCatalogFromHash

// получаешь имя каталога
CryptCATCatalogInfoFromContext

// проверяешь файл
WTData.dwUnionChoice = WTD_CHOICE_CATALOG;
WTCatalogInfo.pcwszCatalogFilePath = sCatInfo.wszCatalogFile;
GUID WVTPolicyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WinVerifyTrust
Автор: ofchar
Дата сообщения: 16.12.2008 08:29
dmka
Попробую. Но, меня терзают смутные сомненья...
Программа будет исследовать "больную" систему "извне". Грузится предполагается с PE.
В обычных условиях с этой задачей прекрасно справляется AVZ. Подозреваю, что начнется путаница с переменными окружения.
Судя по названию функции, в системе должен где-то храниться некий указатель на исследуемый файл. Или каталог придется указывать явно. Я VerifyTool запускал под PE без указания каталога - не получилось. Потом выкрал из нормальной XP файл NT5.CAT, подсунул - заработало.
Ладно, не догоню, так согреюсь.
PS. Мне казалось(перед стартом), что где-то должен храниться список контрольных сумм, без указания файла даже. Например, MD5. Поскольку MD5 считается уникальной( коллизии не часты), достаточно подсчитать КС файла и проверить, есть ли такая же в базе безопасных. Ну, для скорости обработки, можно где-то, например в PE-заголовке, прописывать индекс.
Автор: ofchar
Дата сообщения: 17.12.2008 12:56
dmka
Спасибо. Нашел у немцев исходник модуля на паскале, вот ссылка для интересующихся любителей delphi: http://www.delphipraxis.net/post329268.html
Переделал модуль в GUIевое приложение, под обычной виндой работает. Под PE -нет.
Я откопал сборку PE, где запускается служба криптографии, пытался импортировать в реестр соответствующую ветку из обычной винды - все пока безрезультатно. Хотя, wintrust.dll в сборке есть. Да и в LoadLibrary я путь пробовал указать к либе, лежащей на HDD (у них размер разный, что меня насторожило).
Еще раз спасибо. Теперь буду выяснять, чего не хватает.

Страницы: 1

Предыдущая тема: Функция Лапласа на Делфи


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.