123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /*
- *******************************************************************************
- \file stamp.c
- \brief Integrity control of Windows PE Executables
- \project bee2/cmd
- \created 2011.10.18
- \version 2023.10.09
- \copyright The Bee2 authors
- \license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
- *******************************************************************************
- */
- #include "../cmd.h"
- #include <bee2/core/blob.h>
- #include <bee2/core/err.h>
- #include <bee2/core/mem.h>
- #include <bee2/core/str.h>
- #include <bee2/core/util.h>
- #include <bee2/crypto/belt.h>
- #include <windows.h>
- #include <stdio.h>
- /*
- *******************************************************************************
- Работа с PE-файлом
- *******************************************************************************
- */
- #include "stamp_pe.c"
- /*
- *******************************************************************************
- Утилита stamp
- Функционал:
- - добавление в исполнимый файл Windows контрольной суммы;
- - проверка контрольной суммы.
- Контрольная сумма представляет собой строку из STAMP_SIZE октетов, которая
- добавляется в исполнимый файл как строковый ресурс с идентификатором STAMP_ID.
- *******************************************************************************
- */
- static const char _name[] = "stamp";
- static const char _descr[] = "integrity control of Windows PE executables";
- static int stampUsage()
- {
- printf(
- "bee2cmd/%s: %s\n"
- "Usage:\n"
- " stamp -s <file>\n"
- " set a stamp on <file>\n"
- " stamp -c <file>\n"
- " check a stamp of <file>\n"
- "\\pre <file> is a PE-module (exe or dll)\n"
- "\\pre <file> contains the user-defined resource\n"
- " %d %d {\"0123456789ABCDEF0123456789ABCDEF\"}\n"
- ,
- _name, _descr,
- STAMP_ID, STAMP_TYPE
- );
- return -1;
- }
- /*
- *******************************************************************************
- Вспомогательные функции
- *******************************************************************************
- */
- void stampPrint(const octet* stamp, const char* stamp_name)
- {
- size_t pos;
- printf(stamp_name ? "[%s = " : "[", stamp_name);
- for (pos = 0; pos < STAMP_SIZE; ++pos)
- printf("%02X", stamp[pos]);
- printf("]\n");
- }
- /*
- *******************************************************************************
- Работа с контрольными характеристиками
- *******************************************************************************
- */
- static int stampSet(const char* name)
- {
- HANDLE hFile;
- DWORD size;
- HANDLE hMapping;
- octet* image;
- DWORD offset;
- void* hash_state;
- // открыть файл
- hFile = CreateFileA(name, GENERIC_READ | GENERIC_WRITE,
- 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- printf("File \"%s\" was not found or could not be open.\n", name);
- return -1;
- }
- // длина файла
- size = SetFilePointer(hFile, 0, NULL, FILE_END);
- if (size == INVALID_SET_FILE_POINTER)
- {
- CloseHandle(hFile);
- printf("Error processing the file \"%s\".\n", name);
- return -1;
- }
- // проецировать файл в память
- hMapping = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
- if (hMapping == NULL)
- {
- CloseHandle(hFile);
- printf("Error processing the file \"%s\".\n", name);
- return -1;
- }
- // отобразить файл в память
- image = (octet*)MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);
- if (image == NULL)
- {
- CloseHandle(hMapping);
- CloseHandle(hFile);
- printf("Error processing the file \"%s\".\n", name);
- return -1;
- }
- // найти смещение контрольной характеристики
- offset = stampFindOffset(image, size);
- if (offset == (DWORD)-1)
- {
- UnmapViewOfFile(image);
- CloseHandle(hMapping);
- CloseHandle(hFile);
- printf("A stamp of \"%s\" was not found or corrupted.\n", name);
- return -1;
- }
- // подготовить место для контрольной характеристики
- CASSERT(STAMP_SIZE >= 32);
- memSetZero(image + offset, STAMP_SIZE);
- // стек хэширования
- hash_state = blobCreate(beltHash_keep());
- if (!hash_state)
- {
- UnmapViewOfFile(image);
- CloseHandle(hMapping);
- CloseHandle(hFile);
- printf("Insufficient memory.\n");
- return -1;
- }
- // хэшировать
- beltHashStart(hash_state);
- beltHashStepH(image, offset, hash_state);
- beltHashStepH(image + offset + STAMP_SIZE,
- size - offset - STAMP_SIZE, hash_state);
- beltHashStepG(image + offset, hash_state);
- blobClose(hash_state);
- // печать
- printf("A stamp successfully added to \"%s\"\n", name);
- stampPrint(image + offset, "stamp");
- // завершение
- UnmapViewOfFile(image);
- CloseHandle(hMapping);
- CloseHandle(hFile);
- return 0;
- }
- // проверить характеристику
- static int stampCheck(const char* name)
- {
- HANDLE hFile;
- DWORD size;
- HANDLE hMapping;
- octet* image;
- DWORD offset;
- octet stamp[STAMP_SIZE];
- void* hash_state;
- bool_t success;
- // открыть файл
- hFile = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- printf("File \"%s\" was not found or could not be open.\n", name);
- return -1;
- }
- // длина файла
- size = SetFilePointer(hFile, 0, NULL, FILE_END);
- if (size == INVALID_SET_FILE_POINTER)
- {
- CloseHandle(hFile);
- printf("Error processing the file \"%s\".\n", name);
- return -1;
- }
- // проецировать файл в память
- hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
- if (hMapping == NULL)
- {
- CloseHandle(hFile);
- printf("Error processing the file \"%s\".\n", name);
- return -1;
- }
- // отобразить файл в память
- image = (octet*)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
- if (image == NULL)
- {
- CloseHandle(hMapping);
- CloseHandle(hFile);
- printf("Error processing the file \"%s\".\n", name);
- return -1;
- }
- // найти смещение контрольной характеристики
- offset = stampFindOffset(image, size);
- if (offset == (DWORD)-1)
- {
- UnmapViewOfFile(image);
- CloseHandle(hMapping);
- CloseHandle(hFile);
- printf("A stamp of \"%s\" was not found or corrupted.\n", name);
- return -1;
- }
- // подготовить место для контрольной характеристики
- CASSERT(STAMP_SIZE >= 32);
- memSet(stamp, 0, STAMP_SIZE);
- // состояние хэширования
- hash_state = blobCreate(beltHash_keep());
- if (!hash_state)
- {
- UnmapViewOfFile(image);
- CloseHandle(hMapping);
- CloseHandle(hFile);
- printf("Insufficient memory.\n");
- return -1;
- }
- // хэшировать
- beltHashStart(hash_state);
- beltHashStepH(image, offset, hash_state);
- beltHashStepH(image + offset + STAMP_SIZE,
- size - offset - STAMP_SIZE, hash_state);
- beltHashStepG(stamp, hash_state);
- blobClose(hash_state);
- // сравнить
- success = memEq(image + offset, stamp, STAMP_SIZE);
- printf("Validating \"%s\"... %s\n", name, success ? "OK" : "Failed");
- if (success)
- stampPrint(image + offset, "stamp");
- else
- stampPrint(image + offset, "read_stamp"),
- stampPrint(stamp, "calc_stamp");
- // завершение
- UnmapViewOfFile(image);
- CloseHandle(hMapping);
- CloseHandle(hFile);
- return 0;
- }
- /*
- *******************************************************************************
- Главная функция
- *******************************************************************************
- */
- int stampMain(int argc, char* argv[])
- {
- // справка
- if (argc != 3)
- return stampUsage();
- // разбор команды
- --argc, ++argv;
- if (strEq(argv[0], "-s"))
- return stampSet(argv[1]);
- if (strEq(argv[0], "-c"))
- return stampCheck(argv[1]);
- return -1;
- }
- /*
- *******************************************************************************
- Инициализация
- *******************************************************************************
- */
- err_t stampInit()
- {
- return cmdReg(_name, _descr, stampMain);
- }
|