migration
2
semester-4/ОС/lb-3/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
Викладач: Мельникова Р. В.
|
||||
Оцінка: 96
|
BIN
semester-4/ОС/lb-3/img/1/check.png
Normal file
After Width: | Height: | Size: 219 KiB |
BIN
semester-4/ОС/lb-3/img/1/def.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
semester-4/ОС/lb-3/img/1/dll_load.png
Normal file
After Width: | Height: | Size: 228 KiB |
BIN
semester-4/ОС/lb-3/img/1/func_types.png
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
semester-4/ОС/lb-3/img/1/h.png
Normal file
After Width: | Height: | Size: 125 KiB |
BIN
semester-4/ОС/lb-3/img/1/just.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
semester-4/ОС/lb-3/img/1/just2.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
semester-4/ОС/lb-3/img/1/result.png
Normal file
After Width: | Height: | Size: 225 KiB |
BIN
semester-4/ОС/lb-3/img/2/just_app.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
semester-4/ОС/lb-3/img/2/just_locale.png
Normal file
After Width: | Height: | Size: 135 KiB |
BIN
semester-4/ОС/lb-3/img/2/locale_cpp.png
Normal file
After Width: | Height: | Size: 280 KiB |
BIN
semester-4/ОС/lb-3/img/2/locale_en.rc.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
semester-4/ОС/lb-3/img/2/locale_h.png
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
semester-4/ОС/lb-3/img/2/locale_ua.rc.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
semester-4/ОС/lb-3/img/2/main.png
Normal file
After Width: | Height: | Size: 276 KiB |
BIN
semester-4/ОС/lb-3/img/2/result_en.png
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
semester-4/ОС/lb-3/img/2/result_ua.png
Normal file
After Width: | Height: | Size: 114 KiB |
BIN
semester-4/ОС/lb-3/img/3/append.png
Normal file
After Width: | Height: | Size: 247 KiB |
BIN
semester-4/ОС/lb-3/img/3/crc.def.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
semester-4/ОС/lb-3/img/3/crc.h.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
semester-4/ОС/lb-3/img/3/just.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
semester-4/ОС/lb-3/img/3/main.png
Normal file
After Width: | Height: | Size: 230 KiB |
BIN
semester-4/ОС/lb-3/img/3/rsa.png
Normal file
After Width: | Height: | Size: 238 KiB |
BIN
semester-4/ОС/lb-3/img/3/table.png
Normal file
After Width: | Height: | Size: 88 KiB |
BIN
semester-4/ОС/lb-3/img/3/test.png
Normal file
After Width: | Height: | Size: 200 KiB |
BIN
semester-4/ОС/lb-3/img/3/test_rsa.png
Normal file
After Width: | Height: | Size: 321 KiB |
BIN
semester-4/ОС/lb-3/img/3/update.png
Normal file
After Width: | Height: | Size: 98 KiB |
BIN
semester-4/ОС/lb-3/img/3/verify.png
Normal file
After Width: | Height: | Size: 261 KiB |
17
semester-4/ОС/lb-3/src/.clangd
Normal file
@ -0,0 +1,17 @@
|
||||
CompileFlags:
|
||||
Add: [-Wall, -Wextra, -std=c++17, -DBUILD_SHARED, --target=x86_64-w64-mingw32]
|
||||
CompilationDatabase: build/
|
||||
|
||||
Diagnostics:
|
||||
UnusedIncludes: Strict
|
||||
|
||||
InlayHints:
|
||||
Enabled: Yes
|
||||
ParameterNames: Yes
|
||||
DeducedTypes: Yes
|
||||
|
||||
Index:
|
||||
Background: Build
|
||||
|
||||
Hover:
|
||||
ShowAKA: Yes
|
65
semester-4/ОС/lb-3/src/Justfile
Normal file
@ -0,0 +1,65 @@
|
||||
cc := "x86_64-w64-mingw32-clang++"
|
||||
cc_flags := "-Wall -Wextra -std=c++17"
|
||||
|
||||
windres := "x86_64-w64-mingw32-windres"
|
||||
|
||||
@clean:
|
||||
rm -rf build
|
||||
|
||||
@mkdir-build: clean
|
||||
mkdir -p build
|
||||
|
||||
# Locale
|
||||
# ===================================================
|
||||
|
||||
@build-locale-ua: mkdir-build
|
||||
{{windres}} -c 65001 locale/ua/locale.rc -O coff -o build/locale-en.res
|
||||
{{cc}} {{cc_flags}} --shared -Wl,--out-implib,build/locale.lib locale/ua/locale.cpp build/locale-en.res -o build/locale-ua.dll
|
||||
|
||||
@build-locale-en: mkdir-build
|
||||
{{windres}} -c 65001 locale/en/locale.rc -O coff -o build/locale-en.res
|
||||
{{cc}} {{cc_flags}} --shared -Wl,--out-implib,build/locale.lib locale/en/locale.cpp build/locale-en.res -o build/locale-en.dll
|
||||
|
||||
@build-locale-app: build-locale-ua build-locale-en
|
||||
{{cc}} {{cc_flags}} locale/app/main.cpp -o build/locale.exe
|
||||
|
||||
@run-locale: build-locale-app
|
||||
wine cmd /c build/locale.exe
|
||||
|
||||
# Checksum
|
||||
# ===================================================
|
||||
@build-checksum-lib: mkdir-build
|
||||
{{cc}} {{cc_flags}} --shared checksum/lib/crc.cpp checksum/lib/crc.def -o build/crc.dll -Wl,--out-implib,build/crc.lib
|
||||
|
||||
@build-checksum-app: build-checksum-lib
|
||||
{{cc}} {{cc_flags}} checksum/app/main.cpp -L build -l crc -o build/checksum.exe
|
||||
|
||||
@checksum-append: build-checksum-app
|
||||
wine cmd /c build/checksum.exe append build/rsa.dll
|
||||
|
||||
@checksum-verify: build-checksum-app
|
||||
wine cmd /c build/checksum.exe verify build/rsa.dll
|
||||
|
||||
# Rsa Static
|
||||
# ===================================================
|
||||
@build-rsa-static-lib: mkdir-build build-checksum-app
|
||||
{{cc}} {{cc_flags}} -D BUILD_SHARED --shared rsa-static/lib/rsa.cpp -L build -l crc -o build/rsa.dll -Wl,--out-implib,build/rsa.lib
|
||||
wine cmd /c build/checksum.exe append build/rsa.dll
|
||||
|
||||
@build-rsa-static-app: build-rsa-static-lib
|
||||
{{cc}} {{cc_flags}} rsa-static/app/main.cpp -L build -l rsa -o build/rsa-static.exe
|
||||
|
||||
@run-rsa-static: build-rsa-static-app
|
||||
wine cmd /c build/rsa-static.exe
|
||||
|
||||
# Rsa Shared
|
||||
# ===================================================
|
||||
@build-rsa-shared-lib: mkdir-build build-checksum-app
|
||||
{{cc}} {{cc_flags}} --shared rsa-shared/lib/rsa.cpp rsa-shared/lib/rsa.def -L build -l crc -o build/rsa.dll -Wl,--out-implib,build/rsa.lib
|
||||
wine cmd /c build/checksum.exe append build/rsa.dll
|
||||
|
||||
@build-rsa-shared-app: build-rsa-shared-lib
|
||||
{{cc}} {{cc_flags}} rsa-shared/app/main.cpp -o build/rsa-shared.exe
|
||||
|
||||
@run-rsa-shared: build-rsa-shared-app
|
||||
wine cmd /c build/rsa-shared.exe
|
60
semester-4/ОС/lb-3/src/checksum/app/main.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include "../lib/crc.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void usage() {
|
||||
fprintf(stderr, "Usage: checksum <COMMAND> <INPUT>\n");
|
||||
fprintf(stderr, "Commands:\n");
|
||||
fprintf(stderr, "\tappend - Compute checksum of the file and append it to "
|
||||
"the end of file.\n");
|
||||
fprintf(stderr, "\tverify - Verify checksum of the file.\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Input:\n");
|
||||
fprintf(stderr, "\tPath to input file.\n");
|
||||
}
|
||||
|
||||
enum Command {
|
||||
CommandUnknown,
|
||||
CommandAppend,
|
||||
CommandVerify,
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
Command command;
|
||||
|
||||
if (argc < 3)
|
||||
command = CommandUnknown;
|
||||
else if (strcmp(argv[1], "append") == 0)
|
||||
command = CommandAppend;
|
||||
else if (strcmp(argv[1], "verify") == 0)
|
||||
command = CommandVerify;
|
||||
else
|
||||
command = CommandUnknown;
|
||||
|
||||
switch (command) {
|
||||
case CommandAppend:
|
||||
if (crc_append(argv[2])) {
|
||||
printf("Checksum appended.\n");
|
||||
} else {
|
||||
fprintf(stderr, "Failed to append checksum.\n");
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case CommandVerify:
|
||||
if (crc_verify(argv[2])) {
|
||||
printf("Checksum verified.\n");
|
||||
} else {
|
||||
fprintf(stderr, "Failed to verify checksum.\n");
|
||||
return 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case CommandUnknown:
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
157
semester-4/ОС/lb-3/src/checksum/lib/crc.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
#include "crc.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
uint32_t crc_sym_table[256];
|
||||
|
||||
bool crc_sym_table_computed = false;
|
||||
|
||||
void crc_make_table(void) {
|
||||
for (size_t n = 0; n < 256; n++) {
|
||||
uint32_t c = n;
|
||||
|
||||
for (size_t k = 0; k < 8; k++) {
|
||||
if (c & 1)
|
||||
c = 0xEDB88320 ^ (c >> 1);
|
||||
else
|
||||
c >>= 1;
|
||||
}
|
||||
|
||||
crc_sym_table[n] = c;
|
||||
}
|
||||
|
||||
crc_sym_table_computed = true;
|
||||
}
|
||||
|
||||
uint32_t crc_update(uint32_t crc, uint8_t *buf, size_t size) {
|
||||
uint32_t c = crc ^ 0xFFFFFFFF;
|
||||
|
||||
if (!crc_sym_table_computed)
|
||||
crc_make_table();
|
||||
|
||||
for (size_t n = 0; n < size; n++)
|
||||
c = crc_sym_table[(c ^ buf[n]) & 0xFF] ^ (c >> 8);
|
||||
|
||||
return c ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
uint32_t crc_compute(uint8_t *buf, size_t size) {
|
||||
return crc_update(0, buf, size);
|
||||
}
|
||||
|
||||
bool crc_append(char *path) {
|
||||
FILE *input_file = fopen(path, "rb");
|
||||
if (!input_file) {
|
||||
fprintf(stderr, "Error: Can't open file %s to read.\n", path);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(input_file, 0, SEEK_END);
|
||||
size_t file_size = ftell(input_file);
|
||||
fseek(input_file, 0, SEEK_SET);
|
||||
|
||||
uint8_t *buf = (uint8_t *)malloc(file_size);
|
||||
if (!buf) {
|
||||
fprintf(stderr, "Error: Can't allocate memory for buffer.\n");
|
||||
|
||||
fclose(input_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t read_size = fread(buf, 1, file_size, input_file);
|
||||
if (read_size != file_size) {
|
||||
fprintf(stderr,
|
||||
"Error: File size (%zu) is differ from expected size (%zu).\n",
|
||||
read_size, file_size);
|
||||
|
||||
free(buf);
|
||||
fclose(input_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(input_file);
|
||||
|
||||
uint32_t computed = crc_compute(buf, file_size);
|
||||
free(buf);
|
||||
|
||||
fprintf(stderr, "Info: Computed RSA is %u\n", computed);
|
||||
|
||||
FILE *output_file = fopen(path, "ab");
|
||||
if (!output_file) {
|
||||
fprintf(stderr, "Error: Can't open file %s to write.\n", path);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fwrite(&computed, sizeof(computed), 1, output_file) != 1) {
|
||||
fprintf(stderr, "Error: Can't write computed crc to file.\n");
|
||||
|
||||
fclose(output_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(output_file);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool crc_verify(char *path) {
|
||||
FILE *input_file = fopen(path, "rb");
|
||||
if (!input_file) {
|
||||
fprintf(stderr, "Error: Can't open file %s to read.\n", path);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(input_file, 0, SEEK_END);
|
||||
size_t file_size = ftell(input_file);
|
||||
if (file_size < 4) {
|
||||
fprintf(stderr,
|
||||
"Error: File size is less then 4 bytes, can't verify checksum.\n");
|
||||
|
||||
fclose(input_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t data_size = file_size - 4;
|
||||
fseek(input_file, 0, SEEK_SET);
|
||||
|
||||
uint8_t *buf = (uint8_t *)malloc(data_size);
|
||||
if (!buf) {
|
||||
fprintf(stderr, "Error: Can't allocate memory for buffer.\n");
|
||||
|
||||
fclose(input_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t read_size = fread(buf, 1, data_size, input_file);
|
||||
if (read_size != data_size) {
|
||||
fprintf(stderr,
|
||||
"Error: File size (%zu) is differ from expected size (%zu).\n",
|
||||
read_size, data_size);
|
||||
|
||||
free(buf);
|
||||
fclose(input_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t computed = crc_compute(buf, data_size);
|
||||
uint32_t stored = 0;
|
||||
|
||||
if (fread(&stored, sizeof(stored), 1, input_file) != 1) {
|
||||
fprintf(stderr, "Error: Can't read stored checksum from the file.\n");
|
||||
|
||||
free(buf);
|
||||
fclose(input_file);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(input_file);
|
||||
free(buf);
|
||||
|
||||
fprintf(stderr, "Info: Computed RSA is %u\n", computed);
|
||||
fprintf(stderr, "Info: Stored RSA is %u\n", stored);
|
||||
|
||||
return computed == stored;
|
||||
}
|
5
semester-4/ОС/lb-3/src/checksum/lib/crc.def
Normal file
@ -0,0 +1,5 @@
|
||||
LIBRARY crc.dll
|
||||
EXPORTS
|
||||
crc_compute @1
|
||||
crc_append @2
|
||||
crc_verify @3
|
20
semester-4/ОС/lb-3/src/checksum/lib/crc.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef CRC_LIB
|
||||
#define CRC_LIB
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32_t crc_compute(uint8_t *buf, size_t size);
|
||||
|
||||
bool crc_append(char *path);
|
||||
|
||||
bool crc_verify(char *path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
51
semester-4/ОС/lb-3/src/locale/app/main.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "../locale.h"
|
||||
#include <locale.h>
|
||||
#include <windows.h>
|
||||
|
||||
void print_res_str(HINSTANCE hLib, size_t id) {
|
||||
wchar_t buffer[256] = {0};
|
||||
if (LoadStringW(hLib, id, buffer, sizeof(buffer) / sizeof(wchar_t)))
|
||||
wprintf(L"%ls\n", buffer);
|
||||
else
|
||||
fprintf(stderr, "Error: Can't load string from dll\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
setlocale(LC_ALL, "ukr");
|
||||
|
||||
printf("Choose language to use\n");
|
||||
printf("\t1 - ua\n");
|
||||
printf("\t2 - en\n");
|
||||
printf("choice: ");
|
||||
|
||||
int lang = getchar() - '0';
|
||||
|
||||
HMODULE hLib = 0;
|
||||
|
||||
if (lang == 1)
|
||||
hLib = LoadLibrary("locale-ua.dll");
|
||||
else if (lang == 2)
|
||||
hLib = LoadLibrary("locale-en.dll");
|
||||
else
|
||||
fprintf(stderr, "Error: No such language\n");
|
||||
|
||||
if (!hLib) {
|
||||
fprintf(stderr, "Error: Can't load dll\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Surname:\t");
|
||||
print_res_str(hLib, ID_SURNAME);
|
||||
|
||||
printf("Faculty:\t");
|
||||
print_res_str(hLib, ID_FACULTY);
|
||||
|
||||
printf("Group:\t\t");
|
||||
print_res_str(hLib, ID_GROUP);
|
||||
|
||||
printf("Discipline:\t");
|
||||
print_res_str(hLib, ID_DISCIPLINE);
|
||||
|
||||
FreeLibrary(hLib);
|
||||
return 0;
|
||||
}
|
35
semester-4/ОС/lb-3/src/locale/en/locale.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
fprintf(stderr,
|
||||
"DLL loaded into process. hinstDLL = %p, lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
fprintf(stderr,
|
||||
"New thread created in the process using the DLL. "
|
||||
"hinstDLL = %p, lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
fprintf(stderr,
|
||||
"Thread using the DLL is terminating. hinstDLL = %p, "
|
||||
"lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
fprintf(stderr,
|
||||
"DLL unloaded from process. hinstDLL = %p, lpvReserved = "
|
||||
"%p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
12
semester-4/ОС/lb-3/src/locale/en/locale.rc
Normal file
@ -0,0 +1,12 @@
|
||||
#include "../locale.h"
|
||||
#include <windows.h>
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ID_SURNAME "Sytnyk"
|
||||
ID_FACULTY "Computer science"
|
||||
ID_GROUP "PZPI-23-2"
|
||||
ID_DISCIPLINE "Operating Systems"
|
||||
END
|
9
semester-4/ОС/lb-3/src/locale/locale.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef LOCALE
|
||||
#define LOCALE
|
||||
|
||||
#define ID_SURNAME 100
|
||||
#define ID_FACULTY 101
|
||||
#define ID_GROUP 102
|
||||
#define ID_DISCIPLINE 103
|
||||
|
||||
#endif
|
35
semester-4/ОС/lb-3/src/locale/ua/locale.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
fprintf(stderr,
|
||||
"DLL loaded into process. hinstDLL = %p, lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
fprintf(stderr,
|
||||
"New thread created in the process using the DLL. "
|
||||
"hinstDLL = %p, lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
fprintf(stderr,
|
||||
"Thread using the DLL is terminating. hinstDLL = %p, "
|
||||
"lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
fprintf(stderr,
|
||||
"DLL unloaded from process. hinstDLL = %p, lpvReserved = "
|
||||
"%p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
12
semester-4/ОС/lb-3/src/locale/ua/locale.rc
Normal file
@ -0,0 +1,12 @@
|
||||
#include "../locale.h"
|
||||
#include <windows.h>
|
||||
|
||||
LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ID_SURNAME "Ситник"
|
||||
ID_FACULTY "Комп'ютерних наук"
|
||||
ID_GROUP "ПЗПІ-23-2"
|
||||
ID_DISCIPLINE "Операційні Системи"
|
||||
END
|
104
semester-4/ОС/lb-3/src/rsa-shared/app/main.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "../lib/rsa.h"
|
||||
|
||||
typedef rsa_Pair (*rsa_gen_pair_t)(__int128_t, __int128_t, __int128_t);
|
||||
typedef __int128_t (*rsa_encrypt_t)(__int128_t, __int128_t, __int128_t);
|
||||
typedef __int128_t (*rsa_decrypt_t)(__int128_t, __int128_t, __int128_t);
|
||||
|
||||
char *int128_to_str(__int128_t n) {
|
||||
static char str[41] = {0};
|
||||
char *s = str + sizeof(str) - 1;
|
||||
bool neg = n < 0;
|
||||
if (neg)
|
||||
n = -n;
|
||||
do {
|
||||
*--s = "0123456789"[n % 10];
|
||||
n /= 10;
|
||||
} while (n);
|
||||
if (neg)
|
||||
*--s = '-';
|
||||
return s;
|
||||
}
|
||||
|
||||
int main() {
|
||||
HMODULE hLib = LoadLibraryA("rsa.dll");
|
||||
if (!hLib) {
|
||||
fprintf(stderr, "Error: Can't load rsa.dll.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
rsa_gen_pair_t rsa_gen_pair =
|
||||
(rsa_gen_pair_t)(GetProcAddress(hLib, "rsa_gen_pair"));
|
||||
rsa_encrypt_t rsa_encrypt =
|
||||
(rsa_encrypt_t)(GetProcAddress(hLib, "rsa_encrypt"));
|
||||
rsa_decrypt_t rsa_decrypt =
|
||||
(rsa_decrypt_t)(GetProcAddress(hLib, "rsa_decrypt"));
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
if (!rsa_gen_pair || !rsa_encrypt || !rsa_decrypt) {
|
||||
printf("Error: Can't load functions from rsa.dll\n");
|
||||
|
||||
FreeLibrary(hLib);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t p0 = 8589934609, q0 = 2147483693, e0 = 65537;
|
||||
uint64_t p1 = 2147483659, q1 = 8589934621, e1 = 65537;
|
||||
|
||||
rsa_Pair pair_0 = rsa_gen_pair(p0, q0, e0);
|
||||
rsa_Pair pair_1 = rsa_gen_pair(p1, q1, e1);
|
||||
|
||||
printf("pair_0:\n");
|
||||
printf("- e:\t%s\n", int128_to_str(pair_0.e));
|
||||
printf("- d:\t%s\n", int128_to_str(pair_0.d));
|
||||
printf("- n:\t%s\n", int128_to_str(pair_0.n));
|
||||
|
||||
printf("pair_1:\n");
|
||||
printf("- e:\t%s\n", int128_to_str(pair_1.e));
|
||||
printf("- d:\t%s\n", int128_to_str(pair_1.d));
|
||||
printf("- n:\t%s\n", int128_to_str(pair_1.n));
|
||||
|
||||
uint64_t t[] = {22, 17, 2, 65500, 0x9fffffff};
|
||||
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
printf("- - - - - - - - - - - - - - - - - -\n");
|
||||
|
||||
printf("t[%zu]:\t\t%lld\n", i, t[i]);
|
||||
|
||||
__int128_t e1t = rsa_encrypt(t[i], pair_0.e, pair_0.n);
|
||||
printf("e1t:\t\t%s\n", int128_to_str(e1t));
|
||||
|
||||
__int128_t d1e1t = rsa_decrypt(e1t, pair_0.d, pair_0.n);
|
||||
printf("d1e1t:\t\t%s\n", int128_to_str(d1e1t));
|
||||
|
||||
if (d1e1t != t[i]) {
|
||||
fprintf(stderr, "Error: decrypt[i]on failed - expected: %llu; got: %s\n",
|
||||
t[i], int128_to_str(d1e1t));
|
||||
|
||||
FreeLibrary(hLib);
|
||||
return 1;
|
||||
}
|
||||
|
||||
__int128_t e0d1e1t = rsa_encrypt(t[i], pair_1.e, pair_1.n);
|
||||
printf("e0d1e1t:\t%s\n", int128_to_str(e0d1e1t));
|
||||
|
||||
__int128_t d0e0d1e1t = rsa_decrypt(e0d1e1t, pair_1.d, pair_1.n);
|
||||
printf("d0e0d1e1t:\t%s\n", int128_to_str(d0e0d1e1t));
|
||||
|
||||
if (d0e0d1e1t != t[i]) {
|
||||
fprintf(stderr, "Error: decryption failed - expected: %llu; got: %s\n",
|
||||
t[i], int128_to_str(d0e0d1e1t));
|
||||
|
||||
FreeLibrary(hLib);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(hLib);
|
||||
return 0;
|
||||
}
|
140
semester-4/ОС/lb-3/src/rsa-shared/lib/rsa.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
#include "rsa.h"
|
||||
#include "../../checksum/lib/crc.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
switch (fdwReason) {
|
||||
|
||||
case DLL_PROCESS_ATTACH:
|
||||
fprintf(stderr,
|
||||
"DLL loaded into process. hinstDLL = %p, lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
|
||||
{
|
||||
fprintf(stderr, "Info: Checking integrity of rsa.dll.\n");
|
||||
|
||||
char dll_path[MAX_PATH] = {0};
|
||||
if (GetModuleFileNameA(hInstDLL, dll_path, MAX_PATH) == 0) {
|
||||
fprintf(stderr, "Error: Can't get path to rsa.dll file.\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!crc_verify(dll_path)) {
|
||||
fprintf(stderr, "Error: Can't verify rsa.dll integrity.\n");
|
||||
|
||||
return FALSE;
|
||||
} else {
|
||||
fprintf(stderr, "Info: Integrity of rsa.dll is verified.\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
fprintf(stderr,
|
||||
"New thread created in the process using the DLL. "
|
||||
"hinstDLL = %p, lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
fprintf(stderr,
|
||||
"Thread using the DLL is terminating. hinstDLL = %p, "
|
||||
"lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
fprintf(stderr,
|
||||
"DLL unloaded from process. hinstDLL = %p, lpvReserved = "
|
||||
"%p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
__int128_t mul_mod(__int128_t a, __int128_t b, __int128_t mod) {
|
||||
__int128_t res = 0;
|
||||
a %= mod;
|
||||
|
||||
while (b > 0) {
|
||||
if (b & 1)
|
||||
res = (res + a) % mod;
|
||||
|
||||
a = (a << 1) % mod;
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
__int128_t pow_mod(__int128_t base, __int128_t exp, __int128_t mod) {
|
||||
__int128_t res = 1;
|
||||
base %= mod;
|
||||
|
||||
while (exp > 0) {
|
||||
if (exp & 1)
|
||||
res = mul_mod(res, base, mod);
|
||||
|
||||
base = mul_mod(base, base, mod);
|
||||
exp >>= 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
__int128_t mod_inverse(__int128_t e, __int128_t phi) {
|
||||
__int128_t a = e, b = phi;
|
||||
__int128_t x = 1, y = 0;
|
||||
__int128_t x1 = 0, y1 = 1;
|
||||
__int128_t q, temp;
|
||||
|
||||
while (b != 0) {
|
||||
q = a / b;
|
||||
|
||||
temp = a % b;
|
||||
a = b;
|
||||
b = temp;
|
||||
|
||||
temp = x - q * x1;
|
||||
x = x1;
|
||||
x1 = temp;
|
||||
|
||||
temp = y - q * y1;
|
||||
y = y1;
|
||||
y1 = temp;
|
||||
}
|
||||
|
||||
if (x < 0)
|
||||
x += phi;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
rsa_Pair rsa_gen_pair(__int128_t p, __int128_t q, __int128_t e) {
|
||||
rsa_Pair pair;
|
||||
pair.e = e;
|
||||
pair.n = p * q;
|
||||
|
||||
__int128_t phi = (p - 1) * (q - 1);
|
||||
pair.d = mod_inverse(e, phi);
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
__int128_t rsa_encrypt(__int128_t data, __int128_t e, __int128_t n) {
|
||||
return pow_mod(data, e, n);
|
||||
}
|
||||
|
||||
__int128_t rsa_decrypt(__int128_t data, __int128_t d, __int128_t n) {
|
||||
return pow_mod(data, d, n);
|
||||
}
|
5
semester-4/ОС/lb-3/src/rsa-shared/lib/rsa.def
Normal file
@ -0,0 +1,5 @@
|
||||
LIBRARY rsa.dll
|
||||
EXPORTS
|
||||
rsa_gen_pair @1
|
||||
rsa_encrypt @2
|
||||
rsa_decrypt @3
|
23
semester-4/ОС/lb-3/src/rsa-shared/lib/rsa.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef RSA_LIB
|
||||
#define RSA_LIB
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
__int128_t d;
|
||||
__int128_t e;
|
||||
__int128_t n;
|
||||
} rsa_Pair;
|
||||
|
||||
rsa_Pair rsa_gen_pair(__int128_t p, __int128_t q, __int128_t e);
|
||||
|
||||
__int128_t rsa_encrypt(__int128_t data, __int128_t e, __int128_t n);
|
||||
__int128_t rsa_decrypt(__int128_t data, __int128_t d, __int128_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
71
semester-4/ОС/lb-3/src/rsa-static/app/main.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../lib/rsa.h"
|
||||
|
||||
char *int128_to_str(__int128_t n) {
|
||||
static char str[41] = {0};
|
||||
char *s = str + sizeof(str) - 1;
|
||||
bool neg = n < 0;
|
||||
if (neg)
|
||||
n = -n;
|
||||
do {
|
||||
*--s = "0123456789"[n % 10];
|
||||
n /= 10;
|
||||
} while (n);
|
||||
if (neg)
|
||||
*--s = '-';
|
||||
return s;
|
||||
}
|
||||
|
||||
int main() {
|
||||
uint64_t p0 = 8589934609, q0 = 2147483693, e0 = 65537;
|
||||
uint64_t p1 = 2147483659, q1 = 8589934621, e1 = 65537;
|
||||
|
||||
rsa_Pair pair_0 = rsa_gen_pair(p0, q0, e0);
|
||||
rsa_Pair pair_1 = rsa_gen_pair(p1, q1, e1);
|
||||
|
||||
printf("pair_0:\n");
|
||||
printf("- e:\t%s\n", int128_to_str(pair_0.e));
|
||||
printf("- d:\t%s\n", int128_to_str(pair_0.d));
|
||||
printf("- n:\t%s\n", int128_to_str(pair_0.n));
|
||||
|
||||
printf("pair_1:\n");
|
||||
printf("- e:\t%s\n", int128_to_str(pair_1.e));
|
||||
printf("- d:\t%s\n", int128_to_str(pair_1.d));
|
||||
printf("- n:\t%s\n", int128_to_str(pair_1.n));
|
||||
|
||||
uint64_t t[] = {22, 17, 2, 65500, 0x9fffffff};
|
||||
|
||||
for (size_t i = 0; i < 5; i++) {
|
||||
printf("- - - - - - - - - - - - - - - - - -\n");
|
||||
|
||||
printf("t[%zu]:\t\t%lld\n", i, t[i]);
|
||||
|
||||
__int128_t e1t = rsa_encrypt(t[i], pair_0.e, pair_0.n);
|
||||
printf("e1t:\t\t%s\n", int128_to_str(e1t));
|
||||
|
||||
__int128_t d1e1t = rsa_decrypt(e1t, pair_0.d, pair_0.n);
|
||||
printf("d1e1t:\t\t%s\n", int128_to_str(d1e1t));
|
||||
|
||||
if (d1e1t != t[i]) {
|
||||
fprintf(stderr, "Error: decrypt[i]on failed - expected: %llu; got: %s\n",
|
||||
t[i], int128_to_str(d1e1t));
|
||||
return 1;
|
||||
}
|
||||
|
||||
__int128_t e0d1e1t = rsa_encrypt(t[i], pair_1.e, pair_1.n);
|
||||
printf("e0d1e1t:\t%s\n", int128_to_str(e0d1e1t));
|
||||
|
||||
__int128_t d0e0d1e1t = rsa_decrypt(e0d1e1t, pair_1.d, pair_1.n);
|
||||
printf("d0e0d1e1t:\t%s\n", int128_to_str(d0e0d1e1t));
|
||||
|
||||
if (d0e0d1e1t != t[i]) {
|
||||
fprintf(stderr, "Error: decrypt[i]on failed - expected: %llu; got: %s\n",
|
||||
t[i], int128_to_str(d0e0d1e1t));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
141
semester-4/ОС/lb-3/src/rsa-static/lib/rsa.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
#include "windows.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../checksum/lib/crc.h"
|
||||
#include "rsa.h"
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) {
|
||||
switch (fdwReason) {
|
||||
|
||||
case DLL_PROCESS_ATTACH:
|
||||
fprintf(stderr,
|
||||
"DLL loaded into process. hinstDLL = %p, lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
|
||||
{
|
||||
fprintf(stderr, "Info: Checking integrity of rsa.dll.\n");
|
||||
|
||||
char dll_path[MAX_PATH] = {0};
|
||||
if (GetModuleFileNameA(hInstDLL, dll_path, MAX_PATH) == 0) {
|
||||
fprintf(stderr, "Error: Can't get path to rsa.dll file.\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!crc_verify(dll_path)) {
|
||||
fprintf(stderr, "Error: Can't verify rsa.dll integrity.\n");
|
||||
|
||||
return FALSE;
|
||||
} else {
|
||||
fprintf(stderr, "Info: Integrity of rsa.dll is verified.\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
fprintf(stderr,
|
||||
"New thread created in the process using the DLL. "
|
||||
"hinstDLL = %p, lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
fprintf(stderr,
|
||||
"Thread using the DLL is terminating. hinstDLL = %p, "
|
||||
"lpvReserved = %p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
|
||||
return FALSE;
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
fprintf(stderr,
|
||||
"DLL unloaded from process. hinstDLL = %p, lpvReserved = "
|
||||
"%p\n",
|
||||
hInstDLL, lpvReserved);
|
||||
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
__int128_t mul_mod(__int128_t a, __int128_t b, __int128_t mod) {
|
||||
__int128_t res = 0;
|
||||
a %= mod;
|
||||
|
||||
while (b > 0) {
|
||||
if (b & 1)
|
||||
res = (res + a) % mod;
|
||||
|
||||
a = (a << 1) % mod;
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
__int128_t pow_mod(__int128_t base, __int128_t exp, __int128_t mod) {
|
||||
__int128_t res = 1;
|
||||
base %= mod;
|
||||
|
||||
while (exp > 0) {
|
||||
if (exp & 1)
|
||||
res = mul_mod(res, base, mod);
|
||||
|
||||
base = mul_mod(base, base, mod);
|
||||
exp >>= 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
__int128_t mod_inverse(__int128_t e, __int128_t phi) {
|
||||
__int128_t a = e, b = phi;
|
||||
__int128_t x = 1, y = 0;
|
||||
__int128_t x1 = 0, y1 = 1;
|
||||
__int128_t q, temp;
|
||||
|
||||
while (b != 0) {
|
||||
q = a / b;
|
||||
|
||||
temp = a % b;
|
||||
a = b;
|
||||
b = temp;
|
||||
|
||||
temp = x - q * x1;
|
||||
x = x1;
|
||||
x1 = temp;
|
||||
|
||||
temp = y - q * y1;
|
||||
y = y1;
|
||||
y1 = temp;
|
||||
}
|
||||
|
||||
if (x < 0)
|
||||
x += phi;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
rsa_Pair rsa_gen_pair(__int128_t p, __int128_t q, __int128_t e) {
|
||||
rsa_Pair pair;
|
||||
pair.e = e;
|
||||
pair.n = p * q;
|
||||
|
||||
__int128_t phi = (p - 1) * (q - 1);
|
||||
pair.d = mod_inverse(e, phi);
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
__int128_t rsa_encrypt(__int128_t data, __int128_t e, __int128_t n) {
|
||||
return pow_mod(data, e, n);
|
||||
}
|
||||
|
||||
__int128_t rsa_decrypt(__int128_t data, __int128_t d, __int128_t n) {
|
||||
return pow_mod(data, d, n);
|
||||
}
|
35
semester-4/ОС/lb-3/src/rsa-static/lib/rsa.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef RSA_LIB
|
||||
#define RSA_LIB
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef BUILD_SHARED
|
||||
#define BUILD_SPEC __declspec(dllexport)
|
||||
#elif BUILD_STATIC
|
||||
#define BUILD_SPEC
|
||||
#else
|
||||
#define BUILD_SPEC __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define BUILD_SPEC
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
__int128_t d;
|
||||
__int128_t e;
|
||||
__int128_t n;
|
||||
} rsa_Pair;
|
||||
|
||||
BUILD_SPEC rsa_Pair rsa_gen_pair(__int128_t p, __int128_t q, __int128_t e);
|
||||
|
||||
BUILD_SPEC __int128_t rsa_encrypt(__int128_t data, __int128_t e, __int128_t n);
|
||||
BUILD_SPEC __int128_t rsa_decrypt(__int128_t data, __int128_t d, __int128_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
160
semester-4/ОС/lb-3/Лр_3_Ситник_ПЗПІ_23_2.typ
Normal file
@ -0,0 +1,160 @@
|
||||
#import "@local/nure:0.0.0": *
|
||||
|
||||
#show: lab-pz-template.with(
|
||||
doctype: "ЛБ",
|
||||
title: "Створення та використання бібліотек. Частина 2",
|
||||
subject_shorthand: "ОС",
|
||||
department_gen: "Програмної інженерії",
|
||||
authors: (
|
||||
(
|
||||
name: "Ситник Є. С.",
|
||||
full_name_gen: "Ситника Єгора Сергійовича",
|
||||
group: "ПЗПІ-23-2",
|
||||
gender: "m",
|
||||
variant: none,
|
||||
),
|
||||
),
|
||||
mentor: (
|
||||
name: "Мельнікова Р. В.",
|
||||
gender: "f",
|
||||
degree: "доц. каф. ПІ",
|
||||
),
|
||||
worknumber: 3,
|
||||
)
|
||||
|
||||
#v(-spacing)
|
||||
|
||||
== Мета роботи
|
||||
Вивчити розширені прийоми та методи створення та використання різних типів динамічних бібліотек.
|
||||
|
||||
== Хід роботи
|
||||
|
||||
=== Створити новий варіант бібліотеки "rsa" із застосуванням ".def" файлу, та динамічного завантаження під час виконання програми.
|
||||
|
||||
Файли із розширенням ".def" використовуються для позначення "символів", що будуть експортовані із ".dll" бібліотеки для зовнішнього використання. Зараз застосування таких файлів можна зустріти дуже рідко, адже його майже повністю замінили атрибути "\_\_declspec(dllexport)" та "\_\_declspec(dllimport)". Оскільки такі атрибути були використані під час виконання попередньої лабораторної роботи нам необхідно їх прибрати із заголовочного файлу нової версії бібліотеки, після цього створимо файл "rsa.def" в який додамо назви функцій, що мають бути експортовані.
|
||||
|
||||
#figure(image("img/1/h.png", width: 70%), caption: [Оновлений вміст файлу "rsa.h"]) <1h>
|
||||
#figure(image("img/1/def.png"), caption: [Вміст файлу "rsa.def"]) <1def>
|
||||
|
||||
Також необхідно передати створений "rsa.def" файл компілятору. Для цього оновимо команду компіляції, додавши шлях до відповідного файлу.
|
||||
|
||||
#figure(image("img/1/just.png"), caption: [Оновлений "рецепт" компіляції бібліотеки "rsa.dll"]) <1just>
|
||||
|
||||
Щоб перевірити, що потрібні "символи" експортуються із "rsa.dll" можемо скористатись програмою "dumpbin".
|
||||
|
||||
#figure(
|
||||
image("img/1/check.png", width: 65%),
|
||||
caption: [Перевірка зі допомогою "dumpbin" експортованих із бібліотеки "символів"],
|
||||
) <1check>
|
||||
|
||||
Можемо побачити, що потрібні "символи" експортуються із "rsa.dll".
|
||||
|
||||
Тепер створимо нову версію програми, в якій використаємо динамічне завантаження бібліотеки під час виконання. Для цього змінимо файл "main.cpp". На самому початку виконання програми нам необхідно завантажити "rsa.dll" файл та експортувати із нього функції, типи яких оголосимо заздалегідь. Також додамо виклик "FreeLibrary" перед кожним місцем завершення програми після завантаження бібліотеки.
|
||||
|
||||
#figure(
|
||||
image("img/1/func_types.png", width: 100%),
|
||||
caption: [Оголошені типи функцій для експорту],
|
||||
) <1func_types>
|
||||
|
||||
#figure(
|
||||
image("img/1/dll_load.png", width: 100%),
|
||||
caption: [Завантаження бібліотеки та імпорту функцій із неї],
|
||||
) <1dll_load>
|
||||
|
||||
Також не забудемо оновити "рецепт" компіляції програми.
|
||||
|
||||
#figure(image("img/1/just2.png"), caption: [Оновлений "рецепт" компіляції програми]) <1just2>
|
||||
|
||||
Перевіримо роботу програми.
|
||||
|
||||
#figure(image("img/1/result.png"), caption: [Результат виконання програми]) <1result>
|
||||
|
||||
Програма працює як і раніше.
|
||||
|
||||
=== Створити файли ресурсів із таблицями рядків українською та англійською мовою, та програму для їх використання.
|
||||
|
||||
Файли ресурсів це файли, які містять скрипти, що описують різні не-кодові елементи, які використовуються програмою (наприклад рядки, іконки, бітові карти та інше). Файли ресурсів мають розширення ".rc" та створюються із використанням специфічного синтаксису. Створимо файли "locale.cpp" та "locale.rc" для української та англійської локалізацій, спільний файл "locale.h" для позначення ID ресурсів, та файл "main.cpp" для написання основної програми.
|
||||
|
||||
В файлі заголовків визначимо псевдоніми, що ми будемо використовувати замість числових ID.
|
||||
|
||||
#figure(image("img/2/locale_h.png"), caption: [Вміст файлу "locale.h"]) <2locale_h>
|
||||
|
||||
В файлах "locale.cpp" оголосимо функції "DLLMain", що викликаються під час завантаження/вивантаження бібліотеки, та надрукуємо інформацію для відлагодження.
|
||||
|
||||
#figure(image("img/2/locale_cpp.png"), caption: [Вміст файлів "locale.cpp"]) <2locale_cpp>
|
||||
|
||||
В файлах "locale.rc" оголосимо строки, що відповідатимуть прізвищу, факультету, групі та дисципліні двома мовами, використаємо оголошені раніше псевдоніми в якості ID.
|
||||
|
||||
#figure(image("img/2/locale_ua.rc.png"), caption: [Вміст файлу "locale.rc" із українською локалізацій]) <2locale_ua.rc>
|
||||
#figure(image("img/2/locale_en.rc.png"), caption: [Вміст файлу "locale.rc" із англійською локалізацією]) <2locale_en.rc>
|
||||
|
||||
Створимо "рецепти" для компіляції створених ресурсних файлів. Для перетворення файлів ".rc" у бінарний формат використовується програма "windres", за її допомогою файли ".rc" перетворюються в об'єктні файли ".res", які потім передаються компілятору для створення ".dll". Оскільки я використовую операційну систему ArchLinux я маю додати деякі аргументи для "windres", а саме "-c 65001" для встановлення кодування UTF-8, та "-O coff", щоб вказати формат бінарних файлів, що відповідає формату Windows.
|
||||
|
||||
#figure(image("img/2/just_locale.png"), caption: ["Рецепти" компіляції файлів ресурсів]) <2locale_just>
|
||||
|
||||
В файлі "main.cpp" запитаємо у користувача мову, та завантажимо відповідний цій мові ".dll" файл, після чого завантажимо з цього файлу строки використовуючи визначені раніше псевдоніми, та виведемо ці строки в консоль.
|
||||
|
||||
#figure(image("img/2/main.png"), caption: [Вміст файлу "main.cpp"]) <2main>
|
||||
|
||||
Створимо "рецепт" для компіляції програми.
|
||||
|
||||
#figure(image("img/2/just_app.png"), caption: ["Рецепти" компіляції програми]) <2just_app>
|
||||
|
||||
Перевіримо роботу програми із обома мовами.
|
||||
|
||||
#figure(image("img/2/result_ua.png"), caption: [Результат виконання із українською мовою]) <2result_ua>
|
||||
#figure(image("img/2/result_en.png"), caption: [Результат виконання із англійською мовою]) <2result_en>
|
||||
|
||||
=== Створити новий проект для підрахунку контрольної суми за допомогою алгоритму "crc32" та інтегрувати його в бібліотеку "rsa".
|
||||
|
||||
Алгоритм "crc32" -- це алгоритм обчислення контрольної суми, який використовується для перевірки цілісності даних. Його основна мета це виявлення випадкових помилок передачі та зберігання (перевірка цілісності) даних, але не захист від навмисних змін даних шахраями, адже існують способи навмисно змінити дані зберігши при цьому ту саму контрольну суму.
|
||||
|
||||
Створимо новий проєкт, що складатиметься із бібліотеки та консольного застосунку. Бібліотека буде надавати функції для генерації контрольної суми, додавання згенерованої контрольної суми до файлу, та перевірки цілісності файлу на основі доданої до нього контрольної суми. Консольний застосунок виконуватиме 2 команди -- додавання контрольної суми до файлу, та перевірка файлу.
|
||||
|
||||
Створимо файл заголовків "crc.h", в якому оголосимо відповідні функції, та файл "crc.def", для експорту функцій із ".dll".
|
||||
|
||||
#figure(image("img/3/crc.h.png", width: 80%), caption: [Вміст файлу "crc.h"]) <3crc.h>
|
||||
#figure(image("img/3/crc.def.png"), caption: [Вміст файлу "crc.def"]) <3crc.def>
|
||||
|
||||
Алгоритм "crc32" передбачає побітове ділення даних на поліном, що може бути досить повільним процесом, особливо для великих обсягів даних. Для прискорення цієї операції перед початком алгоритму можна обрахувати проміжні значення та зберегти їх в таблицю (для 1 байту це всього 256 унікальних значень). Створимо таблицю для збереження попередньо обрахованих значень, та функцію, що їх обрахує.
|
||||
|
||||
#figure(image("img/3/table.png"), caption: [Функція наповнення таблиці]) <3table>
|
||||
|
||||
Реалізуємо функцію, що буде обраховувати контрольну суму для наданого буферу.
|
||||
|
||||
#figure(image("img/3/update.png"), caption: [Функція обрахунку контрольної суми для буферу]) <3update>
|
||||
|
||||
Створимо функцію, що відкриватиме файл за вказаною адресою, обраховуватиме його контрольну суму, та додаватиме обраховане значення в кінець файлу.
|
||||
|
||||
#figure(image("img/3/append.png", width: 75%), caption: [Функція додавання контрольної суми до файлу]) <3append>
|
||||
|
||||
Створимо функцію, що відкриватиме файл за вказаною адресою, зчитуватиме збережену в ньому контрольну суму, обраховуватиме контрольну суму повторно, та порівнюватиме збережене та обраховане значення.
|
||||
|
||||
#figure(image("img/3/verify.png", width: 75%), caption: [Функція перевірки цілісності файлу]) <3verify>
|
||||
|
||||
Створимо консольний застосунок, що прийматиме 2 аргументи -- режим роботи та шлях до файлу, та викликатиме відповідні режиму функції.
|
||||
|
||||
#figure(image("img/3/main.png"), caption: [Вміст файлу "main.cpp"]) <3main>
|
||||
|
||||
Також додамо "рецепти" для компіляції створених бібліотеки та застосунку.
|
||||
|
||||
#figure(image("img/3/just.png"), caption: [Створені "рецепти" компіляції]) <3just>
|
||||
|
||||
Перевіримо роботу програми на текстовому файлі.
|
||||
|
||||
#figure(image("img/3/test.png"), caption: [Перевірка роботи програми]) <3test>
|
||||
|
||||
Можемо побачити, що програма працює як задумано.
|
||||
|
||||
Тепер додамо перевірку цілісності в бібліотеку "rsa", використавши функцію перевірки із щойно створеної бібліотеки "crc".
|
||||
|
||||
#figure(image("img/3/rsa.png"), caption: [Перевірка роботи програми]) <3rsa>
|
||||
|
||||
Протестуємо перевірку цілісності. Для цього запустимо програму, щоб переконатись, що вона працює, потім за допомогою редактору змінимо вміст "rsa.dll" (наприклад видаливши визначення якогось із експортованих символів), та спробуємо запустити програму ще раз.
|
||||
|
||||
#figure(image("img/3/test_rsa.png"), caption: [Перевірка роботи програми]) <3test_rsa>
|
||||
|
||||
Можемо побачити, що перевірка цілісності працює, як і очікувалося.
|
||||
|
||||
== Висновки
|
||||
Під час виконання даної лабораторної роботи я вивчив розширені прийоми та методи створення та використання різних типів динамічних бібліотек.
|