bee2.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. *******************************************************************************
  3. \file bee2.c
  4. \brief Bee2 DLL entry points
  5. \project bee2 [cryptographic library]
  6. \created 2013.02.25
  7. \version 2017.01.17
  8. \copyright The Bee2 authors
  9. \license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
  10. *******************************************************************************
  11. */
  12. #include <string.h>
  13. #include <stdio.h>
  14. #include <stdarg.h>
  15. #include <windows.h>
  16. #include <bee2/info.h>
  17. #include <bee2/core/blob.h>
  18. #include <bee2/core/err.h>
  19. #include <bee2/core/mem.h>
  20. #include <bee2/core/util.h>
  21. #include <bee2/core/stack.h>
  22. #include <bee2/crypto/belt.h>
  23. /*
  24. *******************************************************************************
  25. Прочитать / определить контрольную характеристику
  26. *******************************************************************************
  27. */
  28. #include "..\cmd\stamp\stamp_pe.c"
  29. static err_t beeReadAndCalcStamp(octet stampRead[STAMP_SIZE],
  30. octet stampCalc[STAMP_SIZE])
  31. {
  32. err_t code = ERR_OK;
  33. char name[MAX_PATH];
  34. HANDLE hFile, hMapping;
  35. DWORD size, offset;
  36. octet* image;
  37. void* hash_state;
  38. // имя модуля
  39. if (!GetModuleFileNameA(GetModuleHandleA("bee2.dll"), name, sizeof(name)))
  40. return ERR_SYS;
  41. // открыть файл
  42. hFile = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
  43. FILE_ATTRIBUTE_NORMAL, NULL);
  44. if (hFile == INVALID_HANDLE_VALUE)
  45. return ERR_FILE_OPEN;
  46. // длина файла
  47. size = SetFilePointer(hFile, 0, NULL, FILE_END);
  48. if (size == INVALID_SET_FILE_POINTER)
  49. {
  50. CloseHandle(hFile);
  51. return ERR_SYS;
  52. }
  53. // проецировать файл в память
  54. hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  55. if (hMapping == NULL)
  56. {
  57. CloseHandle(hFile);
  58. return ERR_SYS;
  59. }
  60. // отобразить файл в память
  61. image = (octet*)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
  62. if (image == NULL)
  63. {
  64. CloseHandle(hMapping), CloseHandle(hFile);
  65. return ERR_SYS;
  66. }
  67. // найти смещение контрольной характеристики
  68. offset = stampFindOffset(image, size);
  69. if (offset == (DWORD)-1)
  70. {
  71. UnmapViewOfFile(image), CloseHandle(hMapping), CloseHandle(hFile);
  72. return ERR_BAD_FORMAT;
  73. }
  74. // сохранить характеристику
  75. memCopy(stampRead, image + offset, STAMP_SIZE);
  76. // вычислить характеристику
  77. CASSERT(STAMP_SIZE >= 32);
  78. memSetZero(stampCalc, STAMP_SIZE);
  79. hash_state = blobCreate(beltHash_keep());
  80. if (hash_state)
  81. {
  82. // хэшировать
  83. beltHashStart(hash_state);
  84. beltHashStepH(image, offset, hash_state);
  85. beltHashStepH(image + offset + STAMP_SIZE,
  86. size - offset - STAMP_SIZE, hash_state);
  87. beltHashStepG(stampCalc, hash_state);
  88. blobClose(hash_state);
  89. }
  90. else
  91. code = ERR_OUTOFMEMORY;
  92. // очистка и выход
  93. UnmapViewOfFile(image);
  94. CloseHandle(hMapping);
  95. CloseHandle(hFile);
  96. return code;
  97. }
  98. /*
  99. *******************************************************************************
  100. Контроль целостности
  101. *******************************************************************************
  102. */
  103. static err_t beeSelfCheck()
  104. {
  105. // характеристики
  106. octet stampRead[STAMP_SIZE], stampCalc[STAMP_SIZE];
  107. err_t code = beeReadAndCalcStamp(stampRead, stampCalc);
  108. ERR_CALL_CHECK(code);
  109. // сравнить
  110. return memEq(stampRead, stampCalc, STAMP_SIZE) ? ERR_OK : ERR_BAD_HASH;
  111. }
  112. /*
  113. *******************************************************************************
  114. Печать форматированных данных в конец строки
  115. *******************************************************************************
  116. */
  117. static err_t beeSprintf(blob_t* str, const char* format,...)
  118. {
  119. va_list args;
  120. size_t offset;
  121. int count;
  122. // строка не пустая?
  123. offset = blobSize(*str);
  124. if (offset)
  125. {
  126. // проверка
  127. if (((char*)*str)[offset - 1] != '\0')
  128. return ERR_BAD_INPUT;
  129. // подправка
  130. --offset;
  131. }
  132. // сколько требуется символов?
  133. va_start(args, format);
  134. count = _vscprintf(format, args);
  135. va_end(args);
  136. if (count < 0)
  137. return ERR_BAD_INPUT;
  138. // выделение памяти
  139. *str = blobResize(*str, offset + (size_t)count + 1);
  140. if (*str == 0)
  141. return ERR_OUTOFMEMORY;
  142. // печать в строку
  143. va_start(args, format);
  144. vsprintf_s((char*)*str + offset, count + 1, format, args);
  145. va_end(args);
  146. // выйти
  147. return ERR_OK;
  148. }
  149. /*
  150. *******************************************************************************
  151. Печать информации о сборке
  152. *******************************************************************************
  153. */
  154. static err_t beePrintBuildInfo(blob_t* str)
  155. {
  156. // прочитать контрольную характеристику
  157. octet stampRead[STAMP_SIZE], stampCalc[STAMP_SIZE];
  158. err_t code = beeReadAndCalcStamp(stampRead, stampCalc);
  159. octet stamp[2 * STAMP_SIZE + STAMP_SIZE * 4 / 16 + 1], pos, *ptr;
  160. // ошибка чтения?
  161. if (code != ERR_OK)
  162. return beeSprintf(str,
  163. "Platform: Win%d\r\n"
  164. "Version: %s\r\n"
  165. "Stamp: read error",
  166. sizeof(size_t) == 4 ? 32 : 64,
  167. BEE2_VERSION);
  168. // напечатать контрольную характеристику
  169. for (pos = 0, ptr = stamp; pos < STAMP_SIZE; ++pos)
  170. {
  171. if (pos % 16 == 0)
  172. *ptr++ = '\r', *ptr++ = '\n', *ptr++ = ' ', *ptr++ = ' ';
  173. sprintf(ptr, "%02X", (unsigned)stampRead[pos]);
  174. ++ptr, ++ptr;
  175. }
  176. return beeSprintf(str,
  177. "Platform: Win%d\r\n"
  178. "Version: %s\r\n"
  179. "Stamp: %s [%s]",
  180. sizeof(size_t) == 4 ? 32 : 64,
  181. BEE2_VERSION,
  182. stamp,
  183. memEq(stampRead, stampCalc, STAMP_SIZE) ? "OK" : "error");
  184. }
  185. /*
  186. *******************************************************************************
  187. Обработчик сообщений диалогового окна
  188. *******************************************************************************
  189. */
  190. static BOOL CALLBACK beeLogoDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,
  191. LPARAM lParam)
  192. {
  193. // начало
  194. if (uMsg == WM_INITDIALOG)
  195. {
  196. blob_t str = 0;
  197. // печать информации о версии
  198. beePrintBuildInfo(&str);
  199. if (str != 0)
  200. {
  201. SetDlgItemTextA(hDlg, 102, (const char*)str);
  202. blobClose(str);
  203. }
  204. return TRUE;
  205. }
  206. // выход
  207. if (uMsg == WM_COMMAND &&
  208. HIWORD(wParam) == BN_CLICKED &&
  209. (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL))
  210. {
  211. EndDialog(hDlg, 0);
  212. return TRUE;
  213. }
  214. return FALSE;
  215. }
  216. /*
  217. *******************************************************************************
  218. Обработчик окон верхнего уровня (для поиска главного окна)
  219. *******************************************************************************
  220. */
  221. static BOOL CALLBACK beeEnumWindowsProc(HWND hWnd, LPARAM lParam)
  222. {
  223. // нулевой идентификатор присваивается System Idle Process?
  224. DWORD id = 0;
  225. // нашли?
  226. GetWindowThreadProcessId(hWnd, &id);
  227. if (id == GetCurrentProcessId())
  228. {
  229. *((HWND*)lParam) = hWnd;
  230. return FALSE;
  231. }
  232. return TRUE;
  233. }
  234. /*
  235. *******************************************************************************
  236. Найти главное окно
  237. *******************************************************************************
  238. */
  239. static HWND beeFindMainWindow()
  240. {
  241. HWND hWnd = 0;
  242. char title[1024];
  243. char title_tmp[8 + 8 + 2];
  244. // ищем обычное окно
  245. EnumWindows(beeEnumWindowsProc, (LPARAM)&hWnd);
  246. if (hWnd != 0)
  247. return hWnd;
  248. // ищем консольное окно (http://support.microsoft.com/kb/124103)
  249. if (GetConsoleTitleA(title, sizeof(title)) == 0)
  250. return 0;
  251. sprintf(title_tmp, "%08X/%08X", GetTickCount(), GetCurrentProcessId());
  252. if (!SetConsoleTitleA(title_tmp))
  253. return 0;
  254. Sleep(40);
  255. hWnd = FindWindowA(NULL, title_tmp);
  256. SetConsoleTitleA(title);
  257. return hWnd;
  258. }
  259. /*
  260. *******************************************************************************
  261. Напечатать лого
  262. *******************************************************************************
  263. */
  264. err_t beeLogo()
  265. {
  266. // вызвать диалог
  267. if (DialogBoxA(GetModuleHandleA("bee2.dll"),
  268. "BEELOGO", beeFindMainWindow(), (DLGPROC)beeLogoDlgProc) == -1)
  269. return ERR_SYS;
  270. return ERR_OK;
  271. }
  272. /*
  273. *******************************************************************************
  274. Точка входа
  275. *******************************************************************************
  276. */
  277. BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call,
  278. LPVOID lpReserved)
  279. {
  280. switch (ul_reason_for_call)
  281. {
  282. case DLL_PROCESS_ATTACH:
  283. case DLL_THREAD_ATTACH:
  284. case DLL_THREAD_DETACH:
  285. case DLL_PROCESS_DETACH:
  286. break;
  287. }
  288. return TRUE;
  289. }