NSIS: контрольная сумма (MD5), сравнение файлов.

Преамбула

В принципе, патч или кряк для программы можно сделать с помощью NSIS, конечно, это будет не классический патч, т.е., когда меняешь в исходном экзешнике несколько байт, а архив с готовым экзешником и сценарием установки. Но зато и возможностей больше, можно Реестр или INI-файлы подправить, например.

Но одна из главных задач любого патча, перед началом работы проверить, а не пропатчен ли файл уже. Делается это обычно так — берется контрольная сумма MD5 или CRC32 оригинального файла и сравнивается с заранее известной суммой. Если совпадает — файл наш, можно патчить. Можно и наоборот — сравнить контрольную сумму оригинального файла с известной контрольной суммой пропатченного, если они равны — файл уже модифицирован, сообщаем пользователю и завершаем работу.

Получение MD5-суммы в NSIS.

Для получения MD5 в NSIS имеется плагин MD5 Plugin.

Скачиваем архив, копируем md5dll.dll из директории ANSI архива в директорию ANSI-плагинов NSIS (у меня C:\Program Files (x86)\NSIS\Plugins\x86-ansi\), а из директории UNICODE архива в директорию UNICODE-плагинов (C:\Program Files (x86)\NSIS\Plugins\x86-unicode). Понятно, что пути к вашим каталогам плагинов могут отличаться, т.к. зависят от того, куда установлен NSIS/

Примеры использования

Вычисление контрольной суммы строки:

#generate MD5sum of string
md5dll::GetMD5String "TestString"
Pop $0
DetailPrint "MD5 (string): [$0]"

Вывод:
MD5 (string): [5b56f40f8828701f97fa4511ddcd25fb]

Получение случайного хэша MD5:

#generate random MD5sum
md5dll::GetMD5Random
Pop $0
DetailPrint "MD5 (random): [$0]"

Вывод:

MD5 (random): [864fd151525efad56947f25fa3daeb75]

Получение контрольной суммы файла:

#generate MD5sum of file
DetailPrint "MD5 sum of file $EXEDIR\test\1.exe"
md5dll::GetMD5File "$EXEDIR\test\1.exe"
Pop $0
DetailPrint "MD5 (file): [$0]"

Вывод:

MD5 sum of file C:\!\Installers\MD5Sample\test\1.exe
MD5 (file): [03f3ba055d9f325c9abc90181f82657b]

Сравнение файлов

Для более красивого кода сравнения, рекомендую подключить инклюд с макросами логических операторов LogicLib.nsh (есть в комплекте NSIS):

!include LogicLib.nsh

Пример:

md5dll::GetMD5File "$EXEDIR\test\1.exe"
Pop $0
md5dll::GetMD5File "$EXEDIR\test\3.exe"
Pop $1
DetailPrint "Files $EXEDIR\test\1.exe"
DetailPrint "and   $EXEDIR\test\3.exe"
DetailPrint "MD5: $0" 
DetailPrint "and   $1"
${If} $0 == $1
	DetailPrint "IS IDENTICAL!"
${Else}
	DetailPrint "IS DIFFERENT!"
${EndIf}

Пример вывода (сравниваются два одинаковых файла, а потом два разных):

Files C:\!\Installers\MD5Sample\test\1.exe
and C:\!\Installers\MD5Sample\test\2.exe
MD5: 03f3ba055d9f325c9abc90181f82657b
and 03f3ba055d9f325c9abc90181f82657b
IS IDENTICAL!
Files C:\!\Installers\MD5Sample\test\1.exe
and C:\!\Installers\MD5Sample\test\3.exe
MD5: 03f3ba055d9f325c9abc90181f82657b
and 7baeee10b3cd6c210c4fcd61b92b8e1e
IS DIFFERENT!

Ошибки при работе библиотеки MD5

Если файл отсутствует, то функция md5dll::GetMD5File может выдать непредсказуемый результат, строку случайных символов, поэтому, перед использованием md5dll::GetMD5File следует проверять наличие и доступность файлов.

Ссылки

Библиотека:
— Описание на официальном сайте: MD5 plugin
Скачать с официального сайта
Зеркало
Копия (v 0.5) на Mega.nz

Пример из заметки целиком на GitHub

Программа, которая ничего не делает.

Преамбула

