Панель управления
Оплаченные ссылки
Главная » C++ энциклопедия » C » C++. Делаем свою секцию данных в PE
Категория: C++ энциклопедия » C
- 85
Автор: RZah
PE (Portable Executable) - формат исполняемых файлов, объектного кода и динамических библиотек, используемый в 32- и 64-битных версиях операционной системы Microsoft Windows. Формат PE представляет собой структуру данных, содержащую всю информацию, необходимую PE загрузчику для проецирования файла в память (по материалам Wikipedia). Сегодня мы поговорим о том как сделать собственную секцию данных в PE файле.
А зачем?
Во-первых, некоторые компиляторы вольны вставлять строковые данные в сегмент кода, тем самым засоряя его. Насколько мне известно, компиляторы, некогда существовавшей Borland особенно этим грешили.
Во-вторых, это хороший способ спрятать свои данные от юных крэкеров, а в совокупности с хорошим крипто алгоритмом можно отпугнуть и крэкера средней руки. Профи этим, конечно же не остановить и тут надо хорошенько “поломать голову”, но это уже другая история. И так давай проведем пару экспериментов и посмотрим, что из этого выйдет. Для опытов нам потребуется:
1. Компилятор C++ (Майкрософсткий). Я буду использовать Visual Studio 2005;
2. IDA Pro. Можно использовать dumpbin (входит в поставку Visual Studio). Если ни того ни другого у тебя нет, то можно использовать любой HEX редактор, ну или утилиту для просмотра секций PE файла. Для наглядности я буду применять IDA Pro.
С инструментами разобрались. Теперь давай напишем небольшую программу для наших экспериментов. Полный код программы:
Не будем подробно рассматривать этот код (все пояснения я привел в комментариях), а сразу откомпилируем его, а затем откроем получившийся exe’шник в IDA Pro. После анализа файла, IDA любезно предоставит тебе всю необходимую информацию. Однако нас интересуют секции данных, поэтому щелкай по вкладке “String window”. Ты увидишь изображение как на рисунке 1.
На рисунке 1 нам видно, что все наши данные хранятся в открытом виде в секции .rdata (следует заметить, что названия секций не всегда предваряются точкой, просто так принято).
И про dumpbin я не забыл
В командной строке набирай dumpbin (не забудь набрать полный путь к dumpbin) /RAWdata:BYTES /SECTION:.rdata example.exe (путь к нашему exe’шнику). Эта команда позволяет вывести содержимое определенной секции. Выходную информацию можно перенаправить в файл (так проще разбираться). Для этого дописываем в конце example.exe >file.txt. Если опустить параметр /RAWdata:BYTES, то dumpbin выведет информацию о секции .rdata - смещение, адрес секции (см. рисунок 2) и т.д.
Чтобы узнать названия всех секций надо просто набрать dumpbin example.exe (см. рисунок 3).
Чтобы узнать все используемые опции и их описания набери dumpbin /?. Ладно, с этим вроде бы разобрались, идем дальше. А дальше у нас по плану создание собственной секции и размещение в ней данных.
Создание новых секций, да и распределение данных по ним никак не оговорено в стандартах, поэтому каждый компилятор сам себе хозяин в этом плане (для получения подробной информации обратись к документации используемого компилятора). Однако общие правила все же есть:
- Секции .idata, .data, .rdata – содержат данные программы (строки, числа и все остальное, что не жалко);
- .text – сам код программы. В секции .bss обычно находятся неинициализированные переменные и все в этом духе.
Поскольку мы воспользовались компилятором C++, то все ниже описанное будет работать только в нем (однако принцип для всех и вся один и тот же, лишь реализация разная, но с одной оговоркой, если компилятор вообще поддерживает создание новых секций). Если же ты столкнулся с таким компилятором, то я знаю только два пути решения проблемы с созданием новой секции. Первый - сменить компилятор, второй - взять в руки дизассемблер + другие “низкоуровневые” инструменты и вручную начинать ковырять свежеиспеченный exe’шник. Для того чтобы создать новую секцию данных в C++ воспользуемся программой data_seg. Запишем данные во вновь созданную секцию и вернемся к старой секции.
Выполняй компилирование и открывай полученный бинарник в IDA Pro (см. рисунок 4).
На рисунке 4 я выделил нашу новую секцию и данные в ней. Помнишь, я говорил, что в отношении секций данных компилятор сам себе хозяин. Это прямое тому подтверждение – в коде мы назвали секцию Ghost_Rider, а в дизассемблированном виде получаем Ghost_R (компилятор обрезает длинные имена секций). Давай посмотрим через dumpbin все наши секции (см. рисунок 5).
Новая секция готова
Теперь остается реализовать (пусть даже простой) алгоритм шифрования к данным и они будут скрыты от посторонних глаз. В неизвестную секцию мало кто полезет (а вдруг она используется программой в целях поддержания работоспособности или еще чего). Кроме того шифрование неплохая защита от новичков-крякеров, а может и больше, кто знает. На этом все, до встречи.
Исходник прилагается:
Source.zip
А зачем?
Во-первых, некоторые компиляторы вольны вставлять строковые данные в сегмент кода, тем самым засоряя его. Насколько мне известно, компиляторы, некогда существовавшей Borland особенно этим грешили.
Во-вторых, это хороший способ спрятать свои данные от юных крэкеров, а в совокупности с хорошим крипто алгоритмом можно отпугнуть и крэкера средней руки. Профи этим, конечно же не остановить и тут надо хорошенько “поломать голову”, но это уже другая история. И так давай проведем пару экспериментов и посмотрим, что из этого выйдет. Для опытов нам потребуется:
1. Компилятор C++ (Майкрософсткий). Я буду использовать Visual Studio 2005;
2. IDA Pro. Можно использовать dumpbin (входит в поставку Visual Studio). Если ни того ни другого у тебя нет, то можно использовать любой HEX редактор, ну или утилиту для просмотра секций PE файла. Для наглядности я буду применять IDA Pro.
С инструментами разобрались. Теперь давай напишем небольшую программу для наших экспериментов. Полный код программы:
#include "stdafx.h"
#include "windows.h"
//Объявляем константы
#define UserName "Ghost Rider";
#define Password "12345";
//Левые данные
#define Login_for_Admin "Super Admin";
#define Password_Admin "Admin Password=12345";
int _tmain(int argc, _TCHAR* argv[])
{
char buffer_nik[50]; //буфер под ввод ника
char buffer_pas[20]; //буфер под ввод пароля
//Ввод ника
printf("Vvedite nik: > ");
fgets(&buffer_nik[0],50,stdin);
//ввод пароля
printf("Vvedite parol: > ");
fgets(&buffer_pas[0],20,stdin);
//сравнение введенных данных с константами
if ((strcmp(&buffer_nik[0],UserName))&(strcmp(&buffer_pas[0],Password)))
printf("OK.");
else
printf("Wrong Pas or Nik");
return 0;
}
Не будем подробно рассматривать этот код (все пояснения я привел в комментариях), а сразу откомпилируем его, а затем откроем получившийся exe’шник в IDA Pro. После анализа файла, IDA любезно предоставит тебе всю необходимую информацию. Однако нас интересуют секции данных, поэтому щелкай по вкладке “String window”. Ты увидишь изображение как на рисунке 1.
Рисунок 1. Смотрим секции данных в Ida Pro
На рисунке 1 нам видно, что все наши данные хранятся в открытом виде в секции .rdata (следует заметить, что названия секций не всегда предваряются точкой, просто так принято).
И про dumpbin я не забыл
В командной строке набирай dumpbin (не забудь набрать полный путь к dumpbin) /RAWdata:BYTES /SECTION:.rdata example.exe (путь к нашему exe’шнику). Эта команда позволяет вывести содержимое определенной секции. Выходную информацию можно перенаправить в файл (так проще разбираться). Для этого дописываем в конце example.exe >file.txt. Если опустить параметр /RAWdata:BYTES, то dumpbin выведет информацию о секции .rdata - смещение, адрес секции (см. рисунок 2) и т.д.
Рисунок 2. Секция .rdata
Чтобы узнать названия всех секций надо просто набрать dumpbin example.exe (см. рисунок 3).
Рисунок 3. Названия секций
Чтобы узнать все используемые опции и их описания набери dumpbin /?. Ладно, с этим вроде бы разобрались, идем дальше. А дальше у нас по плану создание собственной секции и размещение в ней данных.
Создание новых секций, да и распределение данных по ним никак не оговорено в стандартах, поэтому каждый компилятор сам себе хозяин в этом плане (для получения подробной информации обратись к документации используемого компилятора). Однако общие правила все же есть:
- Секции .idata, .data, .rdata – содержат данные программы (строки, числа и все остальное, что не жалко);
- .text – сам код программы. В секции .bss обычно находятся неинициализированные переменные и все в этом духе.
Поскольку мы воспользовались компилятором C++, то все ниже описанное будет работать только в нем (однако принцип для всех и вся один и тот же, лишь реализация разная, но с одной оговоркой, если компилятор вообще поддерживает создание новых секций). Если же ты столкнулся с таким компилятором, то я знаю только два пути решения проблемы с созданием новой секции. Первый - сменить компилятор, второй - взять в руки дизассемблер + другие “низкоуровневые” инструменты и вручную начинать ковырять свежеиспеченный exe’шник. Для того чтобы создать новую секцию данных в C++ воспользуемся программой data_seg. Запишем данные во вновь созданную секцию и вернемся к старой секции.
#include "stdafx.h"
#include "windows.h"
//Объявляем данные в новой секции
#pragma data_seg(".Ghost_Rider")
char UserName[]="Ghost Rider";
char Password[]="12345";
//возвращаемся к старой секции (.rdata в нашем случае, по умолчанию вообще-то .data )
#pragma data_seg()
//Левые данные
char Login_for_Admin[]="Super Admin";
char Password_Admin[]="Admin Password=12345";
int _tmain(int argc, _TCHAR* argv[])
{
char buffer_nik[50]; //буфер под ввод ника
char buffer_pas[20]; //буфер под ввод пароля
//Ввод ника
printf("Vvedite nik: > ");
fgets(&buffer_nik[0],50,stdin);
//ввод пароля
printf("Vvedite parol: > ");
fgets(&buffer_pas[0],20,stdin);
//сравнение введенных данных с константами
if ((strcmp(&buffer_nik[0],UserName))&(strcmp(&buffer_pas[0],Password)))
printf("OK.");
else
printf("Wrong Pas or Nik");
return 0;
}
Выполняй компилирование и открывай полученный бинарник в IDA Pro (см. рисунок 4).
Рисунок 4. Новая секция (Ida Pro)
На рисунке 4 я выделил нашу новую секцию и данные в ней. Помнишь, я говорил, что в отношении секций данных компилятор сам себе хозяин. Это прямое тому подтверждение – в коде мы назвали секцию Ghost_Rider, а в дизассемблированном виде получаем Ghost_R (компилятор обрезает длинные имена секций). Давай посмотрим через dumpbin все наши секции (см. рисунок 5).
Рисунок 5. Секция .Ghost_R
Новая секция готова
Теперь остается реализовать (пусть даже простой) алгоритм шифрования к данным и они будут скрыты от посторонних глаз. В неизвестную секцию мало кто полезет (а вдруг она используется программой в целях поддержания работоспособности или еще чего). Кроме того шифрование неплохая защита от новичков-крякеров, а может и больше, кто знает. На этом все, до встречи.
Исходник прилагается:
Source.zip
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.





