Санкт-Петербургский государственный политехнический университет
Факультет технической кибернетики
Кафедра компьютерных систем и программных технологий
Отчёт по лабораторной работе №1
Дисциплина: "Системное программное обеспечение"
Выполнил студент гр. 5081/13 Залеский А. А.
Преподаватель __________ Душутина Е. В.
\
Эссе
Обфуска́ция (от лат. obfuscare — затенять, затемнять; и англ. obfuscate — делать неочевидным, запутанным, сбивать с толку) или запутывание кода — приведение исходного текста или исполняемого кода программы к виду, сохраняющему ее функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при декомпиляции. На деле это дело выглядит так – вы, исследуя чужой код мало что понимаете, и ни за что не можете зацепиться глазом – сплошные, ничего не говорящие нолики, единицы, или бессмысленные сочетания символов. Гораздо труднее понять взимодействие классов, вызовы методов необходимо анализировать гораздо более внимательнее (после обфускации в классе могут быть все методы названные как «0», в этом случае их разделять можно по ReturnType и списку параметров и их типов, причем параметры после обфускации могут быть также обезличены).
Существуют различные типы обфускаторов: одни занимаются интерпретируемыми языками типа Perl или PHP и "корежат" исходные тексты (удаляют комментарии, дают переменным бессмысленные имена, шифруют строковые константы, etc.), другие "перемалывают" байт-код виртуальных машин Java и .NET, что технически сделать намного труднее. Самые совершенные обфускаторы вламываются непосредственно в машинный код, "разбавляя" его мусорными инструкциями и выполняя целый ряд структурных (реже - математических) преобразований, изменяющих программу до неузнаваемости.
Цели обфускации
-
Демонстрация неочевидных возможностей языка и квалификации программиста (если производится вручную, а не инструментальными средствами).
-
Оптимизация программы с целью уменьшения размера работающего кода и (если используется некомпилируемый язык) ускорения работы.
-
Затруднение декомпиляции/отладки и изучения программ с целью обнаружения функциональности.
-
Затруднение декомпиляции проприетарных программ с целью предотвращения обратной разработки или обхода DRM и систем проверки лицензий.
-
Нарушение авторских прав программистов и скрытие авторства. Парадокс в том, что используется это преимущественно в проприетарных программах
Ссылки:
-
http://www.vbnet.ru/articles/showarticle.aspx?id=125
-
http://www.insidepro.com/kk/080/080r.shtml
-
http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%84%D1%83%D1%81%D0%BA%D0%B0%D1%86%D0%B8%D1%8F
Тестирование программ на быстродействие.
-
Реализовать пример, написанный на доске и сравнить быстродействие в различных реализациях алгоритма: код с использованием библиотек С++, код с использованием системных функций Windows и код с использованием специализированных функций WinAPI.
#include <Windows.h>
#include <stdio.h>
#include <errno.h>
#define BUF_SIZE 256
int first( int argc, LPTSTR argv, LPTSTR argr) // Решение с помощью встроенных windows функций
{
HANDLE hIn, hOut;
CHAR Buffer[BUF_SIZE];
DWORD size,R,dwBytesWritten;
if(argc != 3){
printf("cpw f1,f2\n");
return 1;
}
hIn = CreateFile(argr,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hIn == INVALID_HANDLE_VALUE) {
printf("ошибка %x\n",GetLastError());
return 2;
}
hOut = CreateFile(argv,GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hOut == INVALID_HANDLE_VALUE) {
printf("ошибка %x\n",GetLastError());
return 2;
}
size = GetFileSize(hIn, &size);
if(size>=BUF_SIZE) size=BUF_SIZE-1;
ReadFile(hIn, Buffer, size, &R, NULL);
WriteFile(hOut, Buffer, size, &dwBytesWritten,NULL);
CloseHandle(hIn);
CloseHandle(hOut);
return 0;
}
int second(int argc, LPTSTR argv, LPTSTR argr) // Решение с помощью функций стандартной библиотеки С
{
FILE *in_file, *out_file;
char* buffer;
size_t bytes_in, bytes_out;
if(argc !=3){
printf("cpw f1,f2\n");
return 1;
}
in_file = fopen(argr,"rb");
if(in_file ==NULL){
perror(argr);
return 2;
}
out_file = fopen(argv, "wb");
if(out_file ==NULL){
perror(argv);
return 3;
}
fseek (in_file , 0 , SEEK_END);
bytes_out = ftell (in_file);
rewind (in_file);
buffer = (char*) malloc (sizeof(char)*bytes_out);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
bytes_in = fread (buffer,1,bytes_out,in_file);
if (bytes_in != bytes_out) {
perror("Ошибка чтения");
return 4;
}
bytes_out = fwrite(buffer,1,bytes_in,out_file);
if (bytes_in != bytes_out) {
perror("Ошибка чтения");
return 4;
}
fclose(in_file);
fclose(out_file);
return 0;
}
int third (int argc,LPTSTR argv, LPTSTR argr){
if(argc !=3){
printf("cpw f1,f2\n");
return 1;
}
if(!CopyFile(argr,argv, FALSE)){
printf("ошибка%x\n", GetLastError());
return 2;
}
return 0;
}
int main(int argc, LPTSTR argv []){
HANDLE in_file,out_file;
DWORD dwBytesWritten;
in_file = CreateFile("in.txt", GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
out_file = CreateFile("out.txt", GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (out_file == INVALID_HANDLE_VALUE) {
printf("ERROR %x \n",GetLastError());
return 2;
}
WriteFile(out_file, "dfsd", 4, &dwBytesWritten, NULL);
CloseHandle(in_file);
CloseHandle(out_file);
first(3,"in.txt","out.txt");
second(3,"out.txt","in.txt");
third(3,"in.txt","out.txt"); }
Первая реализация(first) – это решение с помощью встроенных системных windows функций
Вторая реализация(second) – это решение с помощью функций стандартной библиотеки С
Третья реализация(third) – это решение с помощью специализировнных WinAPI функции.
Время исполнения функций в коде:
Нагрузка на CPU во время вызова каждой из реализаций:
Был доработан и реализован пример, написанный на доске, проанализирован с помощью встроенного в Visual Studio пакета профилирования проекта и с помощью CPU Sampling метода, получен график загруженности системы в зависимости от различной реализации, а так же и количественное время для каждой из реализаций.
Замена одного файла другим(Replace)
#include <Windows.h>
#include <stdio.h>
#include <errno.h>
#define BUF_SIZE 256
int first( int argc, LPTSTR argv, LPTSTR argr) { // Решение с помощью встроенных windows функций
HANDLE hOld, hNew;
CHAR Buffer[BUF_SIZE];
DWORD size,R,dwBytesWritten;
if(argc != 3){
printf("cpw f1,f2\n");
return 1;
}
DeleteFile(argr);
hOld = CreateFile(argv,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hOld == INVALID_HANDLE_VALUE) {
printf("ошибка %x\n",GetLastError());
return 2;
}
size = GetFileSize(hOld, &size);
if(size>=BUF_SIZE) size=BUF_SIZE-1;
ReadFile(hOld, Buffer, size, &R, NULL);
hNew = CreateFile(argr,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (hNew == INVALID_HANDLE_VALUE) {
printf("ошибка %x\n",GetLastError());
return 2;
}
WriteFile(hNew, Buffer, size, &dwBytesWritten,NULL);
CloseHandle(hOld);
DeleteFile(argv);
CloseHandle(hNew);
return 0;
}
int second(int argc, LPTSTR argv, LPTSTR argr) // Решение с помощью функций стандартной библиотеки С
{
FILE *old_file, *new_file;
char* buffer;
size_t bytes_in, bytes_out;
if(argc !=3){
printf("cpw f1,f2\n");
return 1;
}
remove(argr);
old_file = fopen(argv,"rb");
if(old_file ==NULL){
perror(argv);
return 2;
}
new_file = fopen(argr, "wb");
if(new_file ==NULL){
perror(argr);
return 3;
}
fseek (old_file , 0 , SEEK_END);
bytes_out = ftell (old_file);
rewind (old_file);
buffer = (char*) malloc (sizeof(char)*bytes_out);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
bytes_in = fread (buffer,1,bytes_out,old_file);
if (bytes_in != bytes_out) {
perror("Ошибка чтения");
return 4;
}
bytes_out = fwrite(buffer,1,bytes_in,new_file);
if (bytes_in != bytes_out) {
perror("Ошибка чтения");
return 4;
}
fclose(new_file);
fclose(old_file);
remove(argv);
return 0;
}
int third (int argc,LPTSTR argv, LPTSTR argr){ // Решение с помощью winAPI функции.
if(argc !=3){
printf("cpw f1,f2\n");
return 1;
}
if(!ReplaceFile(argr, argv, NULL, REPLACEFILE_IGNORE_MERGE_ERRORS,NULL,NULL)){
printf("ошибка%x\n", GetLastError());
return 2;
}
return 0;
}
void createfiles(){ // Функция создания файлов для возможности «замещения» файла.
HANDLE in_file,out_file;
DWORD dwBytesWritten;
in_file = CreateFile("test1.txt", GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
out_file = CreateFile("test2.txt", GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (out_file == INVALID_HANDLE_VALUE) {
printf("ERROR %x \n",GetLastError());
return ;
}
if (in_file == INVALID_HANDLE_VALUE) {
printf("ERROR %x \n",GetLastError());
return ;
}
WriteFile(in_file, "wyujdhnsgbfdfsd", 15, &dwBytesWritten, NULL);
WriteFile(out_file, "dfsd", 4, &dwBytesWritten, NULL);
CloseHandle(in_file);
CloseHandle(out_file);
}
int main(int argc, LPTSTR argv []){
createfiles();
first(3,"test1.txt","test2.txt");
createfiles();
second(3,"test2.txt","test1.txt");
createfiles();
third(3,"test1.txt","test2.txt");
return 0;
}
Первая реализация(first) – это решение с помощью встроенных windows функций
Вторая реализация(second) – это решение с помощью функций стандартной библиотеки С
Третья реализация(third) – это решение с помощью WinAPI функции.
Время исполнения функций в коде:
Нагрузка на CPU во время вызова каждой из реализаций:
В результате тестирования видно, что в обоих случаях, самым быстрым оказывается использование системных функций Windows. На втором месте идет использование стандартных средств языка C, однако разница довольно мала в первых двух реализациях. Это связано с похожей реализацией алгоритмов, однако в системных вызовах существует некоторая оптимизация. На последнем месте идет вызов специализированной WinAPI функции. С точки зрения написания программы, это самый легкий способ, однако, как видим, он показывает наихудший результат. По-этому, если нужно писать максимально быструю программу, лучше реализовывать все самому.