Да, понадобилась мне такая программа под Win32, которая совсем ничего не делает. Запускается, и сразу завершает работу, не открывая окна консоли и не создавая окно GUI. Для чего, расскажу в другой раз. Встал вопрос, на чем писать. .NET не подходит — слишком уж за такой программой Framework таскать, был Lasarus, но, если честно, не понял, как там все правильно сделать. И тут осенило, есть же TASM, идеально подходящий для такой задачи, будет максимально маленький экзешник, требующий только одну функцию из WinAPI — ExitProcess. Самое то! Правда, на ассемблере я кодил в лохматых годах, так что пришлось немного повспоминать.

Листинг

.386
.MODEL FLAT

	extrn ExitProcess:proc

.DATA
	szHelp DB 'This program start and end'
.CODE
Start:
	nop
	nop
	nop
	push	0
	call	ExitProcess
end	Start

На PasteBin

Описание

.386 — директива, позволяющая ассемблировать инструкции i386-го процессора, нам хватит.
.MODEL FLAT — выбор стандартной в Win32 модели памяти (FLAT)

extrn ExitProcess:proc — директива extrn позволяет использовать в программе функцию (тут ExitProcess) из внешней библиотеки, которую подключим на этапе линковки.
Библиотека IMPORT32.LIB, содержащая основные функции WinAPI должна быть в комплекте TASM.

.DATA — начало сегмента данных, в принципе, в этой программе можно его просто определить и не заполнять, но я определю в нем строку, которая будет храниться прямо в в экзешнике, как его описание. Можно открыть экзешник по F3 в Far’е, например, и увидеть ее. При работе программы строка использоваться не будет.

szHelp DB 'This program start and end' — та самая строчка.

.CODE — Сегмент кода.

Start: — метка, обозначающая точку входа в программу. Можно назвать хоть как (Start, Main и т.д.).

nopпустая операция, процессор в буквальном смысле делает ничего. Можно пропустить, но пусть будет.

push 0 — кладем в стек код возврата, который будет использован функцией ExitProcess.

end Start — конец основной функции программы.

Сборка экзешника

Компиляция:

tasm32 /m simple.asm

где:

/ml — учитывать регистр символов при компиляции.
simple.asm — имя файла с исходником.

Получилось:

Assembling file:   simple.asm
Error messages:    None
Warning messages:  None
Passes:            1

Будет создан файл simple.OBJ

Линковка:

tlink32 /Tpe /aa simple.OBJ,,,IMPORT32.LIB

где:

/Tpe — создать на выходе Win32 PE-файл (Стандартный формат 32-х битного экзешника, начиная с Windows 95).
/aa — Использовать WinAPI

Примечание: Библиотека IMPORT32.LIB должна лежать в том же каталоге, где и simple.OBJ, или прописывайте полный путь к файлам

Больше простых примеров с описанием (на буржуйском)

Writing Win32 programs in assembly language using TASM:
Читать на tolik-punkoff.com
Читать на lj.rossia.org
— Скачать с Mega.NZ
Скачать с Google.Drive

Переключение раскладки на экранной клавиатуре Windows 7

По-прежнему, чиним деньгополдощательные терминалы и всякие прочие АРМ, потому понадобилось, заметка от склероза, чтоб не забыть, да и другим полезно будет.

Вызов экранной клавиатуры

Рассматриваем способы, как ее вызвать, если доступа к физической клавиатуре нет совсем.

1. ПУСК —> Все программы —> Стандартные —> Специальные возможности —> Экранная клавиатура
2. Добираемся мышекликом до экзешника: %windir%\system32\osk.exe

Где %windir% — каталог с установленной Windows (обычно C:\Windows).

Если надо вызвать программу с командной строки (для справки), то соответственно, команда: osk

Примечание: Экранная клавиатура, как и физическая, поддерживает только раскладки клавиатуры (языки ввода) установленные в системе, т.е., если русский язык, например, в системе не установлен совсем, то и переключиться на наго нельзя.

Способ №1

Самый простой. Не пользоваться для переключения языка ввода и раскладки экранной клавиатурой, все спокойно можно делать мышью, с помощью значка индикатора клавиатуры в системном трее.

Способ №2

Щелкаем те же клавиши, которые установлены для переключения клавиатуры в системе, и не задерживаясь, нажимаем ту, с которой начали. Т.е. если переключение клавиатуры настроено на Alt+Shift, то на экранной клавиатуре жмем Alt, потом Shift (или наоборот, сначала Shift потом Alt), а потом возвращаемся к первой клавише, если первой нажимали Alt — нажимаем Alt второй раз, если первый раз нажимали Shift — второй раз нажимаем Shift.

Если в системе установлена комбинация Ctrl+Shift, действия аналогичны, только нажимаем соответствующие клавиши на экранной клавиатуре

Переключение раскладки:

Раскладка переключилась:

ТЕЛЕМАРКЕТ!