Что нового

Как определить наличие цифровой подписи в exe файле?

gora

Знающий
Сообщения
315
Репутация
19
Как определить наличие цифровой подписи в exe файле?
Желательно без использования сторонних утилит, только средствами Autoit.
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
beliy [?]
gora [?]
Желательно без использования сторонних утилит, только средствами Autoit.
А там требуется сторонняя утилита.
beliy
Скрипт в посте не выводит информации о наличии цифровой подписи.
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,590
Репутация
341
gora
А на немецкий форум ты заходил из этой ветки? Там лежал скрипт WinTrust.au3 и кажется это то что тебе нужно.
Файл WinTrust.au3
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
Medic84 [?]
WinTrust.au3 и кажется это то что тебе нужно
Смотрел, но он у меня на файлах без подписи выдает:
An unknown error occurred trying to verify the signature of the "%s" file.
Хотя по логике должно быть:
The file "%s" is not signed or does not exist
А при попытке запуска на виртуалке (тоже Win7 x64) вообще зависает и с большой задержкой вываливается с ошибкой:
---------------------------

---------------------------
Error is: 0x800b0109.

---------------------------
ОК
---------------------------
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
Значит решения нет? AutoIt, своими средствами, этого сделать не может?
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
gora
Может найдешь для себя что-то
полезное в этой статье
http://habrahabr.ru/post/104333/
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,590
Репутация
341
Код:
#include <Array.au3>

Const $xStart = "50450000" ;заголовок
Const $xOffset = 148 * 2 ;смещение до контрольной суммы относительно заголовка
Const $sPtrn = '(..)'

$sPathLog = "C:\Users\Дмитрий\Downloads\autoit-v3-setup.exe"

$hOpen = FileOpen($sPathLog,16)
$sFounded = StringRegExp(FileRead($hOpen,1024), $xStart & ".{" & $xOffset & "}(.{8})(.{8}).*",3)
FileClose($hOpen)

If IsArray($sFounded) And UBound($sFounded) = 2 Then
	$sFounded[0] = StringRegExpReplace($sFounded[0], $sPtrn & $sPtrn & $sPtrn & $sPtrn, '$4$3$2$1')
	$sFounded[1] = StringRegExpReplace($sFounded[1], $sPtrn & $sPtrn & $sPtrn & $sPtrn, '$4$3$2$1')
	
	$hSum = Dec($sFounded[0]) + Dec($sFounded[1])

	If Dec($sFounded[0]) = 0 And Dec($sFounded[1]) = 0 Then
		MsgBox(64,"Информация","Файл НЕ подписан сертификатом")
		Exit
	ElseIf Dec($sFounded[0]) = 0 or Dec($sFounded[1]) = 0 Then
		MsgBox(16,"Информация","Сертификат битый")
		Exit
	EndIf

	If Hex($hSum,16) <> Hex(FileGetSize($sPathLog),16) Then
		MsgBox(16,"Ошибка","Файл\сертификат битый")
	Else
		MsgBox(64,"Информация","Файл подписан сертификатом" & @CRLF & "Адрес: 0x" & $sFounded[0] & @CRLF & "Длинна сертификата: 0x" & $sFounded[1])
	EndIf
	
Else
	MsgBox(16,"Ошибка","Не найдена сигнатура PE формата")
EndIf

Конечный вариант.
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,590
Репутация
341
Код:
#include <Array.au3>

Const $xStart = "50450000" ;заголовок
Const $xOffset = 148 * 2 ;смещение до контрольной суммы относительно заголовка
Const $sPtrn = '(..)'

$sPathLog = "C:\Users\Дмитрий\Downloads\autoit-v3-setup.exe"

$hOpen = FileOpen($sPathLog,16)
$sFounded = StringRegExp(FileRead($hOpen,1024), $xStart & ".{" & $xOffset & "}(.{8})(.{8}).*",3)


If IsArray($sFounded) And UBound($sFounded) = 2 Then
	$sFounded[0] = StringRegExpReplace($sFounded[0], $sPtrn & $sPtrn & $sPtrn & $sPtrn, '$4$3$2$1')
	$sFounded[1] = StringRegExpReplace($sFounded[1], $sPtrn & $sPtrn & $sPtrn & $sPtrn, '$4$3$2$1')
	$hSum = Dec($sFounded[0]) + Dec($sFounded[1])

	If Dec($sFounded[0]) = 0 And Dec($sFounded[1]) = 0 Then
		MsgBox(64,"Информация","Файл НЕ подписан сертификатом")
		Exit
	ElseIf Dec($sFounded[0]) = 0 or Dec($sFounded[1]) = 0 Then
		MsgBox(16,"Информация","Сертификат битый")
		Exit
	EndIf

	If Hex($hSum,16) <> Hex(FileGetSize($sPathLog),16) Then
		MsgBox(16,"Ошибка","Файл\сертификат битый")
	Else
		FileSetPos($hOpen, Dec($sFounded[0]) ,0)
		$sRead = FileRead($hOpen,Dec($sFounded[1]))
		$sLengtName = StringRegExp($sRead, "060355040313(.{2}).*",3)
		$sSignName = StringRegExp($sRead, "060355040313.{2}(.{" & (Dec($sLengtName[0])*2) & "}).*",3)
		MsgBox(64,"Информация","Файл подписан сертификатом" & @CRLF & "Адрес: 0x" & _
		$sFounded[0] & @CRLF & "Длинна сертификата: " & (Dec($sFounded[1])) & " байт" & @CRLF & "Имя издателя: " & BinaryToString("0x"&$sSignName[0],4))
	EndIf

Else
	MsgBox(16,"Ошибка","Не найдена сигнатура PE формата")
EndIf

FileClose($hOpen)


Дополненный вариант, добавлено Имя издателя.
 
Автор
G

gora

Знающий
Сообщения
315
Репутация
19
Yuriy [?]
Может найдешь для себя что-то
полезное в этой статье
Спасибо.
Но, к сожалению, описанный метод поиска цифровой подписи неработоспособен. Просмотрел несколько файлов с подписью и обнаружил, что информация о ней не всегда находится по указанному в статье значению.
22.PNG

Красным выделено, расположение сигнатуры PE (50450000h), и со смешением 98h предполагаемое расположение данных о положении цифровой подписи. Зеленым выделено истинное расположение данных.

Другие варианты есть?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
А я делаю так:

Код:
Func _IsSign($sFile)

	Local $Result

	If Not FileExists($sFile) Then
		Return SetError(1, 0, 0)
	EndIf
;~	$Result = DllCall('crypt32.dll', 'bool', 'CryptQueryObject', 'dword', $CERT_QUERY_OBJECT_FILE, 'wstr', $sFile, 'dword', $CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, 'dword', $CERT_QUERY_FORMAT_FLAG_BINARY, 'dword', 0, 'dword*', 0, 'dword*', 0, 'dword*', 0, 'handle*', 0, 'handle*', 0, 'ptr', 0)
	$Result = DllCall('crypt32.dll', 'bool', 'CryptQueryObject', 'dword', 0x0001, 'wstr', $sFile, 'dword', 0x0400, 'dword', 0x0002, 'dword', 0, 'dword*', 0, 'dword*', 0, 'dword*', 0, 'handle*', 0, 'handle*', 0, 'ptr', 0)
	If (@Error) Or (Not $Result[0]) Then
		Return SetError(2, 0, 0)
	EndIf
;~	If $Result[7] = $CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED Then
	If $Result[7] = 10 Then
		Return 1
	Else
		Return 0
	EndIf
EndFunc   ;==>_IsSign
 
Верх