1
0

migration

This commit is contained in:
2025-04-29 22:08:00 +03:00
commit ad28507008
232 changed files with 12299 additions and 0 deletions

View File

@ -0,0 +1,2 @@
Викладач: Мельникова Р. В.
Оцінка: 96

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

View 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

View 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

View 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;
}

View 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;
}

View File

@ -0,0 +1,5 @@
LIBRARY crc.dll
EXPORTS
crc_compute @1
crc_append @2
crc_verify @3

View 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

View 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;
}

View 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;
}

View 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

View 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

View 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;
}

View 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

View 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;
}

View 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);
}

View File

@ -0,0 +1,5 @@
LIBRARY rsa.dll
EXPORTS
rsa_gen_pair @1
rsa_encrypt @2
rsa_decrypt @3

View 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

View 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;
}

View 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);
}

View 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

View 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>
Можемо побачити, що перевірка цілісності працює, як і очікувалося.
== Висновки
Під час виконання даної лабораторної роботи я вивчив розширені прийоми та методи створення та використання різних типів динамічних бібліотек.